old_contents: 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;
  
new_contents: var apn = require('apn'),
      gcm = require('node-gcm'),
      _ = require('lodash'),
      async = require('async');
  
  
  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);
  
          /*
          * GCM has a cap of 1000 registration ids at a time. We split 1k ids.
          */
          var that = this;
          async.whilst(
              function () {
                  return (regIds = androidDeviceTokens.splice(0, 1000)).length;
              },
              function (callback) {
                  that.gcmSender.send(gcmMessage, regIds, 4, function (err, result) {
                      console.log('GCM', err, result);
                      callback(err);
                  });
              },
              function (err) {}
          );
      }
  };
  
  module.exports = PushService;
  
subject: Add 1k device token cap to GCM messages