UNPKG

3.4 kBJavaScriptView Raw
1
2var inherits = require('util').inherits;
3var EventEmitter = require('events').EventEmitter;
4
5var debug = require('debug')('loopback:component:push:provider:apns');
6var apn = require('apn');
7
8function ApnsProvider(pushSettings) {
9 pushSettings = pushSettings || {};
10 var settings = pushSettings.apns || {};
11 var pushOptions = settings.pushOptions || {};
12 var feedbackOptions = settings.feedbackOptions || {};
13
14 // Populate the shared cert/key data
15 if(settings.certData) {
16 pushOptions.certData = pushOptions.certData || settings.certData;
17 feedbackOptions.certData = feedbackOptions.certData || settings.certData;
18 }
19 if(settings.keyData) {
20 pushOptions.keyData = pushOptions.keyData || settings.keyData;
21 feedbackOptions.keyData = feedbackOptions.keyData || settings.keyData;
22 }
23
24 // Check the push mode production vs development
25 if(settings.production) {
26 // Always override
27 pushOptions.gateway = 'gateway.push.apple.com';
28 feedbackOptions.gateway = 'feedback.push.apple.com';
29 if(pushOptions.port !== undefined) {
30 pushOptions.port = 2195;
31 }
32 if(feedbackOptions.port !== undefined) {
33 feedbackOptions.port = 2196;
34 }
35
36 } else {
37 // Honor the gateway settings for testing
38 pushOptions.gateway = pushOptions.gateway || 'gateway.sandbox.push.apple.com';
39 feedbackOptions.gateway = feedbackOptions.gateway || 'feedback.sandbox.push.apple.com';
40 }
41
42 // Keep the options for testing verification
43 this._pushOptions = pushOptions;
44 this._feedbackOptions = feedbackOptions;
45
46 this._setupPushConnection(pushOptions);
47 this._setupFeedback(feedbackOptions);
48}
49
50inherits(ApnsProvider, EventEmitter);
51
52exports = module.exports = ApnsProvider;
53
54ApnsProvider.prototype._setupPushConnection = function(options) {
55 var self = this;
56 if(options && !options.port){
57 delete options.port;
58 }
59 var connection = new apn.Connection(options);
60
61 function errorHandler(err) {
62 debug('Cannot initialize APNS connection. %s', err.stack);
63 self.emit('error', err);
64 }
65
66 connection.on('error', errorHandler);
67 connection.on('socketError', errorHandler);
68
69 connection.on('transmissionError', function(code, notification, recipient) {
70 var err = new Error('Cannot send APNS notification: ' + code);
71 self.emit(err, notification, recipient);
72 });
73
74 this._connection = connection;
75};
76
77ApnsProvider.prototype._setupFeedback = function(options) {
78 if (!options) {
79 debug('Feedback channel is not enabled in the application settings.');
80 return;
81 }
82
83 var self = this;
84 this._feedback = new apn.Feedback(options);
85 this._feedback.on('feedback', function (devices) {
86 debug('Devices gone:', devices);
87 self.emit('devicesGone', devices);
88 });
89};
90
91ApnsProvider.prototype.pushNotification = function(notification, deviceToken) {
92 // Note parameters are described here:
93 // http://bit.ly/apns-notification-payload
94 var note = new apn.Notification();
95 note.expiry = notification.getTimeToLiveInSecondsFromNow() || note.expiry;
96 note.badge = notification.badge;
97 note.sound = notification.sound;
98 note.alert = notification.alert;
99 note.category = notification.category;
100 note.payload = {};
101
102 Object.keys(notification).forEach(function (key) {
103 note.payload[key] = notification[key];
104 });
105
106 debug('Pushing notification to %j:', deviceToken, note);
107 this._connection.pushNotification(note, deviceToken);
108};