Wiki

Clone wiki

javarosa / SMSSendingAPI

SMS Transmission API

This document provides a format and specification for creating xforms, clients, and servers which are capable of succinctly sending data using the SMS protocol.

Overview

OpenRosa clients and servers commonly want to take advantage of the small packet size and common availability of the SMS protocol to communicate submission data. Unfortunately, the format of SMS messages is difficult to guarantee and coordinate due to their unstructured nature.

This API provides a straightforward way to include the definition of an SMS's format inside of an XForm's structure. This allows an easy inclusion of serialization format inside the xform, and permits servers to transparently provide SMS submissions in the same manner as other XML submissions by linking the data to the schema appropriately.

Background

The XForms Submit Control

The XForms Submission spec

OpenRosa Submission Spec.

XML API

Submission Profile

The API for using SMS as the transport mechanism begins with including a <submission> profile in your XForm definition, as is outlined at a high level in the XForms specification, and specifically in OpenRosa as outlined in the submission defintion.

An example submission profile is:

<xforms:submission method="smspush" action="sms://14032030403" ref="/data/smsblock"/>

The important elements of this profile are the method, which specifies that sms should be used, the action URI (which can be ignored on phones with a default target), and the nodeset, which specifies which block will actually be submitted.

Submission Structure

The ref attribute in the submission method is a pointer to a block of instance data which should be structured in a very specific way. The ref that it points to should be in the xmlns="http://openrosa.org/smsdata" namespace, and should be structured as follows:

    <data xmlns="http://openrosa.org/smsdata" delimeter=" " prefix="UNIQUE"> <!-- Exactly One, arbitrary name. command is a unique string defining the submission. Delimeter is an optional delimiter between elements -->
        <name tag="TAG"/>                                       <!-- arbitrarily many: arbitrary name (not included in submission). tag is an optional tag which will prefix the value inside of the element in the SMS message. Child is assumed to be a string value. -->
    </data>

Essentially, this data is flattened into a message where the first string is the command, and each included element is then appended to the message if it is relevant, pre-pended by the tag, where appropriate.

The serialization proceeds in linear, and for obvious reasons the message may not be well structured if non-tagged data is not necessarily required, so tags should be used whenever an element could be non-relevant.

A sample XForms instance associated with an sms message might look like

<instance>
    <data>
        <smsblock xmlns="http://openrosa.org/smsdata" prefix="FORM232">
            <location tag="+LOC"/>
            <flow tag="+FL"/>
            <comment tag="+CM"/>
        </smsblock>
    ... The other XForm Data ...
    </data>
</instance>

Example Usage

And example end-to-end system using this spec might look like the following.

XForm

<instance>
    <data xmlns="http://myorg.org/myxformdata/flow">
        <smsblock xmlns="http://openrosa.org/smsdata" prefix="FLOW">
            <userid/>
            <location/>
            <status tag="+ST"/>
            <flow tag="+FL"/>
            <comment tag="+CM"/>
        </smsblock>
    ... The other XForm Data ...
    </data>
</instance>

<submission method="smspush" action="sms://14032030403" ref="/data/smsblock"/>
<bind nodeset="/data/smsblock/userid" required="true()"/>
<bind nodeset="/data/smsblock/location" required="true()"/>
<bind nodeset="/data/smsblock/status" relevant="somecondition()"  calculate="if(/data/somewhere/value2='good', 'G', 'B')">
<bind nodeset="/data/smsblock/flow" relevant="somecondition()" calculate="/data/somewhere/value"/>
<bind nodeset="/data/smsblock/comment" relevant="somecondition()"/>

Submissions from this form might look like:

Submission 1:
FLOW U323 KIBADA +ST G +FL 23.3

Submission 2:
FLOW U434 SOMEWHERE +FL 50.0 +CM Needs Supervision

Submission 3:
FLOW U434 SOMELSE +ST B +FL 34.9 +CM Send resupply on Tuesday

Which would be sent to the sms #, and on the server could be re-constituted into

Submission 1:
    <data xmlns="http://myorg.org/myxformdata/flow">
        <smsblock xmlns="http://openrosa.org/smsdata" prefix="FLOW">
            <userid>U323</userid>
            <location>KIBADA</location>
            <status tag="+ST">G</status>
            <flow tag="+FL">23.3</flow>
        </smsblock>
    </data>

Submission 2:
    <data xmlns="http://myorg.org/myxformdata/flow">
        <smsblock xmlns="http://openrosa.org/smsdata" prefix="FLOW">
            <userid>U434 </userid>
            <location>SOMEWHERE</location>
            <flow tag="+FL">50.0</flow>
            <comment tag="+CM">Needs Supervision</comment>
        </smsblock>
    </data>

Submission 3:
    <data xmlns="http://myorg.org/myxformdata/flow">
        <smsblock xmlns="http://openrosa.org/smsdata" prefix="FLOW">
            <userid>U434 </userid>
            <location>SOMELSE</location>
            <status tag="+ST">B</status>
            <flow tag="+FL">34.9</flow>
            <comment tag="+CM">Send resupply on Tuesday</comment>
        </smsblock>
    </data>

Updated