Building SMS Forms
SMS forms allow users to submit reports from any device including feature phones without internet access. SMS forms are ideal in scenarios where targeted users have no way of accessing internet or where they are restricted to using feature phones.
This tutorial will take you through how to build SMS forms for CHT applications, including:
- Defining SMS forms
- Setting validation rules for SMS forms
- Setting automatic responses to SMS reports
You will be building a pregnancy registration workflow that allows Community Health Workers to register households, register household members, and register new pregnancies for the household members.
Brief Overview of Key Concepts
SMS forms are structured text messages that contain a form code representing a report type and some information associated with the report.
SMS forms are defined in either the base_settings.json
or the app_settings/forms.json
file and compiled into the app_settings.json file with the compile-app-settings
action in the cht-conf
tool, then stored in the settings doc in the database.
SMS gateways allow the CHT core framework to send and receive SMS transmission to or from a mobile network operator.
SMS aggregators act as intermediaries between the mobile network operators and the CHT core framework. They allow for greater customization of SMS workflows in the CHT.
Interoperability: CHT apps can receive data from other software when it is submitted as reports using the same JSON/SMS form notation.
Required Resources
You should have a functioning CHT instance with cht-conf
installed locally.
You also need to have some prior knowledge on app_settings.json
.
Implementation Steps
SMS forms are defined using JSON in the app_settings.json
file.
1. Enable Transitions
To ensure SMS forms function as expected, you will first need to enable the following transitions in app_settings.json
.
"update_clinics": true,
"registration": true,
"accept_patient_reports": true,
"generate_shortcode_on_contacts": true,
"death_reporting": true
See Also: Transitions
2. Define a Place Registration Form
To define a form, edit the object corresponding to the forms
key in app_settings.json
.
Add a household registration form by adding a key and object pair to the forms
object as shown below.
"forms": {
"HR": {
"meta": {
"code": "HR",
"label": {
"en": "New Household Registration"
}
},
"fields": {
"place_name": {
"labels": {
"tiny": {
"en": "household_name"
},
"description": {
"en": "Name of Household"
},
"short": {
"en": "Household name"
}
},
"position": 0,
"type": "string",
"length": [
3,
30
],
"required": true
}
}
}
}
Note
Users will register new households by sending a text message in the format HR <household name>
. For example, HR Mary
will register Mary's Household
.
To set the validation rules and autoresponses, edit the array corresponding to the registration
key in app_settings.json
. Add an object within the array as shown below.
"registrations": [
{
"form": "HR",
"events": [
{
"name": "on_create",
"trigger": "add_place",
"params": "{ \"contact_type\": \"clinic\" }",
"bool_expr": ""
}
],
"validations": {
"join_responses": false,
"list": [
{
"property": "place_name",
"rule": "!regex('household') && !regex('house hold')",
"translation_key": "messages.hr.validation.no_household_in_name"
},
{
"property": "place_name",
"rule": "lenMin(1) && lenMax(30)",
"translation_key": "messages.hr.validation.household_name_length"
}
]
},
"messages": [
{
"event_type":"report_accepted",
"recipient": "reporting_unit",
"translation_key": "messages.hr.report_accepted"
}
]
}
]
You can also define your own validation rules.
Note
translation_key
represents the message that is sent out. This will be defined in a translations file.
3. Define a Person Registration Form
Add a person registration form by adding a key and object pair to the forms
object as shown below.
"forms": {
"N": {
"meta": {
"code": "N",
"label": {
"en": "New Person Registration"
}
},
"fields": {
"place_id": {
"labels": {
"tiny": {
"en": "place_id"
},
"description": {
"en": "Household ID"
},
"short": {
"en": "HH ID"
}
},
"position": 0,
"type": "string",
"length": [
1,
13
],
"required": true
},
"gender": {
"labels": {
"tiny": {
"en": "gender"
},
"description": {
"en": "Gender"
},
"short": {
"en": "Gender"
}
},
"position": 1,
"type": "string",
"length": [
1,
6
],
"required": true
},
"age": {
"labels": {
"tiny": {
"en": "age"
},
"description": {
"en": "Age"
},
"short": {
"en": "Age"
}
},
"position": 2,
"type": "integer",
"length": [
1,
2
],
"required": true
},
"patient_name": {
"labels": {
"tiny": {
"en": "patient_name"
},
"description": {
"en": "Patient name"
},
"short": {
"en": "Patient name"
}
},
"position": 3,
"type": "string",
"length": [
3,
30
],
"required": true
}
}
}
}
Note
Users will register a new person by sending a text message in the format N <household id> <gender> <age> <name>
. For example, N 12345 F 20 Jane Cho
will register Jane Cho
who belongs to the household with household ID 12345
.
To set the validation rules and autoresponses, edit the array corresponding to the registration
key in app_settings.json
. Add an object within the array as shown below.
"registrations": [
{
"form": "N",
"events": [
{
"name": "on_create",
"trigger": "add_patient",
"params": "{ \"parent_id\": \"place_id\" }",
"bool_expr": ""
}
],
"validations": {
"join_responses": false,
"list": [
{
"property": "place_id",
"rule": "regex('^[0-9]{5,13}$')",
"translation_key": "messages.validation.household_id"
},
{
"property": "gender",
"rule": "iEquals('m') || iEquals('f')",
"translation_key": "messages.n.validation.gender"
},
{
"property": "age",
"rule": "between(5,130)",
"translation_key": "messages.n.validation.age"
}
]
},
"messages": [
{
"event": "report_accepted",
"translation_key": "messages.n.report_accepted",
"recipient": "reporting_unit"
}
]
}
]
4. Define a Report Submission form
Add a report submission form by adding a key and object pair to the forms
object as shown below.
"forms": {
"P": {
"meta": {
"code": "P",
"label": {
"en": "Pregnancy Registration"
}
},
"fields": {
"patient_id": {
"position": 0,
"labels": {
"tiny": {
"en": "patient_id"
},
"short": {
"en": "Woman's ID"
},
"description": {
"en": "Woman's ID"
}
},
"type": "string",
"length": [
5,
13
],
"required": true
},
"lmp": {
"position": 1,
"labels": {
"tiny": {
"en": "lmp"
},
"short": {
"en": "LMP in weeks"
},
"description": {
"en": "Last menstrual period - in weeks"
}
},
"type": "integer",
"length": [
1,
2
],
"required": false
}
}
}
}
Note
Users will pregnancy registration report by sending a text message in the format P <patient id> <last menstrual period>
. For example, P 23456 21
will register a pregnancy report for a person whose unique ID is 23456
and the last menstrual period was 21 weeks ago
.
To set the validation rules and autoresponses, edit the array corresponding to the registration
key in app_settings.json
. Add an object within the array as shown below.
"registrations": [
{
"form": "P",
"events": [
{
"name": "on_create",
"trigger": "add_expected_date",
"params": "lmp_date",
"bool_expr": "doc.fields.lmp && /^[0-9]+$/.test(doc.fields.lmp)"
}
],
"validations": {
"join_responses": false,
"list": [
{
"property": "patient_id",
"rule": "regex('^[0-9]{5,13}$')",
"translation_key": "messages.validation.patient_id"
},
{
"property": "lmp",
"rule": "lenMin(1) ? (integer && between(4,42)) : optional",
"translation_key": "messages.p.validation.weeks_since_last_lmp"
}
]
},
"messages": [
{
"event_type": "report_accepted",
"translation_key": "messages.p.report_accepted",
"recipient": "reporting_unit"
},
{
"event_type": "registration_not_found",
"translation_key": "messages.validation.woman_id",
"recipient": "reporting_unit"
}
]
}
]
5. Upload App Settings
To upload app settings to your local instance, run the following command:
cht --url=https://<username>:<password>@localhost --accept-self-signed-certs upload-app-settings
Important
Be sure to replace the values <username>
and <password>
with the actual username and password of your test instance.
Next steps
In the next tutorial, you will define scheduled messages that can be triggered or cleared by submitting SMS forms.