# How to send a http2 request to APNs?

**URL:** <https://forum.wixstudio.com/t/how-to-send-a-http2-request-to-apns/32147>\
**Category:** Ask the community\
**Tags:** question, code\
**Created:** [March 9, 2020, 10:25pm UTC](https://forum.wixstudio.com/t/how-to-send-a-http2-request-to-apns/32147 "2020-03-09T22:25:48Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![javierantonf](https://sea1.discourse-cdn.com/wix/user_avatar/forum.wixstudio.com/javierantonf/32/14459_2.png) [@javierantonf](https://forum.wixstudio.com/u/javierantonf)\
**Post date:** [March 9, 2020, 10:25pm UTC](https://forum.wixstudio.com/t/how-to-send-a-http2-request-to-apns/32147/1 "2020-03-09T22:25:48Z")

</div>

I am assuming require(‘http2’) is involved  
Not sure how to build the rest, never touched http2 before. Is it even possible?  
In python, it looks like this:

HEADERS

- END\_STREAM

- END\_HEADERS  
:method = POST  
:scheme = https  
:path = /3/device/DEVICE\_REGISTRATION\_ID  
host = [api.development.push.apple.com](http://api.development.push.apple.com)  
authorization = bearer AUTH\_TOKEN  
apns-id = OPTIONAL\_UUID  
apns-expiration = 0  
apns-priority = 10  
apns-topic = TOPIC  
DATA
- END\_STREAM  
{ “aps” : { “alert” : “Hello” } }

---

<div class="post-metadata">

**Author:** ![javierantonf](https://sea1.discourse-cdn.com/wix/user_avatar/forum.wixstudio.com/javierantonf/32/14459_2.png) [@javierantonf](https://forum.wixstudio.com/u/javierantonf)\
**Post date:** [March 10, 2020, 1:22am UTC](https://forum.wixstudio.com/t/how-to-send-a-http2-request-to-apns/32147/2 "2020-03-10T01:22:04Z")

</div>

For anyone ineterested here is a solution I came up with. It works!  
Code comes with example get endpoint

```javascript
import jwt from 'jsonwebtoken';
import http2 from 'http2';
import { Http2Session, ClientHttp2Session } from 'http2';
export function get_testAPN(request) {
let options = {
"headers": {
"Content-Type": "application/json"
}
}; 
let note = { "aps": { "alert": "Hello" } };
return send(note, '<deviceId>').then(function (result) {
options.body = { "result": result };
return ok(options);
});
}
function getAPNAccessToken() {
var priv = "-----BEGIN PRIVATE ...your p8 file content";
return jwt.sign({}, priv, {
algorithm: "ES256",
issuer: "<Team ID>",
header: { kid: "<Key ID>" }
});
}
let session = null;
function ensureConnected() {
if (!session || session.destroyed) {
session = http2.connect("https://api.development.push.apple.com:443");
}
}
let _lastTokenTime = Date.now();
let _lastToken = getAPNAccessToken();
function getAuthToken() {
// return the same token for 3000 seconds
if (_lastTokenTime > Date.now() - 3000 * 1000) {
return _lastToken;
}
_lastTokenTime = Date.now();
_lastToken = getAPNAccessToken();
return _lastToken;
}
function send(APNNotification, deviceToken) {
return new Promise(function (resolve, reject) {
ensureConnected();
let authToken = getAuthToken();
var header = {
':method': 'POST',
':path': '/3/device/' + deviceToken,
'authorization': 'bearer ' + authToken,
'apns-topic': '<Bundle ID>'
};
return sendPostRequest(header, JSON.stringify(APNNotification), deviceToken)
.then(results => {
resolve(results);
});
});
}
function sendPostRequest(header, payload, deviceToken) {
return new Promise((resolve, reject) => {
var req = session.request(header);
req.setEncoding('utf8');
req.on('response', (headers) => {
let status = headers[http2.constants.HTTP2_HEADER_STATUS].toString();
// ...
let data = '';
req.on('data', (chunk) => {
data += chunk;
});
req.on('end', () => {
resolve({ status: status, body: data, device: deviceToken });
})
});
req.on('error', (err) => {
resolve({ error: err });
});
req.write(payload);
req.end();
});
}
function shutdown() {
this.session.destroy();
}

```
