@swoopshops/easy-apn
Version:
An easy, lightweight, adapter to send (APN) Apple Push Notifications.
118 lines (108 loc) • 3.6 kB
JavaScript
const {
spawn
} = require('child_process');
const fs = require('fs')
function sendPushNotification({
title,
message,
sound = 'default',
badge = 0,
certPath,
exportPassword,
appBundleId,
pushToken,
additionalInfo = '',
debuggerEnabled,
production
}) {
if(!message || !message.length) {return "Easy-APN stderr: [message] field required."}
if(!pushToken || !pushToken.length) {return "Easy-APN stderr: [pushToken] field required."}
if(!appBundleId || !appBundleId.length) {return "Easy-APN stderr: [appBundleId] field required."}
if(!certPath || !certPath.length) {return "Easy-APN stderr: [certPath] field required."}
if(!fs.existsSync(certPath)) {return "Easy-APN stderr: [certPath] invalid."}
else
{
const apnURL = production ?
'https://api.push.apple.com/3/device/' :
'https://api.sandbox.push.apple.com/3/device/';
const curlArgs = [
'curl',
'-v',
'-d',
JSON.stringify({
aps: {
alert: {
title,
body: message,
},
sound: sound || 'default',
badge,
},
"aditional-info": additionalInfo
}),
'--cert-type',
'P12',
'--cert',
`${certPath}:${exportPassword}`,
'-H',
`apns-topic: ${appBundleId}`,
'--http2',
`${apnURL}${pushToken}`,
];
return new Promise((resolve, reject) => {
const curlProcess = spawn('curl', curlArgs);
let err = ''
curlProcess.stdout.on('data', (data) => {
if (debuggerEnabled) {
console.log(`Easy-APN stdout: ${data}`);
}
if(data.toString().includes("TopicDisallowed")){
err = data
}
});
curlProcess.stderr.on('data', (data) => {
if (debuggerEnabled && data.includes('HTTP/2 200')) {
console.log('\x1b[32m ' + `Easy-APN info: ${format(data.toString())}` + ' \x1b[0m');
}
if (data.includes('HTTP/2 40')) {
if (production) {
resolve('\x1b[91m ' +
`\nEasy-APN stderr: sending for ${appBundleId}... cert + appBundleId mismatch.\n \nPlease check you are using production certs if you since this error can happen when you send dev certs to a production environment\n
You have {production : true} in your config. \n
Test by opening this page in a browser https://api.push.apple.com/3/device/
` +
' \x1b[0m');
} else {
resolve('\x1b[91m ' +
`\nEasy-APN stderr: sending for ${appBundleId}... cert + appBundleId mismatch.\n \n This error can happen when you send production certs to a dev (sandbox) environment \n
You have {production : false} or undefined in your config. (pointing to sandbox) \n
Test by opening this page in a browser https://api.sandbox.push.apple.com/3/device/
` +
' \x1b[0m');
}
}
err += `${data}`
});
curlProcess.on('close', (code) => {
if (code === 0) {
resolve(null)
} else {
if (code === 58 && fs.existsSync(certPath)) {
var error = "Easy-APN stderr: [certPath] invalid."
resolve(`Easy-APN stderr: exportPassword for ${certPath} invalid.`)
}
else {
resolve(err)
}
}
});
})}
}
function format(inputString) {
const lines = inputString.split('\n');
if (lines.length >= 2) {
return lines.slice(0, 2).join('\n');
}
return inputString;
}
module.exports = sendPushNotification;