UNPKG

node-pushnotifications-http2

Version:

A cross-platform push service for node.js (Node 8.8.1+)

144 lines (131 loc) 5.32 kB
'use strict'; const gcm = require('node-gcm'); const method = 'gcm'; const sendChunk = (GCMSender, registrationTokens, message, retries) => new Promise(resolve => { GCMSender.send(message, { registrationTokens }, retries, (err, response) => { // Response: see https://developers.google.com/cloud-messaging/http-server-ref#table5 if (err) { resolve({ method, success: 0, failure: registrationTokens.length, message: registrationTokens.map(value => ({ originalRegId: value, regId: value, error: err, errorMsg: err instanceof Error ? err.message : err })) }); } else if (response && response.results !== undefined) { let regIndex = 0; resolve({ method, multicastId: response.multicast_id, success: response.success, failure: response.failure, message: response.results.map(value => { const regToken = registrationTokens[regIndex]; regIndex += 1; return { messageId: value.message_id, originalRegId: regToken, regId: value.registration_id || regToken, error: value.error ? new Error(value.error) : null, errorMsg: value.error ? value.error.message || value.error : null }; }) }); } else { resolve({ method, multicastId: response.multicast_id, success: response.success, failure: response.failure, message: registrationTokens.map(value => ({ originalRegId: value, regId: value, error: new Error('unknown'), errorMsg: 'unknown' })) }); } }); }); const sendGCM = (regIds, data, settings) => { const opts = Object.assign({}, settings.gcm); const id = opts.id; delete opts.id; const GCMSender = new gcm.Sender(id, opts); const promises = []; const notification = { title: data.title, // Android, iOS (Watch) body: data.body, // Android, iOS icon: data.icon, // Android sound: data.sound, // Android, iOS badge: data.badge, // iOS tag: data.tag, // Android color: data.color, // Android click_action: data.clickAction || data.category, // Android, iOS body_loc_key: data.locKey, // Android, iOS body_loc_args: data.locArgs, // Android, iOS title_loc_key: data.titleLocKey, // Android, iOS title_loc_args: data.titleLocArgs // Android, iOS }; let custom; if (typeof data.custom === 'string') { custom = { message: data.custom }; } else if (typeof data.custom === 'object') { custom = Object.assign({}, data.custom); } else { custom = { data: data.custom }; } custom.title = custom.title || data.title; custom.message = custom.message || data.body; custom.sound = custom.sound || data.sound; custom.icon = custom.icon || data.icon; custom.msgcnt = custom.msgcnt || data.badge; if (opts.phonegap === true && data.contentAvailable) { custom['content-available'] = 1; } const message = new gcm.Message({ // See https://developers.google.com/cloud-messaging/http-server-ref#table5 collapseKey: data.collapseKey, priority: data.priority === 'normal' ? data.priority : 'high', contentAvailable: data.contentAvailable || false, delayWhileIdle: data.delayWhileIdle || false, timeToLive: data.expiry - Math.floor(Date.now() / 1000) || data.timeToLive || 28 * 86400, restrictedPackageName: data.restrictedPackageName, dryRun: data.dryRun || false, data: opts.phonegap === true ? Object.assign(custom, notification) : custom, // See https://github.com/phonegap/phonegap-plugin-push/blob/master/docs/PAYLOAD.md#android-behaviour notification: opts.phonegap === true ? undefined : notification }); let chunk = 0; // Split in 1.000 chunks, see https://developers.google.com/cloud-messaging/http-server-ref#table1 do { const tokens = regIds.slice(chunk * 1000, (chunk + 1) * 1000); promises.push(sendChunk(GCMSender, tokens, message, data.retries || 0)); chunk += 1; } while (1000 * chunk < regIds.length); return Promise.all(promises).then(results => { const resumed = { method, multicastId: [], success: 0, failure: 0, message: [] }; results.forEach(result => { if (result.multicastId) { resumed.multicastId.push(result.multicastId); } resumed.success += result.success; resumed.failure += result.failure; resumed.message = [...resumed.message, ...result.message]; }); return resumed; }); }; module.exports = sendGCM;