Push Notification Service deprecated

Introduction

Starting with v7.8.3 the Open-Xchange Middleware implemented a generic Push Notification Service that supports delivering arbitrary user-associated push notification messages to multiple clients in a transport-agnostic way.

Although designed to fit a general purpose approach, at first routing "new mail" notification messages via Web Sockets to the App Suite UI is the primary focus of the current implemenation.

For a comprehensive guide to setup up mail push, please see here

Configuration

  1. Enable the open-xchange-websockets-grizzly package in your chart's values.yaml:

    core-mw:
      packages:
        status:
          open-xchange-websockets-grizzly: enabled
    
  2. Follow the instructions from Web Sockets article

  3. Enable the open-xchange-pns-impl as well as the open-xchange-pns-transport-websockets package:

    core-mw:
      packages:
        status:
          open-xchange-websockets-grizzly: enabled
          open-xchange-pns-impl: enabled
          open-xchange-pns-transport-websockets: enabled
    
  4. Enable the com.openexchange.pns.transport.websocket.enabled property. That property is responsive to config-cascade. Hence it can be specified for user, context, context-set or server scope. For instance, create file pns.properties in Open-Xchange configuration directory (/opt/open-xchange/etc) and add line com.openexchange.pns.transport.websocket.enabled=true to globally enable Push via Web Sockets

Queueing/buffering & processing

The following settings control buffering and queueing as well as processing of push notification messages that are supposed to be transported via a concrete channel (Web Sockets, APNS, FCM, etc.)

  • com.openexchange.pns.delayDuration
    The time in milliseconds a notification is queued in buffer to possible aggregate with similar notifications that arrive during that time.
    Default is 1000 milliseconds.
  • com.openexchange.pns.timerFrequency
    The frequency/delay in milliseconds when the buffering queue will be checked for due notifications (the ones exceeding delayDuration in queue).
    Default is 500 milliseconds.
  • com.openexchange.pns.numProcessorThreads
    Specifies the number of threads that concurrently handle due notifications that were transferred from buffering queue to processing queue.
    Default is 10.
  • com.openexchange.pns.maxProcessorTasks
    Specifies the buffer size for due notifications that were transferred from buffering queue to processing queue.
    Default is 65536.

Web Sockets transport

The following setting controls whether a push notification message is allowed to be transported to associated user using Web Socket transport

Moreover, an even finer-grained decision is possible to be configured as a certain transport is checked for availability providing user, context, client and topic. Hence, it is possible to append client and topic to the property name according to following pattern: com.openexchange.pns.transport.websocket.enabled + ("." + {client})? + ("." + {topic})?

Example:

com.openexchange.pns.transport.websocket.enabled.open-xchange-appsuite.ox:mail:new=true
com.openexchange.pns.transport.websocket.enabled.open-xchange-appsuite.ox:calendar:new=false

That allows the client "open-xchange-appsuite" (App Suite UI) to receive "new mail" notifications via Web Socket, but not for "new appointment".

Web Socket and Webhook payloads for known topics

This section describes the payloads transferred via Web Socket packets and Webhook notifications for well-known topics.

Socket.IO

In general, the communication that happens via a Web Socket connection implements the Socket.IO-specified protocol. Socket.IO itself is a library that enables real-time, bidirectional and event-based communication between the browser and the server.

  • Client establishes a Web Socket connection; e.g.:
  wss://my.ox.com/socket.io/appsuite/?session=XYZ&connection=160491815377&EIO=3&transport=websocket
  • Server responds with first Socket.IO packet providing JSON-formatted meta-data about newly opened Socket.IO Web Socket connection:
  {"sid":"NMUj7A0","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000}
  • Client and server exchange periodic ping-pong packets to keep Socket.IO Web Socket connection alive

  • When a message is delivered via that connection, it looks like:

  [<topic-name>,<argument1>,...,<argumentN>]

So, basically a JSON array consisting of a topic name as first element followed by one ore more arguments (each a JSON primitive, array or object).

For further information, please check here.

Webhooks

A HTTP POST request is sent to the URI, as defined by the subscription and/or configuration: - Subscriptions are always associated with "known" webhook receiver clients, which represent the remote system where the webhook URI is hosted - Eligible client (IDs) are configured in the middleware, and are also set by the client in the subscribe request - Allowed clients can be enabled/disabled for users through the config cascade - Optionally, there is a configurable maximum for the number of subscriptions a user can create (for a certain client)

For each notification message, a custom signature response header X-OX-Signature is created as follows using a pre-shared secret, as follows: - Acquire current time millis as "timestamp" - Concatenate the version number, timestamp, and payload of the notification: v1:<timestamp>:<request_payload> - Hash and sign this string with the client-specific token / shared secret (HMAC-256) as "signature" - Construct the final header value via: t=<timestamp>,v1=<signature>

See the configuration options for Webhook clients for further details.

When a webhook endpoint is invoked, the headers of the POST request are set as configured. See following example of the relevant parts:
User-Agent: Open-Xchange Webhook Client Content-Type: application/json; charset=UTF-8 X-OX-Signature t=1694677849605, v1=de1151595c96d52940b1efd449d461d29dfec87a004548aff579c29da05c0369

For Webhooks, the JSON payload is also enriched by the fields user, context and email1 of the targeted account, so that the receiver is able to distinguish between targeted client devices properly if a shared endpoint URI is configured. Besides the payload element, the request body contains the topic (as event) and the timestamp when the message was generated, e.g.: { "event": "ox:mail:new", "payload": { [...] }, "timestamp": 1694677849605 }

Topic "ox:mail.new"

The "ox:mail:new" topic is the reserved identifier of the Open-Xchange Middleware to deliver "new mail" events to the client.

Its payload argument is a JSON object consisting of the fields:

Field name Field description
folder The identifier of the mailbox folder, in which the new mail has been received
id The identifier of the newly received mail
email The address part of the sender's E-Mail address
displayname The display name (or personal) part of the sender's E-Mail address (if any)
subject The subject line taken from newly received mail
unread The new unread (or unseen) count for the denoted mailbox folder
teaser A teaser/preview of the mail's text body
user The identifier of the targeted user as integer. Only present in Webhooks.
context The context identifier of the targeted user as integer. Only present in Webhooks.
email1 The primary email of the targeted user. Only present in Webhooks.

Web Sockets Example: ["ox:mail:new",{"folder":"default0/INBOX","id":"113","email":"jane.doe@foobar.com","displayname":"Jane Doe","subject":"Let's meet","unread":83,"teaser":"Hello"}]

Webhooks Example: {"event":"ox:mail:new","payload":{"folder":"default0/INBOX","id":"113","email":"jane.doe@foobar.com","displayname":"Jane Doe","subject":"Let's meet","unread":83,"teaser":"Hello","user":14,"context":1,"email1":"john@example.com"},"timestamp":1694677849605}

Topic "ox:calendar:updates"

The "ox:calendar:updates" topic is the reserved identifier of the Open-Xcange Middleware to indicate any kind of changes in the user's calendars to the client.

Its payload argument is a JSON object consisting of the fields:

Field name Field description
needsAction A JSON array of the identifiers of new or updated events where the user attendee's participation status equals "NEEDS-ACTION"
folders A JSON array of the identifiers of folders whose contents contain significant changes so that a refresh of the user interface is suggested.
sourceToken The optional source token string of the client that triggers the change (see chronos module of HTTP API for details).
user The identifier of the targeted user as integer. Only present in Webhooks.
context The context identifier of the targeted user as integer. Only present in Webhooks.
email1 The primary email of the targeted user. Only present in Webhooks.

Web Sockets Example:

["ox:calendar:updates",{"folders":["cal://0/216759","cal://0/30"]}]

Webhooks Example: {"event":"ox:calendar:updates","payload":{"folders":["cal://0/216759","cal://0/30"],"sourceToken":"16946778318313953327844","user":14,"context":1,"email1":"john@example.com"},"timestamp":1694677849605}

APNS transport

The following setting controls whether a push notification message is allowed to be transported to associated user using APNS transport

Moreover, an even finer-grained decision is possible to be configured as a certain transport is checked for availability providing user, context, client and topic. Hence, it is possible to append client and topic to the property name according to following pattern:
com.openexchange.pns.transport.apn.ios.enabled + ("." + {client})? + ("." + {topic})?

Example: com.openexchange.pns.transport.apn.ios.enabled.open-xchange-appsuite.ox:mail:new=true com.openexchange.pns.transport.apn.ios.enabled.open-xchange-appsuite.ox:calendar:new=false That allows the client "open-xchange-appsuite" (App Suite UI) to receive "new mail" notifications via APNS, but not for "new appointment".

Furthermore the actual APNS options need to be configured on a per client basis. APNS options are specified in the /opt/open-xchange/etc/pns-apns-options.yml file; e.g.

# Only an example
myiosclient:
    # Disabled...
    enabled: false
    keystore: /opt/open-xchange/etc/mykey-apns.p12
    password: A3JWKAKR8XB
    production: true
    topic: myBundleId

In this example, myiosclient is the identifier of the client, to which the push notifications are supposed to be routed. Below a certain client identifier, the options specify:

  • enabled
    Boolean. If set to "false" the client configuration will not be available. Default is "true".
  • keystoreId
    String. Specifies the id of the keystore (PKCS #12) containing the APNS certificate and keys for the client-associated iOS application
  • keystore
    String. Specifies the path to the local keystore file (PKCS #12) containing the APNS certificate and keys for the client-associated iOS application. This is an alternative to using keystoreId.
  • password
    String. Specifies the password to use when creating the referenced keystore containing the certificate of the iOS application.
  • production
    Boolean. Indicates which APNS service is used when sending push notifications to iOS devices. A value of "true" will use the production service, a value of "false" references to the sandbox service. Default is "true".
  • topic
    String. Specifies the topic to use for this client's push notifications. Typically the topic is the app's bundleId.

FCM transport

The following setting controls whether a push notification message is allowed to be transported to associated user using FCM transport

Moreover, an even finer-grained decision is possible to be configured as a certain transport is checked for availability providing user, context, client and topic. Hence, it is possible to append client and topic to the property name according to following pattern:
com.openexchange.pns.transport.fcm.enabled + ("." + {client})? + ("." + {topic})?

Example: com.openexchange.pns.transport.fcm.enabled.open-xchange-appsuite.ox:mail:new=true com.openexchange.pns.transport.fcm.enabled.open-xchange-appsuite.ox:calendar:new=false That allows the client "open-xchange-appsuite" (App Suite UI) to receive "new mail" notifications via FCM, but not for "new appointment".

Furthermore the actual FCM options need to be configured on a per client basis. FCM options are specified in the /opt/open-xchange/etc/pns-fcm-options.yml file; e.g.

# Only an example
mygoogleclient:
    # Disabled...
    _type: fcm
    enabled: false
    keyPath: /full/path/of/key.json

In this example, mygoogleclient is the identifier of the client, to which the push notifications are supposed to be routed. Below a certain client identifier, the options specify:

  • enabled
    Boolean. If set to "false" the client configuration will not be available. Default is "true".
  • name String. Defines the app name which should be unique across the entire installation
  • keyPath
    String. Specifies the API key of the server application.

WNS transport

The following setting controls whether a push notification message is allowed to be transported to associated user using WNS transport

Moreover, an even finer-grained decision is possible to be configured as a certain transport is checked for availability providing user, context, client and topic. Hence, it is possible to append client and topic to the property name according to following pattern:
com.openexchange.pns.transport.wns.enabled + ("." + {client})? + ("." + {topic})?

Example: com.openexchange.pns.transport.wns.enabled.open-xchange-appsuite.ox:mail:new=true com.openexchange.pns.transport.wns.enabled.open-xchange-appsuite.ox:calendar:new=false That allows the client "open-xchange-appsuite" (App Suite UI) to receive "new mail" notifications via WNS, but not for "new appointment".

Furthermore the actual WNS options need to be configured on a per client basis. WNS options are specified in the /opt/open-xchange/etc/pns-wns-options.yml file; e.g.

# Only an example
mywindowsclient:
    # Disabled...
    enabled: false
    sid: AIzaSy2535345TbVL2r4yaZ4ZVQvJdcE1vth24546
    secret: 14e435y2535345TbVL2r4yaZ4ZVQvJdcE1vth24546

In this example, mywindowsclient is the identifier of the client, to which the push notifications are supposed to be routed. Below a certain client identifier, the options specify:

  • enabled
    Boolean. If set to "false" the client configuration will not be available. Default is "true".
  • sid
    String. Specifies the SID (Package security identifier).
  • secret
    String. Specifies the client secret.