5
0
mirror of https://github.com/cwinfo/envayasms.git synced 2024-11-14 20:30:26 +00:00
envayasms/.phrozn/entries/serverapi/index.twig

599 lines
21 KiB
Twig
Executable File

id: serverapi
title: Server API Reference
---
<p>
This page describes the application programming interface (API) between the EnvayaSMS app and your server. Deploying EnvayaSMS requires implementing a script on your server in accordance with this API.
</p>
<p>
For convenience, EnvayaSMS includes <a href='https://github.com/youngj/EnvayaSMS/tree/master/server'>server libraries and example code</a>
for certain languages.
</p>
<p>
Drupal users can also install the <a href='https://drupal.org/project/sms_envaya'>Drupal module</a> (developed by Mark Burdett / VozMob).
</p>
<p>
If a server library is not yet available for your programming language, you can still use
EnvayaSMS by implementing code in accordance with the API reference below.
We encourage you to contribute new libraries and example code back to the EnvayaSMS project!
</p>
<h3>Contents</h3>
<ul>
<li><a href='/serverapi/#overview'>API Overview</a></li>
<li><a href='/serverapi/#actions'>HTTP Request Format (Actions)</a></li>
<li><a href='/serverapi/#events'>HTTP Response Format (Events)</a></li>
<li><a href='/serverapi/#errors'>HTTP Response Error Format</a></li>
<li><a href='/serverapi/#amqp'>AMQP Message Format</a></li>
<li><a href='/serverapi/#testing'>Testing Your Implementation</a></li>
</ul>
<h3 id='overview'>API Overview</h3>
<p>
EnvayaSMS communicates with the server via HTTP POST requests, called <b>actions</b>. These actions include:
</p>
<ul>
<li>forwarding incoming messages to the server,</li>
<li>polling for outgoing messages,</li>
<li>notifying the server of the status of outgoing messages, and</li>
<li>notifying the server of a change in device status (such as battery level or power source).</li>
</ul>
<p>
All of these POST requests are made to the same URL (the "Server URL"), with data passed as normal POST parameters.
Each POST request has an "action" parameter that tells the server which action is being performed.
</p>
<p>
For each action sent by the phone, the server sends an HTTP response (as JSON).
If the action was successful, the response should contain zero or more <b>events</b>. Events include:
</p>
<ul>
<li>sending outgoing messages,</li>
<li>canceling outgoing messages that haven't been sent yet,</li>
<li>changing the settings for the EnvayaSMS app, and</li>
<li>displaying log messages in the EnvayaSMS app.</li>
</ul>
<p>
Optionally, EnvayaSMS can also connect directly to an AMQP server (such as RabbitMQ). This allows your server to push outgoing messages to the phone in real-time,
instead of requiring the phone to poll for messages at a fixed interval. Each message in AMQP queue is a single <em>event</em>, also encoded as JSON.
</p>
<p>
(Note: Prior to version 3.0, the HTTP response format was XML. <a href='/serverapi/upgrade30.html'>See information on upgrading to version 3.0</a>.)
</p>
<h3 id='actions'>HTTP Request Format (Actions)</h3>
<p>
The following parameters are sent in all POST requests from EnvayaSMS:
</p>
<dl>
<dt>"version" ::= &lt;integer&gt;</dt>
<dd>
EnvayaSMS's version code. This is an integer that will be incremented whenever
a new version of EnvayaSMS is released. (It is not the same as the version name shown
on the Help screen.)
<br />
<br />
This allows the server to support phones running different API versions at the same time.
If a deployment has many phones running with EnvayaSMS, the server should update its code first,
then the phones can be upgraded to the new version of EnvayaSMS as convenient.
</dd>
<dt>"phone_number" ::= &lt;text&gt;</dt>
<dd>
The phone number of the phone running EnvayaSMS, as entered under Menu &gt; Settings.
<br /><br />
This allows the server to differentiate between EnvayaSMS clients if multiple phones
are running EnvayaSMS.
</dd>
<dt>"log" ::= &lt;text&gt;</dt>
<dd>
Log messages printed to the EnvayaSMS console since the last successful HTTP request.
<br /><br />
You may wish to append this data to a log file to allow administrators
to see error details without needing physical access to the phone.
<br /><br />
EnvayaSMS does not guarantee that the server receives log messages in order. Occasionally,
the server may receive the same log message multiple times.
</dd>
<dt>"network" ::= &lt;text&gt;</dt>
<dd>
The phone's current type of internet connectivity. Typically this is something like "MOBILE" or "WIFI".
</dd>
<dt>"settings_version" ::= &lt;integer&gt;</dt>
<dd>
The current value of the "settings_version" setting.
(The server may optionally set this setting by pushing settings to the phone in a 'settings' event.)
<br /><br />
This allows the server to determine if it should push new settings to the phone, allowing
you to manage and update the app settings remotely (i.e. without manually typing them into the app).
</dd>
<dt>"now" ::= &lt;long integer&gt;</dt>
<dd>
The current time in milliseconds since the Unix epoch at midnight, January 1, 1970 UTC, according to the phone's clock.
</dd>
<dt>"battery" ::= &lt;integer&gt;</dt>
<dd>
The current percentage of the phone's battery level, from 0 to 100.
</dd>
<dt>"power" ::= &lt;integer&gt;</dt>
<dd>
The current power source of the Android phone; 0=battery, 1=USB; 2=AC
</dd>
<dt>"action" ::= "outgoing" | "incoming" | "send_status" | "device_status" | "test" <br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| "amqp_started" | "forward_sent"</dt>
<dd>
The request action determines the purpose of the HTTP request:
<dl>
<dt>"outgoing":</dt>
<dd>
Poll the server for events (including, but not limited to, outgoing messages)
</dd>
<dt>"incoming":</dt>
<dd>
Forward an incoming message to the server (SMS, MMS, or call notification)
</dd>
<dt>"send_status":</dt>
<dd>
Update the server on the status of sending an outgoing message
</dd>
<dt>"device_status":</dt>
<dd>
Notify the server of a change in the Android device's state.
</dd>
<dt>"test":</dt>
<dd>
Test the server connection.
</dd>
<dt>"amqp_started":</dt>
<dd>
The phone has established a real-time connection to an AMQP server.
</dd>
<dt>"forward_sent":</dt>
<dd>
Forwards a message to the server that was previously sent via the Android phone's
Messaging app.
</dd>
</dl>
The other POST parameters sent depend on the request action.
</dd>
</dl>
The following HTTP Headers are sent in all POST requests from EnvayaSMS:
<dl>
<dt>"X-Request-Signature" ::= &lt;text&gt;</dt>
<dd>
A signature of the request to verify the phone and the server share the same password.
(This doesn't protect against MITM snooping or replay attacks, so it is recommended to
use the <code>https://</code> protocol.)
<br />
<br />
The signature is calculated by the following algorithm:
<ol>
<li>Sort all POST parameters, not including file uploads,
by the name of the field (in the usual ASCII order).</li>
<li>Generate an input string by concatenating:
<ul>
<li>the server URL,</li>
<li>each of the sorted POST parameters, in the format name=value for each name/value pair,</li>
<li>the password,</li>
</ul>
with a comma in between each element, like so:
<br />
<code>"&lt;serverURL&gt;,&lt;name1&gt;=&lt;value1&gt;,&lt;...&gt;,&lt;nameN&gt;=&lt;valueN&gt;,&lt;password&gt;"</code>
</li>
<li>Generate the SHA-1 hash of the input string in UTF-8</li>
<li>Encode the SHA-1 hash using Base64 with no line breaks.</li>
</ol>
</dd>
</dl>
Additional parameters sent in POST requests with <b>action=incoming</b>:
<dl>
<dt>"from" ::= &lt;text&gt;</dt>
<dd>
The phone number of the message sender.
</dd>
<dt>"message_type" ::= "sms" | "mms" | "call"</dt>
<dd>
Whether this message is a SMS, MMS, or a notification of an incoming call.
</dd>
<dt>"message" ::= &lt;text&gt;</dt>
<dd>
The message body of the SMS, or the content of the <code>text/plain</code> part of the MMS.
For multipart SMS messages, this field contains all parts concatenated and may be longer than 160 characters.
(This field is empty for incoming call notifications.)
</dd>
<dt>"timestamp" ::= &lt;long integer&gt;</dt>
<dd>
The timestamp of the incoming message, in milliseconds since midnight, January 1, 1970 UTC.
</dd>
</dl>
Additional parameters sent in POST requests with <b>action=incoming and message_type=mms</b>:
<dl>
<dt>"mms_parts" ::= &lt;json_array&gt;</dt>
<dd>
Metadata for each part of the MMS. Each item in the JSON array is an object
with the following keys and values:
<dl>
<dt>"name" ::= &lt;text&gt;</dt>
<dd>
The name of an additional form field where the content of the MMS part
is sent as an attached file.
</dd>
<dt>"cid" ::= &lt;text&gt;</dt>
<dd>
The Content ID of the MMS part. This allows the server to resolve
references in the SMIL part of the MMS
(e.g. <code>&lt;img region="Image" src="cid:805"/&gt;</code>).
</dt>
<dt>"type" ::= "application/smil" | "text/plain" | "image/jpeg" | ...</dt>
<dd>
The Content Type of the MMS part.
</dd>
<dt>"filename" ::= &lt;text&gt;</dt>
<dd>
The filename of the MMS part, as sent by the sender phone,
e.g. <code>"Image001.jpg"</code>.
In cases when the original filename is not available, this filename is a random string.
</dt>
</dl>
In addition, the request contains form fields with the content of each MMS part,
with names as listed in the <code>mms_parts</code> field. Text parts are encoded in UTF-8.
</dt>
</dl>
Additional parameters sent in POST requests with <b>action=outgoing</b>:
<dl>
<dt>
(None)
</dt>
</dl>
Additional parameters sent in POST requests with <b>action=send_status</b>:
<dl>
<dt>"id" ::= &lt;text&gt;</dt>
<dd>
The Server's ID for the outgoing message (from the <code>id</code> attribute
of an <a href='#sms'>sms</a> tag in a previous XML response from the server).
</dd>
<dt>"status" ::= "queued" | "failed" | "cancelled" | "sent"</dt>
<dd>
The current status of the outgoing message.
</dd>
<dt>"error" ::= &lt;text&gt;</dt>
<dd>
A description of the reason for the error, if the message
failed to send; or, an empty string if the message
has been sent successfully.
</dd>
</dl>
Additional parameters sent in POST requests with <b>action=device_status</b>:
<dl>
<dt>"status" ::= "power_connected" | "power_disconnected" <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | "battery_low" | "battery_okay"</dt>
<dd>
This field describes a condition that has changed on the Android device.
<dl>
<dt>"power_connected":</dt>
<dd>
The phone is now connected to external power.
</dd>
<dt>"power_disconnected":</dt>
<dd>
This phone is no longer connected to external power.
</dd>
<dt>"battery_low":</dt>
<dd>
The phone's battery level has dropped below 15%.
</dd>
<dt>"battery_okay":</dt>
<dd>
The phone's battery level is now at least 20% (after dropping below 15%).
</dd>
<dt>"send_limit_exceeded":</dt>
<dd>
EnvayaSMS is delaying sending outgoing messages because the rate limit for sending messages has been exceeded. (Installing additional expansion packs may be needed.)
</dd>
</dl>
</dd>
</dl>
Additional parameters sent in POST requests with <b>action=forward_sent</b>:
<dl>
<dt>"to" ::= &lt;text&gt;</dt>
<dd>
The phone number that the message was sent to.
</dd>
<dt>"message_type" ::= "sms"</dt>
<dd>
Currently only SMS messages are supported.
</dd>
<dt>"message" ::= &lt;text&gt;</dt>
<dd>
The message body of the SMS.
</dd>
<dt>"timestamp" ::= &lt;long integer&gt;</dt>
<dd>
The timestamp of the outgoing message, in milliseconds since midnight, January 1, 1970 UTC.
</dd>
</dl>
Additional parameters sent in POST requests with <b>action=amqp_started</b>:
<dl>
<dt>"consumer_tag" ::= &lt;text&gt;</dt>
<dd>
The consumer tag of the AMQP connection.
<br />
<br />
The server can use this action to kick off old AMQP connections
(that weren't closed properly) before their heartbeat timeout expires.
With RabbitMQ, this can be done using the management API.
</dd>
</dl>
<h3 id='events'>
HTTP Response Format (Events)
</h3>
<p>
In response to a successful HTTP request (i.e., action), the server should return HTTP status code 200, with an <code>application/json</code> content type.
</p>
<p>
The response body should contain a JSON object with an <code>events</code> property, which is an array of events.
Each event is a JSON object, containing one or more properties.</p>
<p>
For example, the following response contains one 'send' event that instructs EnvayaSMS to send one message:
</p>
<pre>
{
"events":[{
"event":"send",
"messages":[{
"id":"4f7c9cea5e11b",
"to":"6507993371",
"message":"hello world'"
}]
}]
}
</pre>
<p>
All events contain at least the following property:
</p>
<dl>
<dt>"event" ::= "send" | "cancel" | "cancel_all" | "log" | "settings"</dt>
<dd>
This property determines the type of event:
<dl>
<dt>"send":</dt>
<dd>
Send one or more outgoing messages
</dd>
<dt>"cancel":</dt>
<dd>
Attempt to cancel an outgoing message that has been queued.
</dd>
<dt>"cancel_all":</dt>
<dd>
Attempt to cancel all outgoing messages that have been queued.
</dd>
<dt>"log":</dt>
<dd>
Display a message in the EnvayaSMS app log.
</dd>
<dt>"settings":</dt>
<dd>
Update some of EnvayaSMS's settings.
</dd>
</dl>
</dd>
</dl>
Additional properties for <b>send</b> events:
<dl>
<dt>"messages" ::= &lt;array&gt;</dt>
<dd>An array of messages to send. Each message is an object with the following properties:
<dl>
<dt>"id" ::= &lt;string&gt; (optional)</dt>
<dd>
An ID for this outgoing message. (EnvayaSMS will send this
back to the server as the id field in a send_status request.)
</dd>
<dt>"to" ::= &lt;string&gt; (optional for incoming, required for outgoing)</dt>
<dd>
The phone number to send the SMS to.
<br />
<br />
This may be omitted (null) if the event is sent as a response to action=incoming.
In this case, the message will be sent as a reply to the original sender.
</dd>
<dt>"priority" ::= &lt;integer&gt; (optional)</dt>
<dd>
The priority level of the outgoing message. If your server is sending outgoing messages
faster than the phone can send them out, the priority level allows you to specify
the order to send them (e.g. so that you can send transactional SMS replies
before asynchronous notifications).
<br />
<br />
Larger integers represent higher priorities.
If omitted, the default priority level is 0.
<br />
<br />
Within a priority level, SMS messages are processed and sent in the order
they were received from the server, and from top to bottom within the XML rsponse.
</dd>
<dt>"message" ::= &lt;string&gt;</dt>
<dd>
The content of the SMS message to send. If the content is longer than the maximum size of a single SMS (typically 160 characters),
it will automatically be sent as a multipart SMS.
</dd>
</dl>
</dd>
</dl>
Additional properties for <b>cancel</b> events:
<dl>
<dt>"id" ::= &lt;string&gt;</dt>
<dd>The ID of the message to cancel sending, previously sent via a "send" event.
</dl>
Additional properties for <b>cancel_all</b> events:
<p>(None)</p>
Additional properties for <b>log</b> events:
<dl>
<dt>"message" ::= &lt;string&gt;</dt>
<dd>A string to display in the EnvayaSMS log.
</dl>
Additional properties for <b>settings</b> events:
<dl>
<dt>"settings" ::= &lt;object&gt;</dt>
<dd><p>An object where each property name is the name of an EnvayaSMS setting, and each property's value is the new value for that setting.</p>
<p>The following settings are used within EnvayaSMS:</p>
<dl>
<dd>enabled ::= &lt;boolean&gt;</dd>
<dd>server_url ::= &lt;string&gt;</dd>
<dd>phone_number ::= &lt;string&gt;</dd>
<dd>password ::= &lt;string&gt;</dd>
<dd>outgoing_interval ::= &lt;integer&gt;</dd>
<dd>keep_in_inbox ::= &lt;boolean&gt;</dd>
<dd>call_notifications ::= &lt;boolean&gt;</dd>
<dd>forward_sent ::= &lt;boolean&gt;</dd>
<dd>network_failover ::= &lt;boolean&gt;</dd>
<dd>test_mode ::= &lt;boolean&gt;</dd>
<dd>auto_add_test_number ::= &lt;boolean&gt;</dd>
<dd>ignore_shortcodes ::= &lt;boolean&gt;</dd>
<dd>ignore_non_numeric ::= &lt;boolean&gt;</dd>
<dd>amqp_enabled ::= &lt;boolean&gt;</dd>
<dd>amqp_port ::= &lt;integer&gt;</dd>
<dd>amqp_vhost ::= &lt;integer&gt;</dd>
<dd>amqp_ssl ::= &lt;boolean&gt;</dd>
<dd>amqp_user ::= &lt;string&gt;</dd>
<dd>amqp_password ::= &lt;string&gt;</dd>
<dd>amqp_queue ::= &lt;string&gt;</dd>
<dd>amqp_heartbeat ::= &lt;integer&gt;</dd>
<dd>market_version ::= &lt;integer&gt;</dd>
<dd>market_version_name ::= &lt;string&gt;</dd>
<dd>settings_version ::= &lt;integer&gt;</dd>
</dl>
</dd>
</dl>
<h3 id='errors'>HTTP Response Error Format</h3>
<p>
If the phone's HTTP request failed for some reason, the server should return an appropriate HTTP error code (400-499 for client errors, 500-599 for server errors).
</p>
<p>
To show a detailed error message in the EnvayaSMS app logs, set the content type as <code>application/json</code> and return a JSON object
as the response body, like so:
</p>
<pre>
{
"error":{
"message:"Your error message"
}
}
</pre>
<h3 id='amqp'>
AMQP Message Format
</h3>
<p>
If you are using AMQP to push outgoing messages and other events to the phone in real time, the content type for each message
should be <code>application/json</code> and the body of each message should be a serialized JSON object representing a single
<em>event</em>, as defined in the <a href='/serverapi/#events'>preceding section</a>.
</p>
<h3 id='testing'>Testing Your Implementation</h3>
<p>
The <a href='https://raw.github.com/youngj/EnvayaSMS/master/server/php/example/www/test.html'>EnvayaSMS Request Simulator</a>
is a standalone HTML file that allows you to simulate EnvayaSMS's HTTP requests entirely in your browser via JavaScript.
</p>
<p>
Just copy the HTML file somewhere on your site, and open it in a web browser. The URL of the EnvayaSMS Request Simulator
must be on the same domain as the Server URL.
</p>