UNPKG

3.34 kBJavaScriptView Raw
1// Copyright IBM Corp. 2013,2015. All Rights Reserved.
2// Node module: loopback-component-push
3// This file is licensed under the Artistic License 2.0.
4// License text available at https://opensource.org/licenses/Artistic-2.0
5
6'use strict';
7
8var g = require('strong-globalize')();
9
10var inherits = require('util').inherits;
11var extend = require('util')._extend;
12var EventEmitter = require('events').EventEmitter;
13var gcm = require('node-gcm');
14var debug = require('debug')('loopback:component:push:provider:gcm');
15
16function GcmProvider(pushSettings) {
17 var settings = pushSettings.gcm || {};
18 this._setupPushConnection(settings);
19}
20
21inherits(GcmProvider, EventEmitter);
22
23exports = module.exports = GcmProvider;
24
25GcmProvider.prototype._setupPushConnection = function(options) {
26 debug('Using GCM Server API key %j', options.serverApiKey);
27 this._connection = new gcm.Sender(options.serverApiKey);
28};
29
30GcmProvider.prototype.pushNotification = function(notification, deviceToken) {
31 var self = this;
32
33 var registrationIds = (typeof deviceToken == 'string') ?
34 [deviceToken] : deviceToken;
35 var message = this._createMessage(notification);
36
37 debug('Sending message to %j: %j', registrationIds, message);
38 this._connection.send(message, registrationIds, 3, function(err, result) {
39 if (!err && result && result.failure) {
40 var devicesGoneRegistrationIds = [];
41 var errors = [];
42 var code;
43 result.results.forEach(function(value, index) {
44 code = value && value.error;
45 if (code === 'NotRegistered' || code === 'InvalidRegistration') {
46 debug('Device %j is no longer registered.', registrationIds[index]);
47 devicesGoneRegistrationIds.push(registrationIds[index]);
48 } else if (code) {
49 errors.push(g.f('{{GCM}} error code: %s, deviceToken: %s',
50 (code || 'Unknown'), registrationIds[index]));
51 }
52 });
53
54 if (devicesGoneRegistrationIds.length > 0) {
55 self.emit('devicesGone', devicesGoneRegistrationIds);
56 }
57
58 if (errors.length > 0) {
59 err = new Error(errors.join('\n'));
60 }
61 }
62
63 if (err) {
64 debug('Cannot send message: %s', err.stack);
65 self.emit('error', err);
66 return;
67 }
68
69 debug('GCM result: %j', result);
70 });
71};
72
73GcmProvider.prototype._createMessage = function(notification) {
74 // Message parameters are documented here:
75 // https://developers.google.com/cloud-messaging/server-ref
76 var message = new gcm.Message({
77 timeToLive: notification.getTimeToLiveInSecondsFromNow(),
78 collapseKey: notification.collapseKey,
79 delayWhileIdle: notification.delayWhileIdle,
80 });
81
82 var propNames = Object.keys(notification);
83 // GCM does not have reserved message parameters for alert or badge, adding them as data.
84 propNames.push('alert', 'badge');
85
86 propNames.forEach(function(key) {
87 if (notification[key] !== null &&
88 typeof notification[key] !== 'undefined') {
89 message.addData(key, notification[key]);
90 }
91 });
92
93 message.addNotification('title', notification.messageFrom);
94 message.addNotification('body', notification.alert);
95 ['icon', 'sound', 'badge', 'tag', 'color', 'click_action']
96 .forEach(function(prop) {
97 if (notification[prop]) {
98 message.addNotification(prop, notification[prop]);
99 }
100 });
101
102 return message;
103};