1*8682b075SBartosz Kaszubowskiconst fs = require('fs'); 2*8682b075SBartosz Kaszubowskiconst http2 = require('http2'); 3*8682b075SBartosz Kaszubowskiconst jwt = require('jsonwebtoken'); 4bd1b8ce2SBrent Vatne 5bd1b8ce2SBrent Vatneconst token = jwt.sign( 6bd1b8ce2SBrent Vatne { 7*8682b075SBartosz Kaszubowski iss: 'APPLE-TEAM-ID', 8bd1b8ce2SBrent Vatne iat: Math.round(new Date().getTime() / 1000), 9bd1b8ce2SBrent Vatne }, 10*8682b075SBartosz Kaszubowski fs.readFileSync('./myapp_apns_key.p8', 'utf8'), 11bd1b8ce2SBrent Vatne { 12bd1b8ce2SBrent Vatne header: { 13*8682b075SBartosz Kaszubowski alg: 'ES256', 14*8682b075SBartosz Kaszubowski kid: 'P8-KEY-ID', 15bd1b8ce2SBrent Vatne }, 16bd1b8ce2SBrent Vatne } 17bd1b8ce2SBrent Vatne); 18bd1b8ce2SBrent Vatne 19*8682b075SBartosz Kaszubowskiconst IS_PRODUCTION = false; // TODO: your check 20bd1b8ce2SBrent Vatneconst client = http2.connect( 21bd1b8ce2SBrent Vatne IS_PRODUCTION ? 'https://api.push.apple.com' : 'https://api.sandbox.push.apple.com' 22bd1b8ce2SBrent Vatne); 23bd1b8ce2SBrent Vatne 24*8682b075SBartosz Kaszubowskiconst deviceToken = 'device token grabbed cient-side'; 25bd1b8ce2SBrent Vatne 26*8682b075SBartosz Kaszubowskiconst headers = { 27*8682b075SBartosz Kaszubowski ':method': 'POST', 28*8682b075SBartosz Kaszubowski ':scheme': 'https', 29*8682b075SBartosz Kaszubowski 'apns-topic': 'YOUR-BUNDLE-IDENTIFIER', // TODO: your application bundle ID 30*8682b075SBartosz Kaszubowski ':path': '/3/device/' + deviceToken, 31bd1b8ce2SBrent Vatne authorization: `bearer ${token}`, 32bd1b8ce2SBrent Vatne}; 33bd1b8ce2SBrent Vatne 34bd1b8ce2SBrent Vatneconst request = client.request(headers); 35bd1b8ce2SBrent Vatne 36*8682b075SBartosz Kaszubowskirequest.setEncoding('utf8'); 37bd1b8ce2SBrent Vatne 38bd1b8ce2SBrent Vatnerequest.write( 39bd1b8ce2SBrent Vatne JSON.stringify({ 40bd1b8ce2SBrent Vatne aps: { 41bd1b8ce2SBrent Vatne alert: { 42bd1b8ce2SBrent Vatne title: "\uD83D\uDCE7 You've got mail!", 43*8682b075SBartosz Kaszubowski body: 'Hello world! \uD83C\uDF10', 44bd1b8ce2SBrent Vatne }, 45bd1b8ce2SBrent Vatne }, 46bd1b8ce2SBrent Vatne }) 47bd1b8ce2SBrent Vatne); 48bd1b8ce2SBrent Vatne 49*8682b075SBartosz Kaszubowskirequest.on('response', (headers, flags) => { 50bd1b8ce2SBrent Vatne for (const name in headers) { 51bd1b8ce2SBrent Vatne console.log(`${name}: ${headers[name]}`); 52bd1b8ce2SBrent Vatne } 53bd1b8ce2SBrent Vatne}); 54bd1b8ce2SBrent Vatne 55*8682b075SBartosz Kaszubowskilet data = ''; 56*8682b075SBartosz Kaszubowskirequest.on('data', chunk => { 57bd1b8ce2SBrent Vatne data += chunk; 58bd1b8ce2SBrent Vatne}); 59bd1b8ce2SBrent Vatne 60*8682b075SBartosz Kaszubowskirequest.on('end', () => { 61bd1b8ce2SBrent Vatne console.log(`\n${data}`); 62bd1b8ce2SBrent Vatne client.close(); 63bd1b8ce2SBrent Vatne}); 64bd1b8ce2SBrent Vatne 65bd1b8ce2SBrent Vatnerequest.end(); 66