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