Push Notifications
General
The Push Notifications feature is implemented via common standards and technologies. Users can decide per section or entry if they want to receive notifications on creation or updates. As an administrator, you can decide the style and the content of the notifications.
The notifications are per definition always opt-in: The user has to allow notifications in their browser.
Portrait decides between the two following notification modes:
Single Entry Notification
Will get triggered when either:
A subscribed entry has been updated
A subscribed section has been updated and only one entry was changed
Section Notification
Will get triggered when:
A subscribed section has been updated and the sum of updated and created entries is higher than 1
Requirements
This feature works with Portrait 6.5.x onwards and does not function in combination with the public mode.
Usage
To receive push notifications, users can subscribe to entries or entire sections. Each subscription is valid for the current device the user is using. In addition, the user has to allow push notifications via their browser as well as on their operating system.
Users are too often asked for permissions on the web. Visit a news website nowadays, and you will be prompted to opt-in for notifications. This leads to the habit, that users just click on “decline” without realizing what is going on. This is doomed to not work, and should be considered a bad practice by the site providers.
However, Portrait will only ask for permission to send notifications the first time, you click on subscribe. This should reduce friction, and engage in a better way.
Read more about Using Push Notifications in the user manual section.
Anatomy of a push notification
Before we dig into the configuration of push notifications, we take a look at a real world example for a notification (based on the iOS platform).
This example is based on the expense management app:
Everything marked green or red can be changed.
The app icon (marked green) and the app name “Spesen” (marked green, part of the title) - is a global setting and based on your App config: General settings
Title (“Benachrichtigung”) and body (“Kaffee kaffeemik - 15,50 (Dominik Rainer) aktualisiert”) is a setting per configuration - see below.
As you might have noticed, the word “von” (in English: “from”) is always part of the title on iOS. Firstly, that will look different on other platforms like Android or Chrome Dekstop.
Secondly, this can make up weird confusing texts, so please check this, before you ship your app.
Examples:
Spesenverwaltung - Spesen von Spesen
Neuer Eintrag von Spesen
Benachrichtigung von Spesen
To summarize: If you want to be grammatically correct, your freedom in the title is limited - shift relevant content to the body instead.
App Configuration
In the application YML file, check that you defined the basic setup of the push notifications service. Newer setups of Portrait ship already with these settings.
application:
push:
enabled: true
push_service_subject: 'mailto:yourEmail@domain.at'
urgency: normal
The following settings are possible:
Name | Type | Description |
---|---|---|
enabled | boolean |
|
push_service_subject | string | Used as the subject in the VAPID method for the push service. This must be either a “mailTo-Link” or the URI to your site. Example: |
urgency | string | Optional – default is |
application:
push:
deplay: 2000 # in ms
threadPoolSize: 1
|
|
|
---|---|---|
|
|
|
|
| The number of the threadpool used for processing the initial task for submitting a batch of notifications. |
|
| The delay in ms when the threadtask to process the notifications is launched. Should at least 2000ms in order to for customFields Permission checks to work. (lower the chance a dirty read on elasticsearch) |
VAPID Keys
In order to authenticate to the push service, Vapid Keys are used. Keys use the Elliptic Curve Diffie-Hellman format - ECDH. These are stored in the config folder and consist of a private key vapid_private_key
and a public key vapid_public_key
.
Configuration per Section
The content of the notifications is configured on section level. Thus, title and body can be customized per each section separately. Otherwise, a default configuration is used.
Example configuration:
section:
sections:
- name: expenses
group: Mein Arbeitsplatz
caption: Spesen
push:
titleSection: "{{sectionName}} - Neuigkeiten"
titleSingleItem: "{{sectionName}} - Neuigkeiten"
bodySection: "{{totalCount}} Aktualisierungen"
bodySingleItem: "{{name}} {{#eq actionType \"created\"}}erstellt{{else}}aktualisiert{{/eq}}"
The following settings are possible:
Name | Type | Description |
---|---|---|
titleSingleItem | string | Title of the notification for a single entry. Recommended - default is:
Default example: |
bodySingleItem | string | Message of the notification. Recommended - default is:
Default example: |
titleSection | string | Title of the notification for a section. Recommended - default is:
Default example: |
bodySection | string | Message of the notification for a section.
Default example: |
Field processors
As seen in the previous chapters, custom notification content relies on Field Processors. In the context of Notifications, the following parameters are supported:
Property | Single Entry / Section | Description |
---|---|---|
| / | The internal ID of the section. |
| / | The caption of the section. |
| / | The group the section is part of in the menu / sidebar of the frontend. |
| / | The total amount of updated/added elements of the subscribed section. |
| / | The amount of new entries of a subscribed section. |
| / | The amount of updated entries of a subscribed section. |
| / | Reflects the status of the action. Either Comes handy in combination with a field processor evaluator, example:
|
| / | The name of the entry. |
All fields of an entry | / | Each field/column of a single entry can be part of the push notifications - refer to the field with its Useful, if you need to build precise and short notification texts. Example The section config therefore is: You want to the following the notification text: Therefore, your field processor looks like this: |