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