Sending Push Notifications from your web server

With thousands of mobile applications vying for your customers’ attention, Push Notifications are a great way to keep them engaged and returning to your application. From simple alerts to rich-content messages, Push is perfect for direct marketing campaigns, application updates, schedule reminders and productivity messages. You can design a push message to just deliver information, or to lead users to deeper interactions within your application.

Simply put, push messages will tune in your users, and at the same time help build brand awareness and loyalty, and create new revenue opportunities.

[announce]

Now let’s discuss technical details. The most popular mobile platforms are Android and iOS.

APNs (short for Apple Push Notification service) is the centerpiece of the push notifications feature. It is a robust and highly efficient service for propagating information to iOS and OS X devices. Each device establishes an accredited and encrypted IP connection with the service and receives notifications over this persistent connection. If a notification for an application arrives when that application is not running, the device alerts the user that the application has data waiting for it.

Software developers (“providers”) originate the notifications in their server software. The provider connects with APNs through a persistent and secure channel while monitoring incoming data intended for their client applications. When new data for an application arrives, the provider prepares and sends a notification through the channel to APNs, which pushes the notification to the target device

Google Cloud Messaging for Android (GCM) is a service that allows you to send data from your server to your users’ Android-powered device, and also to receive messages from devices on the same connection. The GCM service handles all aspects of message queuing and delivery to the target Android application running on the target device. GCM is completely free no matter how big your messaging needs are, and there are no quotas.

After a few hours of learning all this stuff, I wrote a PHP helper class for sending both types of push messages.

Here is the code

 

<?php

/**

 * Push messages helper

 *

 * @author Roman (RCooLeR) Derevianko <roman.derevianko@gmail.com>

 * @license http://www.opensource.org/licenses/mit-license.php MIT License

 */

class PushNotifications {

    /**

     * CONSTANTS

     */

    public static $GCM_SEND_ENDPOINT = "https://android.googleapis.com/gcm/send";

    public static $GCM_API_KEY = 'replace with yours';

    public static $PASS_PHRASE = 'replace with yours';

    /**

     * Send method

     * @params

     * $userDevices=array(

     *          array('token'=>string $token,'is_Android'=>boolean),

     *          array('token'=>string $token,'is_Android'=>boolean),

     * );

     * $data=array(); //Associative array with data to send

     * @return

     * Associative array with responses

     */

    public static function send($userDevices, $data) {

        // Set the device(s) to push the notification to.

        $devices = array();

        foreach ($userDevices as $device) {

            if ($device['is_Android'])

                $devices[] = $device->token;

        }

        if (!empty($devices))

            $android = self::sendToAndroid($devices, $data);

        else

            $android = 'No devices';

        $devices = array();

        foreach ($userDevices as $device) {

            if (!$device['is_Android'])

                $devices[] = $device->token;

        }

        if (!empty($devices))

            $iOS = self::sendToIOS($devices, $data);

        else

            $iOS = 'No devices';

        //Send notification

        return array('android' => $android, 'iOS' => $iOS);

    }

    /**

     * Send To Android Devices method

     * @params

     * $userdevices - Array with tokens of devices

     * $data=array(); //Associative array with data to send

     * @return

     * Response from GCM

     */

    private static function sendToAndroid($devices, $data) {

        //Set POST variables

        $fields = array(

            'registration_ids' => $devices,

            'data' => $data,

        );

        $headers = array(

            'Authorization: key=' . self::$GCM_API_KEY,

            'Content-Type: application/json'

        );

        //Open connection

        $ch = curl_init();

        //Set the url, number of POST vars, POST data

        curl_setopt($ch, CURLOPT_URL, self::$GCM_SEND_ENDPOINT);

        curl_setopt($ch, CURLOPT_POST, true);

        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

        //Execute post

        $result = curl_exec($ch);

        if (curl_errno($ch)) {

            print curl_error($ch);

        } else {

            curl_close($ch);

        }

        $results = json_decode($result);

        return $results;

    }

    /**

     * Send To iOS Devices method

     * @params

     * $userdevices - Array with tokens of devices

     * $data=array(); //Associative array with data to send

     * @return

     * Response from APNS

     */

    public static function sendToIOS($devices, $data) {

        $ctx = stream_context_create();

        stream_context_set_option($ctx, 'ssl', 'local_cert', 'path_to/ios.pem');

        stream_context_set_option($ctx, 'ssl', 'passphrase', self::$PASS_PHRASE);

        $fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);

        if (!$fp)

            return "Failed to connect amarnew: $err $errstr" . PHP_EOL;

        $results = array();

        //echo 'Connected to APNS' . PHP_EOL;

        //Create the payload body

        $body['aps'] = array(

            'badge' => 0,

            'alert' => $data['message'],

            'body' => $data,

            'sound' => 'default'

        );

        $payload = json_encode($body);

        foreach ($devices as $device) {

            // Build the binary notification

            $msg = chr(0) . pack('n', 32) . pack('H*', $device) . pack('n', strlen($payload)) . $payload;

            //Send it to the server

            $results[] = fwrite($fp, $msg, strlen($msg));

        }

        //      Close the connection to the server

        fclose($fp);

        if (empty($results))

            return FALSE;

        else

            return $results;

        fclose($fp);

    }

}

Additional links to read:

Apple Push Notification Service

Google Cloud Messaging for Android

By Roman Derevianko, PHP developer at Letzgro

 

 

[/testimonial]

Tags: iOS MacOS

Insights from our Consulting Department

January 22, 2019
How To Convert Traffic into Sales with Lead Conversion Strategy
October 15, 2016
How to Create the Smartest Chatbot Ever With IBM Watson Services

4 thoughts on “Sending Push Notifications from your web server

  1. Great! Thanks.

    “GCM allows us to send a notification to up to 1000 device at a time.” please suggest me how I can achieve that.
    Thanks in Advance

  2. Hi
    Thank for the code.
    I am trying to implement your class in my php page (message.php).
    In my message.php page I send by POST method a message that have to be read in my APP (Android and iOS)
    What exactly I have to write to call the class?

    include(“PushNotifications.php”);

    myMessage=$_POST[‘message’];

    $classPush= new PushNotifications();
    $classPush->data($myMessage);
    $classPush->send();

    This is incorrect ?

    Thanks

  3. Hello,

    From where I will get this 2 below variables:-

    public static $GCM_API_KEY = ‘replace with yours’;

    public static $PASS_PHRASE = ‘replace with yours’;

Leave a Reply

Your email address will not be published. Required fields are marked *