Push notifications

Last modified by François Grisez on 2023/12/19 17:44

Overview

The PushNotification module allows Flexisip to wake up a liblinphone-basd application when a chat message or call invite cannot be delivered because the application is unavailable. This feature has become crucial since mobile OSs make the application hibernate in order to save power.

Flexisip supports native push systems for Android and iOS, but can also delegate the work of sending these requests to a tier service using HTTP GET API.

Enable Push Notifications

First, enable the PushNotification module.

[module::PushNotification]
enabled=true

Applications notify Flexisip of their push IDs using custom parameters in their REGISTER requests, so that Flexisip is able to send push requests to a given application if it is still registered. Thus, the expiration time of a REGISTER affects how long an application can be woken up, so you need to configure Flexisip to allow a high expiration value.

[module::Registrar]
# Allow applications to be woken up for 7 days
# after their last REGISTER.
max-expires=604800

Furthermore, by default, Flexisip immediately forgoes setting up a call session or delivering a message when the destination is not available. Thus, the application won't be able to receive the call invitation or the chat message for which it has been woken up because it has been dropped by the proxy. The fork-late setting in the module::Router section must be set to true to allow the proxy to hold call invitations and chat messages for a given time before dropping them.

[module::Router]
fork-late=true

# Make chat messages to be held for 7 days
# before dropping them. Call invitations are held for 32s
# in conformance with RFC 3261.
message-delivery-timeout=604800

Configure for each mobile platform

Apple

Generate authentication certificates

Flexisip uses TLS client certificates to authenticate itself to the Apple Push Notification Service. Thus, a client certificate must be created and signed by Apple's certification authority for each application that need to send push notifications. The following procedure will guide you to make and install a certificate to make your Flexisip instance send notifications to your application:

1. Create a Certificate Signing Request (CSR).

2. Follow this guide to make Apple's authority sign your CSR. Just follow the “Obtain a Provider Certificate from Apple” section.

3. Convert the certificate into a PKCS#12 file:

  1.   Double click the aps.cer file to open it in Keychain Access app.
  2.   Click on “My Certificates” tab and find the cert (should start with something like “Apple Push Services: <App ID>”).
    Warning: if you select the cert in “All Items” you will not be able to export it to a .p12 as required by the next step.
  3.   Right click and select “Export: <cert name>”.
  4.   Export it as “Personal Information Exchange (.p12)”.

4. At this point, you have a single .p12 file which contains your signed certificate and the associated private key. Unfortunately, Flexisip expects PEM-formated certificates, so you need to export your certificate into PKCS#12 format and then translate the certificate into PEM with OpenSSL command-line tool:

# Since OpenSSL v3.x
$ openssl pkcs12 -nodes -provider default -provider legacy -in <certificate-given-by-apple>.p12 -out <app-id>.prod.pem

# Before OpenSSL v3.x
$ openssl pkcs12 -nodes -in <certificate-given-by-apple>.p12 -out <app-id>.prod.pem

Warning: the name of the generated PEM file is imposed by Flexisip.

5. It is highly recommended to also make a VoIP certificate. Those are required when Flexisip needs to send a push notification for audio/video call invitations. To do so, you just need to repeat step 1 to 4 but selecting “VoIP Services Certificate” instead of “Apple Push Notification service SSL (Sandbox & Production)” while carrying out step 2. The name of the generated PEM file must be changed in step 4 to avoid collision with the previously made certificate:

$ openssl pkcs12 -nodes -in <certificate-given-by-apple>.p12 -out <app-id>.voip.prod.pem

6. Push all your PEM certificates to your Flexisip host server into /etc/flexisip/apn.

7. Create a symbolic link for each added certificate so Flexisip will be able to send push notifications to your in-development application:

$ cd /etc/flexisip/apn
$ ln -s <app-id>.{prod,dev}.pem
$ ln -s <app-id>.voip.{prod,dev}.pem

Configure Flexisip

To enable Apple push notifications you need to set apple=true and place the certificates you made earlier in /etc/flexisip/apn. The directory where to place Apple push certificates may be changed using apple-certificate-dir parameter.

[module::PushNotification]
apple=true

Android (Firebase)

Register your application on Firebase service

Sign in into Firebase and follow Add Firebase using the Firebase console procedure. Steps 3 and 4 may be skipped.

Flexisip configuration

API: V1

Available since Flexisip 2.3.3

Add your pairs of <Firebase project number>:<Path to service account json file>, each separated by a space character.

[module::PushNotification]
firebase=true
firebase-service-accounts=<project_number_1>:<service_account_file_1> <project_number_2>:<service_account_file_2>

Then you can eventually modify these parameters if you need it.

# Represents the time in seconds to execute the access token refresh
# operation just before the current access token expires. This parameter
# is used to control overlapping access token lifetimes.
# Default: 300
firebase-token-expiration-anticipation-time=300

# Default interval in seconds to execute the access token refresh
# operation in the event that the access token has not been successfully
# obtained.
# Default: 60
firebase-default-refresh-interval=60

API: legacy

Add your pairs of <Firebase project number>:<Firebase Cloud Messaging API (Legacy) Server Key> each separated by a space character.

[module::PushNotification]
firebase=true
firebase-projects-api-keys=<project_number_1>:<private_key_1> <project_number_2>:<private_key_2>

Testing

You may test your server-side configuration is ok by using the flexisip-pusher tool embedded in the Flexisip installation package. It allows you to manually send a notification request to the push notification server. You may invoke flexisip-pusher using the following command:

./flexisip_pusher --pn-provider <provider> --pn-param <params> --pn-prid <prid> --debug

where <provider>, <params> and <prid> indicate which push server to use and all the information required to send a push notification to a specific device, as normalized by rfc8599. A summary of the possible values is also available in our « Push notification » specification.

Testing on iOS

To send a classic « Remote » push notification:

./flexisip_pusher --pn-provider apns.dev --pn-param ABCD1234.<bundle-id> --pn-prid <token> --apple-push-type RemoteBasic --debug

To send a VoIP push notification:

./flexisip_pusher --pn-provider apns.dev --pn-param ABCD1234.<bundle-id>.voip --pn-prid <token> --apple-push-type PushKit --debug

Check the the following message to know whether the push request has been successfully sent:

1 push notification(s) sent, 1 successfully and 0 failed.

If you get the following error:

E: PNR 0x7fed1a449858 with identifier 1 failed with error 8 (Invalid token)

It probably means that you are using the wrong application id.

Note: to test the production certificate, you must generate an adhoc IPA and install it manually!

Testing on Android

Here's how to send an Android (Firebase) push notification:

API: V1

./flexisip_pusher --pn-provider fcm --pn-param <ProjectID> --pn-prid <device_token> --key <path_to_service_account_file> --debug

API: legacy

./flexisip_pusher --pn-provider fcm --pn-param <ProjectID> --pn-prid <device_token> --key <secret_key> --debug