Simple and extendable app server for XMPP push notifications as defined in XEP-0357.
The app server is implemented as a module for the Prosody XMPP server.
Currently, only push notifications to Apple's APNS and Google's FCM are implemented, but other push services can easily be added in a separate module.
- Prosody 0.9 or later.
- Lua 5.1 (5.2 should also work, but is untested).
- Installed penlight Lua library (Debian package:
lua-penlight
). - Installed luasec Lua library version 0.5 (Debian package:
lua-sec
), higher versions are untested.
Just check out the repository somewhere and point prosody at this directory
using plugin_paths
in its main config file.
For example: plugin_paths = { "/usr/local/lib/mod_push_appserver" }
.
Then add mod_push_appserver
and the submodule you need (for example
mod_push_appserver_apns
or mod_push_appserver_fcm
) to global
modules_enabled
or to the enabled modules of a specific virtual host.
I will eventually add a commented minimal configuration example for prosody to this repository, too.
For chat apps using VoIP pushes to APNS, the priority should be set to high
.
The alert text can be ignored in this case (if you only want to wakeup your
device). For normal push notifications, the priorities high
and silent
are
supported. The configured alert text (push_appserver_apns_push_alert
) is
ignored for silent
pushes.
For pushes to FCM the priorities high
and normal
are supported with normal
priorities being delayed while the device is in doze mode.
Pushes having priority high
are always delivered, even in doze mode, thus
should be used for chat apps.
All POST
endpoints can be used via GET
to get back a simple html form which
allows you to manually test the endpoint behaviour in your browser, if the config
option push_appserver_debugging
is set to true (an error is returned otherwise).
-
POST to
http://<host>:5280/push_appserver/v1/register
orhttps://<host>:5281/push_appserver/v1/register
POST data:type=<push type>&node=<device uuid>&token=<apns/fcm/etc. push token>
function: register device for push
result: text document separated by\n
- first line:
OK
, everything else (includingERROR
) is specified as error condition if ok: 2nd line: XEP-0357 pushnode
, 3rd line: XEP-0357 pushsecret
if error: 2nd and subsequent lines: error description
- first line:
-
POST to
http://<host>:5280/push_appserver/v1/unregister
orhttps://<host>:5281/push_appserver/v1/unregister
POST data:type=<push type>&node=<device uuid>
function: unregister device
result: text document separated by\n
- first line:
OK
, everything else (includingERROR
) is specified as error condition
if ok: 2nd line: XEP-0357 pushnode
, 3rd line: XEP-0357 pushsecret
if error: 2nd and subsequent lines: error description
- first line:
-
POST to
http://<host>:5280/push_appserver/v1/push
orhttps://<host>:5281/push_appserver/v1/push
POST data:node=<device uuid>&secret=<secret obtained on register>
function: send push notification to device
result: text document separated by\n
- first line:
OK
, everything else (includingERROR
) is specified as error condition
if ok: 2nd line: XEP-0357 pushnode
if error: 2nd and subsequent lines: error description
- first line:
-
GET to
http://<host>:5280/push_appserver/v1/settings
orhttps://<host>:5281/push_appserver/v1/settings
function: get list of registered device UUIDs
result: html site listing all registered device UUIDS as links -
GET to
http://<host>:5280/push_appserver/v1/settings/<device uuid>
orhttps://<host>:5281/push_appserver/v1/settings/<device uuid>
function: get internal data saved for this device UUID
result: HTML site listing all data (serialized Lua table using penlight'spl.pretty
)
- push_appserver_debugging (boolean)
Make/push_appserver/v1/settings
HTTP endpoint available. Default:false
.
This setting will also make http forms available at allPOST
HTTP endpoints for easier manual testing of your setup by simply using your browser of choice. - push_appserver_rate_limit (number)
Allow this much push requests to one node per second. Default: 5.
This should mitigate some DOS attacks.
- push_appserver_apns_cert (string)
Path to your APNS push certificate in PEM format. - push_appserver_apns_key (string)
Path to your APNS push certificate key in PEM format. - push_appserver_apns_capath (string)
Path to CA certificates directory. Default:"/etc/ssl/certs"
(Debian and Ubuntu use this path for the system CA store). - push_appserver_apns_ciphers (string)
Ciphers to use when establishing a tls connection. Default:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256
- push_appserver_apns_sandbox (boolean)
Use apns sandbox api endpoint if
true
, production endpoint otherwise. Default:true
. - push_appserver_apns_push_alert (string)
Alert text for push message. Default:"dummy"
. - push_appserver_apns_push_ttl (number)
TTL for push notification in seconds. Default:nil
(that means infinite). - push_appserver_apns_push_priority (string)
Value"high"
for high priority pushes or"silent"
for silent pushes. Default:"silent"
. - push_appserver_apns_feedback_request_interval (number)
Interval in seconds to query Apple's feedback service for extinction of invalid tokens. Default: 24 hours.
- push_appserver_fcm_key (string)
Your FCM push credentials. - push_appserver_fcm_capath (string)
Path to CA certificates directory. Default:"/etc/ssl/certs"
(Debian and Ubuntu use this path for the system CA store). - push_appserver_fcm_ciphers (string)
Ciphers to use when establishing a tls connection. Default:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256
- push_appserver_fcm_push_ttl (number)
TTL for push notification in seconds, can be 4 weeks at max. Default:nil
(that means 4 weeks). - push_appserver_fcm_push_priority (string)
Value"high"
for high priority pushes that wake up the device even when in doze mode or"normal"
for normal pushes that can be delayed. Default:"high"
.
mod_push_appserver and its submodules use events to communicate with each other. These events are documented here.
mod_push_appserver triggers the event incoming-push-to-<push type>
(currently only the types apns
and fcm
are supported).
The event handler has to return true
or an error description string
for failed push attempts and false
for successfull ones.
Returning nil
will be handled as error!
The event data has to include the following keys:
- origin
Prosody session the stanza came from (typically an s2s session). - settings
The registered push settings available at the/push_appserver/v1/settings/<device uuid>
HTTP endpoint. - stanza
The incoming push stanza (see XEP-0357 for more information).
Submodules (like mod_push_appserver_apns) can trigger the event
unregister-push-token
. The event data has to include the following keys:
- token
The push token to invalidate (note: this is not the secret obtained by registering the device, but the raw token obtained from APNS, FCM etc.). - type
apns
,fcm
etc. - timestamp
The timestamp of the delete request. mod_push_appserver won't unregister the token if it was re-registered after this timestamp.
{
type = "apns",
token = "DEADBEEFABCDEF0123456DEADBEEF112DEADBEEFABCDEF0123456DEADBEEF112",
last_push_error = "2017-03-18T04:07:44Z",
last_successful_push = "2017-03-18T03:54:24Z",
registered = "2017-03-17T02:10:21Z",
renewed = "2017-03-18T02:54:51Z",
node = "E0FF1D8C-EB96-4E10-A912-F68B03FD8D3E",
secret = "384e51b4b2d5e4758e5dc342b22dea9217212f2c4886e2a3dcf16f3eb0eb3807"
}