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