var apn = require('apn'),
    gcm = require('node-gcm'),
    _ = require('lodash');


var PushService = function(data) {
    this.gcm = data.gcm;
    this.apn = data.apn;
    this.gcmSender = new gcm.Sender(this.gcm.apiKey);
    this.apnSender = new apn.Connection(this.apn);
};


/**
 * 
 * @param {Array.<{token, type}>} devices
 * @param {string} text
 * @param {(Object|string)=} opt_payload
 */
PushService.prototype.send = function(devices, text, opt_payload) {
    var groupedDevices = _.groupBy(devices, function(device) {
            return device.type;
        });

    if (!!groupedDevices.ios) {
        var apnDevices = groupedDevices.ios.map(function(device) {
                return new apn.Device(device.token);
            }),
            apnNotification = new apn.Notification();

        console.log('Apple device count: ' + apnDevices.length);

        // Send APN Notification
        apnNotification.expiry = Math.floor(Date.now() / 1000) + 3600 * 24; // Expires 1 hour from now.
        apnNotification.sound = "ping.aiff";
        apnNotification.alert = text || '';

        if (!!opt_payload)
            apnNotification.payload = opt_payload;

        // apnNotification.badge = 0;
        this.apnSender.pushNotification(apnNotification, apnDevices);
    }

    if (!!groupedDevices.android) {
        var gcmMessage = new gcm.Message();
        // Send GCM Notification
        gcmMessage.addData('title', this.gcm.messageTitle);
        gcmMessage.addData('message', text || '');

        if (!!opt_payload)
            gcmMessage.addData('payload', JSON.stringify(opt_payload));

        var androidDeviceTokens = groupedDevices.android.map(function(device) {
            return device.token;
        });

        console.log('Android device count: ' + androidDeviceTokens.length);

        this.gcmSender.send(gcmMessage, androidDeviceTokens, 4, function (err, result) {
            console.log('GCM', err, result);
        });
    }

     
};

module.exports = PushService;

@@ -75,16 +75,46 @@
 lodash')
+,%0A    async = require('async')
 ;%0A%0A%0Avar 
@@ -310,17 +310,16 @@
 %0A%0A/**%0A *
- 
 %0A * @par
@@ -1848,58 +1848,352 @@
     
-this.gcmSender.send(gcmMessage, androidDeviceToken
+/*%0A        * GCM has a cap of 1000 registration ids at a time. We split 1k ids.%0A        */%0A        var that = this;%0A        async.whilst(%0A            function () %7B%0A                return (regIds = androidDeviceTokens.splice(0, 1000)).length;%0A            %7D,%0A            function (callback) %7B%0A                that.gcmSender.send(gcmMessage, regId
 s, 4
@@ -2215,24 +2215,32 @@
 , result) %7B%0A
+        
             
@@ -2284,24 +2284,116 @@
     
-%7D);%0A    %7D%0A%0A     
+            callback(err);%0A                %7D);%0A            %7D,%0A            function (err) %7B%7D%0A        );%0A    %7D
 %0A%7D;%0A

Add 1k device token cap to GCM messages