RapidSMS Developers Guide/Creating a RapidSMS App

App structure

edit

A RapidSMS App is a Django app which includes some RapidSMS-specific files and follows some conventions. A Typical app would look like this:

__init__.py
app.py
models.py
admin.py
views.py
urls.py
static/
templates/

A minimal app would contain:

__init__.py
app.py
  • app.py: SMS code
  • models.py: Django models (database)
  • admin.py: Django admin
  • views.py: Django view (web interface)
  • urls.py: Djangi URL patterns (for web interface)
  • static/: folder containing static files for web interface. Accessible at http://<server>/static/<appname>/
  • templates: Django templates

SMS Code

edit

An App's SMS code is composed of a rapidsms.app.App class which will be instantiated and called by the router.

Skeleton of a app.py:

import rapidsms

class App(rapidsms.app.App):

    def parse(self, message):
        pass

    def handle(self, message):
        pass

How it works ?

edit

The router, launched by the route command, instantiates all the App's App classes. This is done in the order of the apps= string in local.ini ; then it calls the start method of each, then the configure message of each.

Once a message is received, it follows the following procedure:

  1. call parse method of each App, passing it the Message object.
  2. class handle method of each App, passing it the Message object.

Once one of the handle method return True, the message is considered handled and thus not passed to the other apps. That's why order matters.

Configuring your App

edit

RapidSMS offers the ability to add some configuration for your app in the local.ini file. In your local.ini, add a section for your app with key-value peers.

Example for a test app:

[test]
country=ml

Adding such configuration will have the router call the configure method of the test App during startup. Make sure your app has a configure method that can answer to it :

    def configure(self, country):
        pass

or

    def configure(self, **kwargs):
        pass

Note that all arguments are passed as strings.

Message Object

edit

The Message object is at the heart of RapidSMS. It is the one carrying the SMS from the backend, to the router, then back to the backend for delivery to the user.

Properties

edit
  • message.text: the actual text message. This can be a str or a unicode text. There is no size limitation.
  • message.peer: sender/recipient identity. Depending on backend, this is usually a string representing the phone number or equivalent.
  • message.date: a datetime object representing the reception date.
  • message.status: a string representing the status of the message. Not widely used.
  • message.person: a Person object which hold a reference to the connection
  • message.connection: a Connection object which holds reference to both the backend and the identity.

Methods

edit
  • message.send(): sends the object to the appropriate backend.
  • message.respond(text, status): creates a message to send back to the sender of this one. Actual sending is differed.
  • message.flush_responses(): sends all responses created with .respond()
  • message.forward(identity, text): creates a new message object on same backend with different identity then call respond().

Models

edit

Most RapidSMS Apps are used for Data Collection and rely on a Database. Because RapidSMS is built on top of Django, you are encouraged to use Django's Models for this.

Since nothing here is specific to RapidSMS, please refer to Django Documentation[1]

Example

edit

Creating a model

edit

A model resides in models.py file and should subclass django.db.models.Model:

from django.db import models

class SMS(models.Model):
    number = models.CharField(max_length=30)
    text = models.TextField()

This model contains 2 properties: number and text, both are strings.

Django's Models are an ORM (Object Relational Mapping). This means that from your apps, you will instantiate those objects like live objects and django will take care of storage/retrieval to/from the database.

Important: Your model is just the representation of your data. You can consider it like the list of your tables fields. Each time you modify it, you will need to ask Django to update the actual database, which is separate.

Creating the database

edit

As stated above, Django will be entirely responsible for Database access. Just make sure your local.ini is correctly configured regarding the Database then re-sync the Database.

./rapidsms syncdb

This command will create every newly added model.

Should you need to modify your model, you will have to erase and re-create the database:

./rapidsms reset <appname>

Dumping and restoring Data

edit

Django includes a tool to backup and restore the content of your Database (models).

./rapidsms dumpdata <appname>

This will display a serialized version of all your models data for the app appname. You can also select one particular model.

./rapidsms dumpdata <appname>.SMS > backup.json

The previous command will save the content of the SMS model only and redirect it to a file. The default format for dumping and restoring datas in Django is JSON.

To restore a backup file, use the following

./rapidsms loaddata backup.json


Views

edit

In Django-terminology, views are web pages.

Please, refer to documentation as none of the following is RapidSMS specific.

To display a web-page, the django way, you need to complete three steps:

Set the URL

edit

The file urls.py keeps a record of all your app's URLs. You need each of your views (pages) to be defined in urls.py in order to access them.

Example for an app named test:

from django.conf.urls.defaults import *

import test.views as views

urlpatterns = patterns('',
    url(r'^test/?$', views.index),
)

The above file will call the index view (nonexistent right now) for each HTTP request to http://<server>/test.

Create a template

edit

To save the developer some time and effort with dealing with HTML, Django offers the ability to use templates. A template is an HTML file which can accept a particular syntax to display variables and other data from the view.

Create a sample RapidSMS template in the templates/ folder:

{% extends base_template %}

{% block content %}
<p>Hello {{ name }}!</p>
{% endblock %}

This template extends the base_template one (which is RapidSMS's design) and replace the content of the block content with a paragraph. This paragraph contain a template variable which we will have replaced by some text in the view.

Create an HTTP function

edit

A view is just a function which return an HTTP object to be displayed on the visitor's browser.

A minimal views.py file:

from django.http import HttpResponse

def index(request):
    return HttpResponse("hello")

With this view, displaying the corresponding web page on a browser will result in a blank page with the word hello.

Instead of writing HTML inside our view, we can call the template we just created.

On this, Django and RapidSMS differs a little. Here is the RapidSMS way:

from rapidsms.webui.utils import render_to_response

def index(request):
    greeting = "Thomas"
    return render_to_response(request, 'templates/index.html', {'name': greeting})

This way, we are displaying a template and passing it a context (Hash) containing a list of our template-variables and their associated values.

Displaying it in a browser will result in a nice RapidSMS U.I with a sentence greeting Thomas.

Django Admin

edit

To access the Data corresponding to your models visually, you can enable the Django admin. Django provide a web interface for administering some of its features but also the models created by developers.

It is accessible at http://<server>/admin.

Refer to Customizing Admin U.I to enable it for your App.

Running RapidSMS · SMS & the Keyworder

  1. http://docs.djangoproject.com/en/1.1/topics/db/models/#topics-db-models