1+ var Parse = require ( 'parse/node' ) . Parse ;
2+ // TODO: apn does not support the new HTTP/2 protocal. It is fine to use it in V1,
3+ // but probably we will replace it in the future.
4+ var apn = require ( 'apn' ) ;
5+
6+ /**
7+ * Create a new connection to the APN service.
8+ * @constructor
9+ * @param {Object } args Arguments to config APNS connection
10+ * @param {String } args.cert The filename of the connection certificate to load from disk, default is cert.pem
11+ * @param {String } args.key The filename of the connection key to load from disk, default is key.pem
12+ * @param {String } args.passphrase The passphrase for the connection key, if required
13+ * @param {Boolean } args.production Specifies which environment to connect to: Production (if true) or Sandbox
14+ */
15+ function APNS ( args ) {
16+ this . sender = new apn . connection ( args ) ;
17+
18+ this . sender . on ( 'connected' , function ( ) {
19+ console . log ( 'APNS Connected' ) ;
20+ } ) ;
21+
22+ this . sender . on ( 'transmissionError' , function ( errCode , notification , device ) {
23+ console . error ( 'APNS Notification caused error: ' + errCode + ' for device ' , device , notification ) ;
24+ // TODO: For error caseud by invalid deviceToken, we should mark those installations.
25+ } ) ;
26+
27+ this . sender . on ( "timeout" , function ( ) {
28+ console . log ( "APNS Connection Timeout" ) ;
29+ } ) ;
30+
31+ this . sender . on ( "disconnected" , function ( ) {
32+ console . log ( "APNS Disconnected" ) ;
33+ } ) ;
34+
35+ this . sender . on ( "socketError" , console . error ) ;
36+ }
37+
38+ /**
39+ * Send apns request.
40+ * @param {Object } data The data we need to send, the format is the same with api request body
41+ * @param {Array } deviceTokens A array of device tokens
42+ * @returns {Object } A promise which is resolved immediately
43+ */
44+ APNS . prototype . send = function ( data , deviceTokens ) {
45+ var coreData = data . data ;
46+ var expirationTime = data [ 'expiration_time' ] ;
47+ var notification = generateNotification ( coreData , expirationTime ) ;
48+ this . sender . pushNotification ( notification , deviceTokens ) ;
49+ // TODO: pushNotification will push the notification to apn's queue.
50+ // We do not handle error in V1, we just relies apn to auto retry and send the
51+ // notifications.
52+ return Parse . Promise . as ( ) ;
53+ }
54+
55+ /**
56+ * Generate the apns notification from the data we get from api request.
57+ * @param {Object } coreData The data field under api request body
58+ * @returns {Object } A apns notification
59+ */
60+ var generateNotification = function ( coreData , expirationTime ) {
61+ var notification = new apn . notification ( ) ;
62+ var payload = { } ;
63+ for ( key in coreData ) {
64+ switch ( key ) {
65+ case 'alert' :
66+ notification . setAlertText ( coreData . alert ) ;
67+ break ;
68+ case 'badge' :
69+ notification . badge = coreData . badge ;
70+ break ;
71+ case 'sound' :
72+ notification . sound = coreData . sound ;
73+ break ;
74+ case 'content-available' :
75+ notification . setNewsstandAvailable ( true ) ;
76+ var isAvailable = coreData [ 'content-available' ] === 1 ;
77+ notification . setContentAvailable ( isAvailable ) ;
78+ break ;
79+ case 'category' :
80+ notification . category = coreData . category ;
81+ break ;
82+ default :
83+ payload [ key ] = coreData [ key ] ;
84+ break ;
85+ }
86+ }
87+ notification . payload = payload ;
88+ notification . expiry = expirationTime ;
89+ return notification ;
90+ }
91+
92+ if ( typeof process !== 'undefined' && process . env . NODE_ENV === 'test' ) {
93+ APNS . generateNotification = generateNotification ;
94+ }
95+ module . exports = APNS ;
0 commit comments