Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Moodle Mobile Push Notifications: Difference between revisions

From MoodleDocs
(28 intermediate revisions by 4 users not shown)
Line 2: Line 2:
Moodle Mobile should receive Moodle messages as push notifications on iOS and Android.
Moodle Mobile should receive Moodle messages as push notifications on iOS and Android.


== How it works ==
== Use case and web services ==
=== The generic way ===
[[Image:Screenshot_2_05_13_5_16_PM.png|thumb]]
====App====
[[Image:Screenshot_2_05_13_5_14_PM.png|thumb]]
# User runs the mobile app.
=== currently implemented use case ===
# User accepts to receive push notification.
# The user opens the app and accepts to receive push notifications. The app contacts Apple push notification server and gets a device token. The mobile app PushPlugin plugin does it.
# User logins on a Moodle site.
# The user enters its Moodle credentials. The app gets an [http://airnotifier.github.io AirNotifier] access key from the site. (note that this access key is currently the same for each site => meaningless). The key is retrieved by calling the webservice message_airnotifier_get_access_key(permissions). create_token is the only possible permission at the moment.  
# App registers the device on airnotifier (Apple device token + site url).
# The app sends its token to [http://airnotifier.github.io AirNotifier] server - it's done by a HTTP POST request.  
# App registers the device on the Moodle site (Apple device ID (or an Airnotifier device ID if it's more secured/generic) to be able to receive the notification and the device name to be able to disable the device)
# The app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename)
# User enables airnotifier notification in her/his Moodle profile.
# Someone/Something triggers a Moodle message. [http://airnotifier.github.io AirNotifier] provider (Moodle site) sends a payload for a specific device token to airnotifier server - it's done by a HTTP POST
# Moodle sends a message to Airnotifier server throughout its Airnotifier messaging provider.
# The user receive the notification.
# Airnotifier dispatches the message to the correct notification system.
# The user device receives the push notification.
# The app opens on a specific page (following the parameters payload).


====Site====
# Moodle runs Airnotifier messaging provider installation process.
# Airnotifier messaging provider requests an access key from the Airnotifier server - Moodle site temporarily opens an access point to confirm its site url.
# Airnotifer server has successfully identified the site url, it return the access key (the site can send messages and broadcast).


=== Apple use case ===
=== brainstorming use case ===
We start from the mobile device, when user launch the app, app should register it's device token to AirNotifier and Moodle at the same time, to register with AirNotifier, we could be sure the token is valid, the invalid token would disturb TCP connection with apple push notification server, so it's very important we do this. To register with Moodle, so moodle site could associate this token with user ID, when something interesting happened to this user, Moodle site will be able to send notification to certain device
# During [http://airnotifier.github.io AirNotifier] provider installation, the site contacts Airnotifer server to request an access key for itself + an access key for the devices (to send their device token to [http://airnotifier.github.io AirNotifier] server).
# The user opens the app and accepts to receive push notifications. The app contacts Apple push notification server and gets a device token.
# The user enters its Moodle credentials. The app gets an [http://airnotifier.github.io AirNotifier] access key from the site. It's done calling the webservice message_airnotifier_get_access_key(type). An admin could request the site access key, the others only get the device access key.
# The app sends its device token to [http://airnotifier.github.io AirNotifier] server + the site url (so airnotifier knows the device/site couple, and so [http://airnotifier.github.io AirNotifier] can allow site broadcast) - it's done by a HTTP POST request.
# The app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename)
# During this web service, the site confirms the device token to [http://airnotifier.github.io AirNotifier]. It's done by a HTTP POST request. [http://airnotifier.github.io AirNotifier] server deletes unconfirmed device tokens older than one minute every hours.
# Someone/Something triggers a Moodle message. [http://airnotifier.github.io AirNotifier] provider (Moodle site) sends a payload for a specific device token to airnotifier server - it's done by a HTTP POST
# Time to time, the [http://airnotifier.github.io AirNotifier] server checks Apple feedback and delete the unactive device tokens.
# When the [http://airnotifier.github.io AirNotifier] provider tries to send a message to a deleted device, it receive an error from [http://airnotifier.github.io AirNotifier] server and stores it.  Then it sends a unique alert to the device user. The device is disabled on the user messaging settings. After a month, the cron processes delete the device.


Registering token on AirNotifier: Send POST HTTP request to http://server.name/tokens with app name (it's moodle) and app access key in HTTP header, and token in HTTP body
=== another brainstorming use case ===
Registering token on Moodle: Sending user ID and token, this should be done by new web service, we probably need a new table to record user tokens, NOTE, user may has multi mobile devices, so it's one-many relationship
# All the sites (public or privately) already registered in Moodle.net will have automatically keys for using [http://airnotifier.github.io AirNotifier]
AirNotifier will issue access key to moodle installations, they share one app name: moodle, we need an admin panel in moodle to set this access key, this access keys only allow sending notifications and broadcasts, they don't have permission to register tokens, we only allow tokens being registered from mobile devices
# When registering a new site in Moodle.net there will be a new option for enabling PUSH Notificiations (true by default)
# If your site is not registered and your Mobile Services were enabled you will see a message in the Moodle Notifications page indicating that "You must register your site in order to be able to send PUSH Notifications"
# If your site is not registered and you enable Mobile Services you will see a message near to the "Enable Mobile Services" indicating that "You must register your site in order to be able to send PUSH Notifications"
# If your installation has a very big number of users, during the registration process and in the Notifications page you will see a message indicating "The public PUSH Notification server is limited to Moodle sites with less than N (5k, 20k...) users"
# The user opens the app and accepts to receive push notifications. The app contacts Apple push notification server and gets a device token. A user can disable at any time notifications for his device
# Every time the user open the app, the app gets an [http://airnotifier.github.io AirNotifier] access key from the site. It's done calling the webservice message_airnotifier_get_access_key(type). An admin could request the site access key, the others only get the device access key.
# The app sends its device token to [http://airnotifier.github.io AirNotifier] server + the site url (so airnotifier knows the device/site couple, and so [http://airnotifier.github.io AirNotifier] can allow site broadcast) - it's done by a HTTP POST request. This is done only if your device token has changed.
# The app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename, siteURL) This is done every time a user opens the app
# Since the app is sending its device token every time a user opens the app, a cron job in the Moodle Site can delete old device tokens (so we can avoid the [http://airnotifier.github.io AirNotifier] feedback service in the first stage)
# Someone/Something triggers a Moodle message. [http://airnotifier.github.io AirNotifier] provider (Moodle site) sends a payload for a specific device token + specific site to airnotifier server - it's done by a HTTP POST
# If the user disable the PUSH Notification feature, a WS message_airnotifier_remove_user_device is called, also the [http://airnotifier.github.io AirNotifier] is requested to delete the user device


iPhone app use a separate access key, which will be used to register device token


So we got user's device tokens in Moodle database, when somethings happened, for instance, a new instant message sent to a user who has mobile device registered. We will look for messaging processor in Moodle, this message processor is in charge of sending push notification request to AirNotifier, it will send POST HTTP request to http://server.name/notification with token and message digest in HTTP body, app name (it's moodle) and access key in http header
Benefits are:
-We can reuse the current registration process that is secure (as far as I know)
-The [http://airnotifier.github.io AirNotifier] API for register new sites will be exposed only to Moodle.net (not to all sites)
-It will be easier notify registered sites that are abusing (Moodle.net can communicate with sites (sending an automatic email to the user admin))
-Moodle will have statistics of sites using PUSH directly in Moodle.net (no need to ask [http://airnotifier.github.io AirNotifier])
-The registration process can be improved to retrieve the number of registered devices that are receiving notifications
-I think that it will "enforce" users to register their sites (for receive security notifications, etc..)
-Big companies with big Moodle installations usually doesn't register their Moodle sites, this will force these companies to use their own [http://airnotifier.github.io AirNotifier] server instance
-Since we have the number of users in a Moodle site, we can automatically disable [http://airnotifier.github.io AirNotifier] for big installations (more thant Nk users)
-I think that having all the information that the registration provides will help us to "monitor and prevent abuse" of the [http://airnotifier.github.io AirNotifier] server


The message processor should be a new output type message plugin besides email, jabber and and popup
== Payload content ==
In user settings page, user should have options to choose whether or not to send notification to certain devices.
The current payload content would need a bit of brainstorming. We need to identify what to send as it is extremely short. The app will behave following the content it receives.
Broadcast, moodle site may want to broadcast messages to all registered mobile devices, it's inefficient to send individual notification to AirNotifier, it can be done by using http://server.name/broadcast service, moodle site only send one POST request to this endpoint with access key and app name in HTTP header and md5($CFG->wwwroot) in HTTP body, the hashed wwwroot is the default channel subscribed by all devices registered in AirNotifier, it will take care of broadcasting
=== Apple ===
 
The Apple payload is limited to 256bytes and it includes everything sent. Our current implementation is still quite of a wip:
=== Google specificities ===
<code php>
{type:'moodle_instantmessage',id:'8',urlparams:'{"user":"2","id":"8"}',userfrom:'Manager Moodle',date:'1367477362',alert:'This is a message text.',}
</code>
=== GCM ===
The Apple payload is about 4Kb. As it's more more permissive than Apple, it is not an issue. The content will be the same than Apple ones, just the format changes.


==Deliverables==
==Deliverables==
* push notification support on the mobile app - the app receives the push notification and behaves correctly.
* push notification support on the mobile app - the app receives the push notification and behaves correctly.
* The Airnotifier server - it sends notification to APNS / GCM.
* The [http://airnotifier.github.io AirNotifier] server - it sends notification to APNS / GCM.
* The Airnotifier provider - it sends Moodle messages to Airnotifier - MDL-36445
* The [http://airnotifier.github.io AirNotifier] provider - it sends Moodle messages to [http://airnotifier.github.io AirNotifier] - MDL-36445


=== Airnotifier messaging provider ===
=== [http://airnotifier.github.io AirNotifier] messaging provider ===
In your messaging setting page you can select which of your devices can receive push notifications. MDL-36445
In your messaging setting page you can select which of your devices can receive push notifications. MDL-36445
The provider has usual messaging provider settings.
The provider has usual messaging provider settings.


=== Airnotifier server ===
=== [http://airnotifier.github.io AirNotifier] server ===
To install the server follow: https://github.com/dongsheng/airnotifier/wiki/Installation
To install the server follow: https://github.com/airnotifier/airnotifier/wiki/Installation


Need to be done:
Need to be done:
* feedback - MOBILE-191
* feedback - MOBILE-191
* load stress - Done
* load stress
* IP banning - Done MOBILE-192
* IP banning - need to be tested MOBILE-192
* Site broadcast (site keys) MOBILE-395
* Site broadcast (site keys) MOBILE-395
* DDOS attacks
* DDOS attacks
* iOS support - Done
* iOS support - it works
* Android support MOBILE-396
* Android support MOBILE-396


=== App push notification support in the mobile app ===
=== App push notification support in the mobile app ===
# Get the token from Apple (through phonegap PushPlugin)
MOBILE-168
# Send the token to Airnotifier server (+ site url). See https://github.com/dongsheng/airnotifier/blob/master/test/token_create.sh. Currently it's not possible to link the site url to the token.
# send the token by web service to the Moodle site.


==== The app is closed or is running in the background ====
==== The app is closed or is running in the background ====
It's a normal OS notification. The user can open the app from it. We need to define what happens when we open the app.
It's a normal OS notification. The user can open the app from it. We need to define what happens when we open the app. See payload content section.


==== The app is opened ====
==== The app is opened ====
Line 77: Line 98:
* Are we checking the 'feedback service' and removing devices which no longer exist, apple ominously writes "Note: APNs monitors providers for their diligence in checking the feedback service and refraining from sending push notifications to nonexistent applications on devices."
* Are we checking the 'feedback service' and removing devices which no longer exist, apple ominously writes "Note: APNs monitors providers for their diligence in checking the feedback service and refraining from sending push notifications to nonexistent applications on devices."


== Improvement ==
== Improvements ==
See Apu's comment in https://tracker.moodle.org/browse/MDL-36445?focusedCommentId=200343&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-200343.
See Apu's comment in https://tracker.moodle.org/browse/MDL-36445?focusedCommentId=200343&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-200343.
Specially the mention about language.
Specially the mention about language.
== Web service call ==
=== current implementation ===
# the app contact apple to get its device token (it's done by the PushPlugin that itself use Cocoa API)
# after login on the site, the app get an access key from the site to add its token to airnotifier (this access key is currently the same for each site => meaningless). It's done calling the webservice message_airnotifier_get_access_key(permissions). create_token is te only possible permission.
# the app send its token to Airnotifier server - it's done by a HTTP POST request.
# the app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename)
# Airnotifier provider (Moodle site) sends a message for a specific device token to airnotifier server - it's done by a HTTP POST
=== suggested implementation ===
# during the message provider installation, the site contact Airnotifer to request an access key for itself + an access key for their user devices to add device token on airnotifier.
# the app contact apple to get its device token (it's done by the PushPlugin that itself use Cocoa API)
# after login on the site, the app get an access key from the site to add its token to airnotifier. It's done calling the webservice message_airnotifier_get_access_key(permissions). An admin could request the site token, the other only get create_token.
# the app send its token to Airnotifier server indicating the site url (so airnotifier knows what token a site can broadcast) - it's done by a HTTP POST request.
# the app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename)
# during this web service, the site confirms the device token to Airnotifier. It's done by a HTTP POST request. Airnotifier server deletes unconfirmed device token older than one minute.
# Airnotifier provider (Moodle site) sends a message for a specific device token to airnotifier server - it's done by a HTTP POST
# A feedback service is run every hour and clean up the unactive device token from airnotifier.
# When message provider try to send a message to a delete device, it store the error and send a unique message to the user to alert that it's device is not registered anymore. The device is disabled. After a month cron delete the device.
== Payload format ==
The current payload format would need a bit of brainstorming. We need to identify what to send as it is extremely short.
=== Apple ===
The Apple payload is limited to 256bytes and this include any params! Our current implementation is still quite a wip:
<code php>
{type:'moodle_instantmessage',id:'8',urlparams:'{"user":"2","id":"8"}',userfrom:'Manager Moodle',date:'1367477362',alert:'This is a message text.',}
</code>
=== GCM ===
The Apple payload is about 4Kb.

Revision as of 06:38, 4 June 2016

Goal

Moodle Mobile should receive Moodle messages as push notifications on iOS and Android.

Use case and web services

Screenshot 2 05 13 5 16 PM.png
Screenshot 2 05 13 5 14 PM.png

currently implemented use case

  1. The user opens the app and accepts to receive push notifications. The app contacts Apple push notification server and gets a device token. The mobile app PushPlugin plugin does it.
  2. The user enters its Moodle credentials. The app gets an AirNotifier access key from the site. (note that this access key is currently the same for each site => meaningless). The key is retrieved by calling the webservice message_airnotifier_get_access_key(permissions). create_token is the only possible permission at the moment.
  3. The app sends its token to AirNotifier server - it's done by a HTTP POST request.
  4. The app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename)
  5. Someone/Something triggers a Moodle message. AirNotifier provider (Moodle site) sends a payload for a specific device token to airnotifier server - it's done by a HTTP POST
  6. The user receive the notification.


brainstorming use case

  1. During AirNotifier provider installation, the site contacts Airnotifer server to request an access key for itself + an access key for the devices (to send their device token to AirNotifier server).
  2. The user opens the app and accepts to receive push notifications. The app contacts Apple push notification server and gets a device token.
  3. The user enters its Moodle credentials. The app gets an AirNotifier access key from the site. It's done calling the webservice message_airnotifier_get_access_key(type). An admin could request the site access key, the others only get the device access key.
  4. The app sends its device token to AirNotifier server + the site url (so airnotifier knows the device/site couple, and so AirNotifier can allow site broadcast) - it's done by a HTTP POST request.
  5. The app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename)
  6. During this web service, the site confirms the device token to AirNotifier. It's done by a HTTP POST request. AirNotifier server deletes unconfirmed device tokens older than one minute every hours.
  7. Someone/Something triggers a Moodle message. AirNotifier provider (Moodle site) sends a payload for a specific device token to airnotifier server - it's done by a HTTP POST
  8. Time to time, the AirNotifier server checks Apple feedback and delete the unactive device tokens.
  9. When the AirNotifier provider tries to send a message to a deleted device, it receive an error from AirNotifier server and stores it. Then it sends a unique alert to the device user. The device is disabled on the user messaging settings. After a month, the cron processes delete the device.

another brainstorming use case

  1. All the sites (public or privately) already registered in Moodle.net will have automatically keys for using AirNotifier
  2. When registering a new site in Moodle.net there will be a new option for enabling PUSH Notificiations (true by default)
  3. If your site is not registered and your Mobile Services were enabled you will see a message in the Moodle Notifications page indicating that "You must register your site in order to be able to send PUSH Notifications"
  4. If your site is not registered and you enable Mobile Services you will see a message near to the "Enable Mobile Services" indicating that "You must register your site in order to be able to send PUSH Notifications"
  5. If your installation has a very big number of users, during the registration process and in the Notifications page you will see a message indicating "The public PUSH Notification server is limited to Moodle sites with less than N (5k, 20k...) users"
  6. The user opens the app and accepts to receive push notifications. The app contacts Apple push notification server and gets a device token. A user can disable at any time notifications for his device
  7. Every time the user open the app, the app gets an AirNotifier access key from the site. It's done calling the webservice message_airnotifier_get_access_key(type). An admin could request the site access key, the others only get the device access key.
  8. The app sends its device token to AirNotifier server + the site url (so airnotifier knows the device/site couple, and so AirNotifier can allow site broadcast) - it's done by a HTTP POST request. This is done only if your device token has changed.
  9. The app registers its device to the site - it's done by a ws call message_airnotifier_add_user_device(appname, devicetoken, devicename, siteURL) This is done every time a user opens the app
  10. Since the app is sending its device token every time a user opens the app, a cron job in the Moodle Site can delete old device tokens (so we can avoid the AirNotifier feedback service in the first stage)
  11. Someone/Something triggers a Moodle message. AirNotifier provider (Moodle site) sends a payload for a specific device token + specific site to airnotifier server - it's done by a HTTP POST
  12. If the user disable the PUSH Notification feature, a WS message_airnotifier_remove_user_device is called, also the AirNotifier is requested to delete the user device


Benefits are: -We can reuse the current registration process that is secure (as far as I know) -The AirNotifier API for register new sites will be exposed only to Moodle.net (not to all sites) -It will be easier notify registered sites that are abusing (Moodle.net can communicate with sites (sending an automatic email to the user admin)) -Moodle will have statistics of sites using PUSH directly in Moodle.net (no need to ask AirNotifier) -The registration process can be improved to retrieve the number of registered devices that are receiving notifications -I think that it will "enforce" users to register their sites (for receive security notifications, etc..) -Big companies with big Moodle installations usually doesn't register their Moodle sites, this will force these companies to use their own AirNotifier server instance -Since we have the number of users in a Moodle site, we can automatically disable AirNotifier for big installations (more thant Nk users) -I think that having all the information that the registration provides will help us to "monitor and prevent abuse" of the AirNotifier server

Payload content

The current payload content would need a bit of brainstorming. We need to identify what to send as it is extremely short. The app will behave following the content it receives.

Apple

The Apple payload is limited to 256bytes and it includes everything sent. Our current implementation is still quite of a wip: {type:'moodle_instantmessage',id:'8',urlparams:'{"user":"2","id":"8"}',userfrom:'Manager Moodle',date:'1367477362',alert:'This is a message text.',}

GCM

The Apple payload is about 4Kb. As it's more more permissive than Apple, it is not an issue. The content will be the same than Apple ones, just the format changes.

Deliverables

  • push notification support on the mobile app - the app receives the push notification and behaves correctly.
  • The AirNotifier server - it sends notification to APNS / GCM.
  • The AirNotifier provider - it sends Moodle messages to AirNotifier - MDL-36445

AirNotifier messaging provider

In your messaging setting page you can select which of your devices can receive push notifications. MDL-36445 The provider has usual messaging provider settings.

AirNotifier server

To install the server follow: https://github.com/airnotifier/airnotifier/wiki/Installation

Need to be done:

App push notification support in the mobile app

MOBILE-168

The app is closed or is running in the background

It's a normal OS notification. The user can open the app from it. We need to define what happens when we open the app. See payload content section.

The app is opened

The app displays a notification popup. Or better, it's a small temporary notification message at the top that retarct by itself - less intrusive.

Risks

These risks have been raised by Dan in MDL-36445:

  • Have we load tested it with large numbers of users/notifications?
  • What is stopping someone downloading Moodle getting the keys to DOS our push notification service (surely blacklisting us with apple)
  • If someone gains access to device ids, could they then use our service to spam users?
  • Are we checking the 'feedback service' and removing devices which no longer exist, apple ominously writes "Note: APNs monitors providers for their diligence in checking the feedback service and refraining from sending push notifications to nonexistent applications on devices."

Improvements

See Apu's comment in https://tracker.moodle.org/browse/MDL-36445?focusedCommentId=200343&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-200343. Specially the mention about language.