· 4 years ago · Jun 22, 2021, 07:52 AM
1'use strict';
2
3const crypto = require('crypto');
4const request = require('request');
5
6const RateLimiter = require('limiter').RateLimiter;
7const limiter = new RateLimiter(1, 100); //10 per second
8
9const AIRSHIP_APP = {
10 BLAH: {
11 key: KEY,
12 secret: SECRET
13 }
14};
15
16const BASE_URL = 'https://go.urbanairship.com/api';
17const getAuth = (key, secret) => Buffer.from(key+':'+secret).toString('base64');
18
19const getNamedUser = async function(username, app = AIRSHIP_APP.BLAH) {
20 const id = hash(username);
21 const result = await sendRequest(app, '/named_users', { qs: {id}});
22
23 if (!result || !result.ok) {
24 console.log('UA getNamedUser result not ok for ' + username);
25 return null;
26 }
27
28 return result.named_user;
29};
30
31const pushNotification = async function(notification, app = AIRSHIP_APP.BLAH) {
32 const options = {
33 method: 'POST',
34 body: notification
35 };
36
37 let response = await sendRequest(app, '/push', options);
38
39 if (!response.ok) {
40 throw new Error(`Push to Airship returned not ok! ${JSON.stringify(response)}`);
41 }
42
43 return response;
44};
45
46const updateBadgeSilent = async function(username, badge, app = AIRSHIP_APP.BLAH) {
47 await pushNotification(app, {
48 "device_types": [
49 "android",
50 "ios"
51 ],
52 "notification": {
53 "ios": {
54 "content-available": true,
55 "badge": badge
56 },
57 "alert": ""
58 },
59 "audience": {
60 "named_user": hash(username)
61 },
62 });
63};
64
65const buildNotification = function(username, message, link = null, badge = 0, title = "Your Title", contentAvailable = true) {
66 let ios = {
67 "priority": 5
68 };
69
70 if (badge > -1) {
71 ios["badge"] = badge + 1;
72 } else {
73 ios["badge"] = 0;
74 }
75
76 if (contentAvailable) {
77 ios["content-available"] = true;
78 }
79
80 let config = {
81 "device_types": [
82 "android",
83 "ios"
84 ],
85 "notification": {
86 "android": {
87 "title": title
88 },
89 "ios": ios,
90 "alert": message
91 },
92 "audience": {
93 "named_user": hash(username)
94 },
95 };
96
97 if (link) {
98 const deepLink = {
99 "open": {
100 "content": link,
101 "type": "deep_link"
102 }
103 };
104
105 config.notification.actions = deepLink;
106 }
107
108 return config;
109};
110
111module.exports = {
112 AIRSHIP_APP,
113 getNamedUser,
114 pushNotification,
115 buildNotification,
116 updateBadgeSilent
117};
118
119const hash = function(str) {
120 return crypto.createHash('md5').update(str).digest('hex');
121};
122
123const sendRequest = function(app, endpoint, options) {
124 let defaults = {
125 method: 'GET',
126 uri: BASE_URL + endpoint,
127 json: true,
128 headers: {
129 'Authorization': 'Basic ' + getAuth(app.key, app.secret),
130 'Accept': 'application/vnd.urbanairship+json; version=3;'
131 }
132 };
133
134 const opts = Object.assign({}, defaults, options);
135
136 return new Promise((resolve,reject) => {
137 limiter.removeTokens(1, (err, remainingRequests) => {
138 request(opts, (err, res, data) => {
139 if (err) {
140 console.log(err);
141 return reject(err);
142 }
143 if (!data) {
144 return reject(new Error("Urban Airship API did not return any data"));
145 }
146
147 return resolve(data);
148 });
149 });
150 });
151};