• log out

Subscriptions

Users may subscribe to, and unsubscribe from, certain streams. When all of the user's clients (user agents) are not connected to the server by a socket, they are considered "disconnected". If a message is posted to a stream that a user is subscribed to, while they are disconnected, it may cause an offline notification to be delivered.

Each subscription has a filter which records (in JSON) some information:

  • types is an array of regular expression strings against which the type of the message is tested.
  • notifications is the limit on the number of offline notifications that can be delivered until the user connects again. Here, 0 means no limit.

Rules

If a user is disconnected and a message passes the subscription filter, it is then processed by the rules, if any, that the subscriber user set up. A user may have zero or more rules for each subscription.

Each rule has the following fields which records (in JSON) some information:

  • filter is an object possibly containing:
    • types is an array of regular expression strings against which the type of the message is tested.
    • labels is an array of strings naming some contact labels of the subscriber user. If the user who posted the message is a contact with one of those labels, this filter passes.
  • readyTime is a timestamp, in seconds since 1970, when the user's device is ready to receive notifications again.
  • deliver is an object possibly containing:
    • to should normally be a string naming the key under the Streams/rules/deliver config which is stored an array of strings. But you can also pass your own array of strings here. In either case, the array can include:
      • "email" use email if it exists
      • "email+pending" use email or pending (unverified) email
      • "mobile" use mobile number if it exists
      • "email+pending" use mobile or pending (unverified) mobile
      • "devices" deliver push notifications to any devices, browsers, etc. if user authorized them
      Notification delivery is attempted in the order that the strings appear in the array. If one succeeds, the rest are not used. You can also have an array of strings in place of one of these strings, in which case all the strings inside are used, even if one of them succeeds. For example, if the array was ["devices", ["email", "mobile"]] then the devices are tried first, and if there are no devices, then both email and mobile are used (if any) to send a notification.
    • emailAddress is a literal email address to deliver the notification to
    • mobileNumber is a literal mobile number to deliver the notification to
    • deviceId is a literal device id to deliver the notification to

Notifications

As you can see, posting messages to streams can result in notifications being delivered as an email, text message, or a push notification to a device or browser. Here's how that transformation happens:

First, a template is loaded, named "$messageType/$deliveryType.handlebars", where $deliveryType can be email, mobile or device. The fallback is just "Streams/message/$deliveryType.handlebars".

The subject of the email comes from the Streams/types/$streamType/messages/$messageType/subject config field, with a fallback to Streams/types/$streamType/messages/*/subject and Streams/types/*/messages/$messageType/subject. It is also used as the title of the push notification, if any.

Notifications can be delivered to many destinations:

  • email addresses via Users.Email.sendMessage() method.
  • mobile numbers via Users.Mobile.sendMessage() method.
  • Native iOS apps via Users.Device.Ios.prototype.pushNotification method.
  • Native Android apps via Users.Device.Android.prototype.pushNotification method.
  • Chrome and Firefox via Users.Device.Web.prototype.pushNotification method doing Web Push.
  • Safari for Mac via Users.Device.Safari.prototype.pushNotification method using Safari's non-standard Web Push

The native apps can include your apps made with Cordova. To work with notifications, all you have to do is call the methods of Users.Device on the client side:

  • subscribe(callback) requests permission from the user to deliver notifications (usually displayed in a standard dialog by the browser, or operating system in native Cordova apps), and upon success, adds the device for the user automatically in the database.
  • unsubscribe(callback) removes the device, if any, from the user in the database.
  • subscribed(callback) passes a boolean variable to the callback, indicating whether the user is currently subscribed.

All this is handled automatically for you, depending on which platform and browser the web interface is currently being displayed in. You can have a button, for example, which reflects the state of subscribed(), and then can be used to subscribe() and unsubscribe from notifications.

User Experience

Subscriptions and notifications are a standard mechanism across all Qbix apps, and work with the rest of the system, including contacts and labels, streams and messages. Users can also have a unified experience throughout Qbix apps, including standard dialogs to manage subscriptions, which you can bring up using Streams.Dialogs.subscription().

Currently, the app delivering the notification has to have the user's email address, phone number or device ids. Later, we will also support notifications between communities, so that apps will be able to ask other apps to deliver notifications on their behalf. But you don't have to worry about that. Just post messages to streams. And when you are designing new types of streams, you add some config fields and templates in the right places, and things will "just work" (TM).