Websites Navigation: Airbit | Shop | m-shell.net
Languages: EN | DE

Accessing SMS

Given our small database db, we can now look into receiving and sending SMS.

To access the SMS functionality of your phone from m, we load the corresponding module. There are many modules for different functions of your phone, or of m; chapter * () gives you an overview. A few good reasons for having modules:

  • m can be extended by new modules, adding to its power and flexibility. This includes modules written by yourself, as you will see later on.
  • Isolating different concepts into separate modules clarifies m and makes it easier to understand and learn.
  • Only loading a module when it is needed saves memory.
The module giving SMS access is called, not surprisingly, module sms. Using it, our service could look as follows:

// load the SMS module
use sms
// define the reply database
db=["party": "The party starts at 8pm!",
    "place": "I am at home.",
    "mood": "Just don't ask."];
while true do
  // wait for a message
  id=sms.receive();
  // get the message
  msg=sms.get(id);
  // get the trimmed text in lowercase
  t=lower(trim(msg["text"]));
  // if we find it in our database, reply
  if db[t]#null then
    print "Got",t,"from",msg["sender"];
    sms.send(msg["sender"], db[t]);
    sms.delete(id)
  end
end

A few explanations:

  • A module is loaded (or imported) with the use command.
  • The loop while true will forever execute the code between do and the corresponding end. That's exactly what we want: our service should only stop if we stop the process from the m application.
  • Functions from a module are called by their name, prefixed by the module name and a dot: sms.receive() calls function receive from module sms.
  • sms.receive() waits until a new SMS arrives, and returns a number identifying the new message. We assign this number to variable id.
  • Note the empty argument list after sms.receive. These are required to make it clear to m that we want to call a function.
  • sms.get(id) retrieves the message with the id we got from sms.receive(), and returns it as an associative array. The array has, among others, the following members:

    senderThe phone number of the sender of the message.
    textThe text of the message.

    As you see, associative arrays are also often used by the m library, whenever a set of related values has to be dealt with.

  • Our service should also work if the message sent contains leading or trailing blanks, and case should not matter. We therefore use two functions built into m: trim to remove blanks, and lower to convert all uppercase characters to lowercase. All put together, we can simply write lower(trim(msg["text"])).
  • We test whether our database in variable db contains a reply for the message text t. Remember that db[t] returns null if there is no element for key t, so if db[t] does not equal null, we have a reply.
  • If there is a reply in the database, a confirmation is printed on the console, and the reply is sent with sms.send(). This function takes two arguments: the recipient of the message, and the message text. Since we send a reply, the recipient is the sender of the original message, which we find in msg["sender"].
  • After sending the reply, we delete the message, as we do not want our SMS inbox to fill up with messages we already replied to. sms.delete(id) deletes the message with the id we got from sms.receive().
When creating automated replying systems, it is a good idea to check whether we are not accidentally replying to a message coming from ourselves, and entering into a never ending loop. Let's assume we have added a keyword "echo" with reply "echo":

db["echo"]="echo";

If we now send ourselves a message "echo", the service will start to reply to itself until it is stopped.

This is unlikely to happen, but if it does, the consequences may be quite expensive.

In m, there is a simple way to check whether we sent a message to ourselves: if m is properly configured, gsm.number contains our own phone number which we can check against. The above check for a valid message can be completed by:

  // if it's not from us, and we find it
  // in our database, reply
  if msg["sender"]#gsm.number and db[t]#null then

Don't forget to add module gsm to the use clause:

use sms, gsm


© 2004-2011 airbit AG, CH-8008 Zürich
Document AB-M-TUT-887
mShell Home  > Documentation  > Manuals