Difference between revisions of "Setup Push notifications for iOS or Android"

From Sky Networks Wiki
Jump to navigation Jump to search
 
(11 intermediate revisions by one other user not shown)
Line 24: Line 24:
 
https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns
 
https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns
  
You can also just use the provisionator from onesignal and it will do everything for you.
+
You can also just use the provisionator from onesignal and it will do everything for you. (much easier)
  
 
https://onesignal.com/provisionator#
 
https://onesignal.com/provisionator#
Line 33: Line 33:
 
a) For google firebase you will need your Legacy server key - which can be found under your project settings, cloud messaging tab.
 
a) For google firebase you will need your Legacy server key - which can be found under your project settings, cloud messaging tab.
  
b) For Apple you will need the push certificate from their developer console.  This file should be put into he ios push certification is put into the /home/skynet/sky/bin/Certs folder
+
b) For Apple you will need the push certificate from their developer console.  This file should be put into he ios push certification is put into the /home/skynet/sky/bin/Certs/<vendor> folder, where the default vendor is sky.
 
There is a script (genpems) to convert the downloaded .p12 files into the required pem certificates.  Edit the script as necessary to create production or dev certificates.
 
There is a script (genpems) to convert the downloaded .p12 files into the required pem certificates.  Edit the script as necessary to create production or dev certificates.
 
The files that are needed for push are:  (If these are generated by by the provisionator or some other tool, you might just get one .pem file.  This same file can be copied to the key and cert.pem files)
 
The files that are needed for push are:  (If these are generated by by the provisionator or some other tool, you might just get one .pem file.  This same file can be copied to the key and cert.pem files)
Line 42: Line 42:
 
  apns-dev-key.pem
 
  apns-dev-key.pem
 
  apns-dev-cert.pem
 
  apns-dev-cert.pem
 +
or
 +
apns-voip-key.pem
 +
apns-voip-cert.pem
  
 
The configuration file is located in /home/skynet/sky/conf/autoload_configs/sofia.conf.xml
 
The configuration file is located in /home/skynet/sky/conf/autoload_configs/sofia.conf.xml
Line 52: Line 55:
 
     <!--Send push for calls where the phone is not registered (otherwise the push script needs to be put in the dialplan (in the dialplan is the recommended way)) -->
 
     <!--Send push for calls where the phone is not registered (otherwise the push script needs to be put in the dialplan (in the dialplan is the recommended way)) -->
 
     <param name="is-push-every-call" value="0"/>
 
     <param name="is-push-every-call" value="0"/>
     <!--Use the Apple dev certificate or production certificate. 0 - use production certificate and production push server 1 - use sandbox and dev certificate -->
+
     <!--Use the Apple dev certificate or production certificate. 0 - use production certificate and production push server, 1 - use sandbox and dev certificate, 2 - use voip push certificate and production push server, 3 - use voip push and sandbox server -->
 
     <param name="is-dev-cert" value="0"/>
 
     <param name="is-dev-cert" value="0"/>
 
     <!--push type. 1:notification, 2:data. Currently, we don't support mixture of notification and data. -->
 
     <!--push type. 1:notification, 2:data. Currently, we don't support mixture of notification and data. -->
Line 71: Line 74:
 
</nowiki>
 
</nowiki>
  
 +
 +
Note on sandbox vs. production on iOS - if you are debugging on iOS (in development) you will need to use the sandbox.  If your app is in production on the app store - use the production cert/site.
  
 
2. push server Usage.
 
2. push server Usage.
 
   There should be a script called pushtest to try it in the sky/bin directory
 
   There should be a script called pushtest to try it in the sky/bin directory
 
   Here is the source:
 
   Here is the source:
 +
<nowiki>
 
#!/bin/bash
 
#!/bin/bash
 
#
 
#
 
# Send a push notify to a client
 
# Send a push notify to a client
# $1 - calling number
+
# $1 - calling number (can be anything - it's not checked)
# $2 - called number
+
# $2 - called number (should include the company domain/context of the call)
 
#
 
#
 
fsc "sofia_push external2 $1 $2
 
fsc "sofia_push external2 $1 $2
 +
</nowiki>
  
 
   skydance push is an API command. It has 3 argments. The usage is:
 
   skydance push is an API command. It has 3 argments. The usage is:
Line 87: Line 94:
  
  
   2.1 The push can be used in diaplan like:
+
   2.1 The push can be used in diaplan right before the bridge command like this:
     <action application="lua" data="/home/skynet/sky/scripts/sofia_push.lua external2 1001 1002"/>
+
     <action application="lua" data="/home/skynet/sky/scripts/sofia_push.lua external2 1001@company1.sky-networks.com 1002@company1.sky-networks.com" inline="true"/>
  
  
Line 100: Line 107:
 
X-Mobile: os=ios;token="hDcyb5glkvfGoDY96Em/QQ8lZ3k+3ZpKL/ZUDQz/Cpw="  -  
 
X-Mobile: os=ios;token="hDcyb5glkvfGoDY96Em/QQ8lZ3k+3ZpKL/ZUDQz/Cpw="  -  
  
Note: In the iOS token case it is base64 encoded so you will need to pull the token from the push notify in a line like this:
+
If you are integrating this with multiple vendors the "vendor=xxxxx" tag will also needed to be appended in the X-Mobile header at the end to indicate what directory the associated certs will be found in.  If the vendor is not supplied, the system will assume the certificates are in the sky/bin/Certs/sky directory.
 +
 
 +
Note: For iOS the token is base64 encoded in the SIP X-header so you will need to pull the actual token from the push notify in a line like this:
 +
 
 +
Sending APN to Device with token:8e6adc4d55a27d2fa9da9a8ebe5451e4547b640511519ef07aae045630dea607
 +
 
 +
There are 2 tokens in use for Apple:
 +
 
 +
token - the regular “old” style token from Apple for Applle push notifications.
 +
voiptoken - the token used for Apple “Voip” push notifications.
 +
 
 +
The difference is that a “Voip” push does not require acknowledgement from the user in order to notify the user and start the app.  So it is preferred (usually) over the other type. 
 +
 
 +
Since both are supported, both can be included on the same Apple device.
 +
 
 +
For Android there is only one type push and it is supported with just the token field.
 +
 
 +
Below are the code snippets from Apple for constructing the 2 types of push notifications.
  
Sending APN to Device with token:8e6adc4d55a27d2fa9da9a8ebe5451e4547b640511519ef07aae045630dea607 
+
(void)pushRegistry:(nonnull PKPushRegistry *)registry didUpdatePushCredentials:(nonnull PKPushCredentials *)pushCredentials forType:(nonnull PKPushType)type {
 +
    // Get Device token
 +
    NSString *token = [pushCredentials.token.description stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
 +
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
 +
   
 +
    NSLog(@"voiptoken=%@",token);
 +
   
 +
    unsigned char tokenString[128];
 +
    unsigned char outString[128];
 +
    char headerString[128];
 +
   
 +
    int tokenLength=32;
 +
    size_t outSize=sizeof(outString);
 +
   
 +
    memset(tokenString,0,sizeof(tokenString));
 +
    memset(outString,0,sizeof(outString));
 +
    memset(headerString,0,sizeof(headerString));
 +
   
 +
    // Put the bytes from the deviceToken into the 'C' array tokenString
 +
   
 +
    tokenLength = (int)[pushCredentials.token length];
 +
    [pushCredentials.token getBytes:tokenString length:tokenLength];
 +
   
 +
    // Now base64 encode it to prepare it for sending in the register msg
 +
   
 +
    if (Base64EncodeData(tokenString,tokenLength, (char *)outString,&outSize,0))
 +
    {
 +
       
 +
        NSLog(@"stoken voip Len(%lu) = %s",outSize, outString);
 +
       
 +
       
 +
        // Now convert it to the header in NSString format and store it for later use during registration
 +
       
 +
        sprintf(headerString,";voiptoken=%c%s%c",34,outString,34);
 +
       
 +
        NSString *myNSToken = [NSString stringWithCString:headerString encoding:NSASCIIStringEncoding];
 +
       
 +
        // Read the original header we received when we setup a token for the Apple Push Service
 +
        NSString *myTokenHeader=[[NgnEngine sharedInstance].configurationService getStringWithKey:IDENTITY_TOKEN];
  
Note: the iOS one is base64 encoded in this example.  The decode for this is controlled in the mod_sofia setup.
+
        // Now concatenate it with myNSToken and resave.
 +
       
 +
        [[NgnEngine sharedInstance].configurationService setStringWithKey: IDENTITY_TOKEN andValue:  [NSString stringWithFormat:@"%@%@", myTokenHeader , myNSToken]];
 +
       
 +
       
 +
    }
 +
    else
 +
    {
 +
        NSLog(@"Error converting voip token to base64!");
 +
    }
 +
   
 +
}

Latest revision as of 06:47, 19 August 2020

Click Here to return to the the SkyPhone Main Screen: Back

Push notifications are used to notify the user of incoming calls and start SkyPhone when it is not running. If Skyphone is running, it will simply receive the call and start ringing.

To setup push notifications requires 2 things:

1. An updated mod_sofia.so module which you can obtain from Sky Networks.

2. mod_sofia configuration: It is configured as follows:


The SkyDANCE SkyPhone for iOS and Android is already setup to use push messaging.

However if you want to incorporate your own solutions

Click here for instructions on how to setup firebase cloud messaging on your app. https://firebase.google.com/docs/cloud-messaging


Click here for instructions on how to setup your push notification certificate for Apple. This is required for apple notifications even if you use firebase for the push instead of APN (Apple Push Notifications)

https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server

https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns

You can also just use the provisionator from onesignal and it will do everything for you. (much easier)

https://onesignal.com/provisionator#


Once it's setup you can access

a) For google firebase you will need your Legacy server key - which can be found under your project settings, cloud messaging tab.

b) For Apple you will need the push certificate from their developer console. This file should be put into he ios push certification is put into the /home/skynet/sky/bin/Certs/<vendor> folder, where the default vendor is sky. There is a script (genpems) to convert the downloaded .p12 files into the required pem certificates. Edit the script as necessary to create production or dev certificates. The files that are needed for push are: (If these are generated by by the provisionator or some other tool, you might just get one .pem file. This same file can be copied to the key and cert.pem files)

apns-dis-key.pem
apns-dis-cert.pem

or

apns-dev-key.pem
apns-dev-cert.pem

or

apns-voip-key.pem
apns-voip-cert.pem

The configuration file is located in /home/skynet/sky/conf/autoload_configs/sofia.conf.xml

 <!-- push server -->
    <-- ios skyphone has a base64 encode. This variable is used to check that.-->
    <param name="is-ios-encode" value="1"/>
    <!--If there is base64 encode, set this value. But there is no base64 encode in Skyphone. -->
    <param name="is-android-encode" value="0"/>
    <!--Send push for calls where the phone is not registered (otherwise the push script needs to be put in the dialplan (in the dialplan is the recommended way)) -->
    <param name="is-push-every-call" value="0"/>
    <!--Use the Apple dev certificate or production certificate. 0 - use production certificate and production push server, 1 - use sandbox and dev certificate, 2 - use voip push certificate and production push server, 3 - use voip push and sandbox server -->
    <param name="is-dev-cert" value="0"/>
    <!--push type. 1:notification, 2:data. Currently, we don't support mixture of notification and data. -->
    <param name="push-method" value="1"/>
    <!--IOS push use FCM or not. If not, will use APNS-->
    <param name="ios-push-use-fcm" value="0"/>
    <!--FCM push URI. Normally it would not change-->
    <param name="android-push-url" value="https://fcm.googleapis.com/fcm/send"/>
    <!--API key of the app when created on google developer console. Product settings, cloud messaging - Legacy server key-->
    <param name="android-api-key" value="AIzaSyCE5l74KKPbOyWMZ-l2raqtUaD6FY2X0Y8"/>
    <!--The log file for push notifies-->
    <param name="push-log-file" value="/home/skynet/sky/log/sky_push.log"/>
    <!--It will use the "fs_cli -x" to call the API command to check endpoint state. Set the path of the fs_cli/sky_cli-->
    <param name="fs-cli" value="/home/skynet/sky/bin/fs_cli"/>
    <!--If the destination is UNREGISTER or EXPIRED, it's the wait time before destination's phone returns REGISTER message. Otherwise, it's not used.-->
    <param name="invite-wait-time" value="10"/>
  


Note on sandbox vs. production on iOS - if you are debugging on iOS (in development) you will need to use the sandbox. If your app is in production on the app store - use the production cert/site.

2. push server Usage.

  There should be a script called pushtest to try it in the sky/bin directory
 Here is the source:

#!/bin/bash
#
# Send a push notify to a client
# $1 - calling number (can be anything - it's not checked)
# $2 - called number (should include the company domain/context of the call)
#
fsc "sofia_push external2 $1 $2

 skydance push is an API command. It has 3 argments. The usage is:
  sofia_push <profile_name> <calling_number> <called number>


  2.1 The push can be used in diaplan right before the bridge command like this:
   <action application="lua" data="/home/skynet/sky/scripts/sofia_push.lua external2 1001@company1.sky-networks.com 1002@company1.sky-networks.com" inline="true"/>


3. The push token that is used can be found in the registration message in the X-Mobile header. Registrations can be seen in the sky/log/sky_sbc.log file. Here's an example:

Android: X-Mobile: os=android;token="abcyU8K7sf8:APA91bEAX8-WwrpIWSQ-cwAzgBAba_JFHVtAGPVSfeVM1Mf5LnygH1HRfkMskFD0RmQeLcRofg3Q6mrmzmSuKlzvZzdpkO7om12I3KQUlp0r7d6PNNne2K7NFGr6W463rQTJJIoowoow"

iOS: X-Mobile: os=ios;token="hDcyb5glkvfGoDY96Em/QQ8lZ3k+3ZpKL/ZUDQz/Cpw=" -

If you are integrating this with multiple vendors the "vendor=xxxxx" tag will also needed to be appended in the X-Mobile header at the end to indicate what directory the associated certs will be found in. If the vendor is not supplied, the system will assume the certificates are in the sky/bin/Certs/sky directory.

Note: For iOS the token is base64 encoded in the SIP X-header so you will need to pull the actual token from the push notify in a line like this:

Sending APN to Device with token:8e6adc4d55a27d2fa9da9a8ebe5451e4547b640511519ef07aae045630dea607

There are 2 tokens in use for Apple:

token - the regular “old” style token from Apple for Applle push notifications. voiptoken - the token used for Apple “Voip” push notifications.

The difference is that a “Voip” push does not require acknowledgement from the user in order to notify the user and start the app. So it is preferred (usually) over the other type.

Since both are supported, both can be included on the same Apple device.

For Android there is only one type push and it is supported with just the token field.

Below are the code snippets from Apple for constructing the 2 types of push notifications.

(void)pushRegistry:(nonnull PKPushRegistry *)registry didUpdatePushCredentials:(nonnull PKPushCredentials *)pushCredentials forType:(nonnull PKPushType)type {
   // Get Device token
   NSString *token = [pushCredentials.token.description stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
   token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
   
   NSLog(@"voiptoken=%@",token);
   
   unsigned char tokenString[128];
   unsigned char outString[128];
   char headerString[128];
   
   int tokenLength=32;
   size_t outSize=sizeof(outString);
   
   memset(tokenString,0,sizeof(tokenString));
   memset(outString,0,sizeof(outString));
   memset(headerString,0,sizeof(headerString));
   
   // Put the bytes from the deviceToken into the 'C' array tokenString
   
   tokenLength = (int)[pushCredentials.token length];
   [pushCredentials.token getBytes:tokenString length:tokenLength];
   
   // Now base64 encode it to prepare it for sending in the register msg
   
   if (Base64EncodeData(tokenString,tokenLength, (char *)outString,&outSize,0))
   {
       
       NSLog(@"stoken voip Len(%lu) = %s",outSize, outString);
       
       
       // Now convert it to the header in NSString format and store it for later use during registration
       
       sprintf(headerString,";voiptoken=%c%s%c",34,outString,34);
       
       NSString *myNSToken = [NSString stringWithCString:headerString encoding:NSASCIIStringEncoding];
       
       // Read the original header we received when we setup a token for the Apple Push Service
       NSString *myTokenHeader=[[NgnEngine sharedInstance].configurationService getStringWithKey:IDENTITY_TOKEN];
       // Now concatenate it with myNSToken and resave.
       
       [[NgnEngine sharedInstance].configurationService setStringWithKey: IDENTITY_TOKEN andValue:  [NSString stringWithFormat:@"%@%@", myTokenHeader , myNSToken]];
       
       
   }
   else
   {
       NSLog(@"Error converting voip token to base64!");
   }
   

}