Custom Backends¶
You can create a custom backend if the supplied backends don’t suffice. Since backends handle both inbound and outbound communication, the following section is divided into Incoming Messages and Outgoing Messages, respectively.
The built-in Vumi and Kannel backends use the methods described below, so you can review the source code to see actual implementation examples.
For a more general backend overview, please see RapidSMS Backends.
Incoming Messages¶
HTTP Backend¶
RapidSMS provides a base suite of HTTP views and forms to help simplify backend
creation in rapidsms.backends.http
. These are useful for standardizing
incoming message handling. They can be extended for use in your own backends. The HTTP Backend powers both the Vumi and Kannel backends.
You can, of course, simply write your own Django views to handle incoming messages if the supplied classes do not provide enough flexibility.
Incoming message life cycle¶
Typically, when RapidSMS receives a message over HTTP, it’s processed in the following way:
- Data from a text message is received by Django over an HTTP request.
- The HTTP request is routed through a Backend URL.
- This backend view takes the HTTP request and passes it into a backend form.
- This backend form cleans the message data and checks its validity.
- If the message is valid, message data is sent to the router for processing via
rapidsms.router.receive()
. - An HTTP response is sent to the HTTP request sender with an HTTP status code to indicate that the message was received and passed to the router for processing successfully or that there was an error.
The HTTP response from a backend view does not necessarily indicate that the resulting messages were sent by the router, only that the incoming message was added to the queue for processing.
GenericHttpBackendView¶
-
class
rapidsms.backends.http.views.
GenericHttpBackendView
(**kwargs)¶ Simple view that allows customization of accepted paramters.
-
http_method_names
= ['get', 'post']¶ Accepts GET and POST by default.
-
params
= {}¶ Dictionary that defines mappings to
identity
andtext
.
-
The simplest type of custom backend is an HTTP backend that needs to accept
parameters other than identity
and text
. To create such a custom
backend, one can subclass the GenericHttpBackendView
as follows:
from rapidsms.backends.http.views import GenericHttpBackendView
class MyBackendView(GenericHttpBackendView):
params = {
'identity_name': 'phone',
'text_name': 'message',
}
The params
dictionary contains key value pairs that map internal names to
the keys used in requests to the backend. In the above example, an HTTP request
would provide phone
and message
parameters.
An URL pattern for this backend might look like:
from project_name.app_name.views import CustomHttpBackendView
urlpatterns = patterns('',
url(r'^backends/mybackend/$',
MyBackendView.as_view(backend_name='mybackend')),
)
A request to this backend might look like the following:
>>> import urllib
>>> import urllib2
>>> data = urllib.urlencode({'phone': '1112223333', 'message': 'ping'})
>>> request = urllib2.urlopen(http://localhost:8000/backends/mybackend/', data)
>>> request.code
200
>>> request.read()
'OK'
Custom Validation¶
Another custom backend might necessitate handling more parameters in the request, or validating the incoming data differently. A convenient way to do this validation with Django is with forms:
from .forms import ExtraParamsHttpBackendForm
from rapidsms.backends.http.views import GenericHttpBackendView
class ExtraParamsHttpBackendView(GenericHttpBackendView):
form_class = ExtraParamsHttpBackendForm
This example application would have the following forms definition:
from django import forms
from rapidsms.backends.http.forms import BaseHttpForm
class ExtraParamsHttpBackendForm(BaseHttpForm):
extra = forms.TextField()
def get_incoming_data(self):
fields = self.cleaned_data.copy()
return {'identity': self.cleaned_data['identity_name'],
'text': self.cleaned_data['text_name'],
'extra': self.cleaned_data['extra']}
This uses RapidSMS’s BaseHttpForm:
-
class
rapidsms.backends.http.forms.
BaseHttpForm
(*args, **kwargs)¶ Helper form for validating incoming messages.
Parameters: backend_name – (Optional) name of the backend -
get_incoming_data
()¶ Return a dictionary containing the connection and text for this message, based on the field names passed to __init__().
Must be implemented by subclasses.
-
lookup_connections
(identities)¶ Simple wrapper to ease connection lookup on child forms.
-
Data coming into this backend would require an extra
parameter, which would
be passed onto the message queue.
Alternatively, here’s an example of a backend form with custom validation:
from django import forms
from rapidsms.backends.http.forms import BaseHttpForm
MY_NUMBER = '1231231234'
class OnlyTextMeHttpBackendForm(BaseHttpForm):
def clean_text_name():
text_name = self.cleaned_data.get('text_name')
if text_name != MY_NUMBER:
raise forms.ValidationError(
'SMS received from number other than {0}'.format(MY_NUMBER)
)
return text_name
Outgoing Messages¶
BackendBase¶
Similar to HTTP Backend for incoming messages, BackendBase
provides
the foundation for outbound functionality. All backends will typically extend
this base class. This class will be passed the configuration dictionary
defined in Backend Settings.
-
class
rapidsms.backends.base.
BackendBase
(router, name, **kwargs)¶ Base class for outbound backend functionality.
-
configure
(**kwargs)¶ Configuration parameters from
INSTALLED_BACKENDS
will be passed here after the router is instantiated. You can override this method to parse your configuration.
-
classmethod
find
(module_name)¶ Helper function to import backend classes.
Parameters: module_name – Dotted Python path to backend class name Returns: Imported class object
-
model
¶ The model attribute is the RapidSMS model instance with this backend name. A new backend will automatically be created if one doesn’t exist upon accessing this attribute.
-
send
(id_, text, identities, context=None)¶ Backend sending logic. The router will call this method for each outbound message. This method must be overridden by sub-classes. Backends typically initiate HTTP requests from within this method. Any exceptions raised here will be captured and logged by the selected router.
If multiple
identities
are provided, the message is intended for all recipients.Parameters: - id_ – Message ID
- text – Message text
- identities – List of identities
- context – Optional dictionary with extra context provided by router to backend
-