-
Notifications
You must be signed in to change notification settings - Fork 1
API Documentation Reference
The flow of sending a notification is pretty easy:
- Decide which kind of notification you want to send;
- Decide which kind of
Connector
you want to use (token
orcertificates
), based on your will or Apple requirements for the kind of notification (refer to Know when to use push types @ Apple Developer) - Device which target you want to use (
Device
orBroadcastChannel
) - Send it
- (opt) Analyze the outcome and check receiving
This package exposes one function per PushType. Each function has a signature and not all the functions accept the same payload. The payload depends on some constraints defined in the Apple Documentation. The idea is that this package automatically abstracts the mandatory or suggested matters by Apple, by letting developers to focus on the integration of notification rather than on implementation.
AlertNotification
BackgroundNotification
ComplicationNotification
ControlsNotification
FileProviderNotification
LiveActivityNotification
LocationNotification
MDMNotification
PushToTalkNotification
VoipNotification
WidgetNotification
All the notifications can be imported from the namespace hapns/notifications/*
:
import { VoipNotification } from "hapns/notifications/VoipNotification";
Note
Typescript only
Some notifications modules have a NotificationCustomAppData
interface exposed, that can help ensuring the correctness of the
payload being sent to the notification. This is called Module Augmentation.
Example:
declare module "hapns/notifications/AlertNotification" {
export interface NotificationCustomAppData {
myCustomField: number
}
}
All the notifications objects accept some data that will have to respect this structure (changed, for readability). Some notifications objects will not accept all of them, so providing them will make them getting, therefore, ignored.
interface NotificationData<NotificationPayload extends object, AppPayload extends object, Priority extends 1 | 5 | 10 = 1 | 5 | 10> {
expiration?: number;
collapseID?: string;
priority?: Priority;
payload?: NotificationPayload;
appData?: AppPayload;
}
Field Name | Description |
---|---|
expiration |
apns-expiration header, as timestamp |
collapseID |
apns-collapse-id header |
priority |
apns-priority header. Some notifications push types constraint this to a subset of values. |
payload |
Content of the request body that will be set inside aps object, if the notification supports aps , otherwise other |
appData |
Content of the request body that will be set along with aps object, if the notification support custom application data. |
function AlertNotification(appBundleId: string, data: NotificationData): Notification<AlertNotificationBody>;
Name | Value |
---|---|
topic |
Application or Pass (Apple Wallet) BundleID |
data |
NotificationData |
Payload in data for this notification, is an object that contains the fields that applies to this kind of notification (refer to Payload key Reference). All the keys are optional.
Key | Optional |
---|---|
alert |
Yes |
badge |
Yes |
sound |
Yes |
threadId |
Yes |
category |
Yes |
mutableContent |
Yes |
targetContentId |
Yes |
interruptionLevel |
Yes |
relevanceScore |
Yes |
filterCriteria |
Yes |
Note
Typescript only
This function applies some constraints: alert
can be either an empty object ({}
), a string
or an object
.
When it is an {}
, badge
and sound
will not be allowed and an error will be returned.
Empty object is allowed in Apple Wallet notification, where a local notification is generated after the update.
Note
Typescript only
This function applies some constraints: alert
object can contain several kind of data. However, localization keys are mutually exclusive with the "steady" opposite. E.g. using title
AND title-loc-key
will return an error. Same is valid for body
(with loc-key
) and subtitle
(subtitle-loc-key
).
Example:
import { AlertNotification } from "hapns/notifications/AlertNotification";
const notification = AlertNotification("com.x.y.myapp", {
priority: 10,
payload: {
alert: {
"title-loc-key": "ALERT_TITLE",
"title-loc-args": ['Hello', 'hapns']
}
},
appData: {
myCustomData: 5
}
});
function BackgroundNotification(appBundleId: string, data: NotificationData): Notification<AlertNotificationBody>;
Name | Value |
---|---|
topic |
Application or Pass (Apple Wallet) BundleID |
data |
NotificationData |
Passing a payload
in data
is forbidden and will be ignored if provided.
This because background notifications can have exclusively the key content-available
, which is already provided by this function.
Only appData
can be provided.
priority
is ignored, as automatically and forcefully set to 5, as per Apple requirements.
Example:
import { BackgroundNotification } from "hapns/notifications/BackgroundNotification";
const notification = BackgroundNotification("com.x.y.myapp", {
appData: {
myCustomData: 5
}
});
function ComplicationNotification(appBundleId: string, data: NotificationData): Notification;
/**
* @TODO
*/
function ControlsNotification(appBundleId: string, data: NotificationData): Notification;
/**
* @TODO
*/
function FileProviderNotification(appBundleId: string, data: NotificationData): Notification;
/**
* @TODO
*/
function LiveActivityNotification(appBundleId: string, data: NotificationData): Notification;
This function accepts the appBundleId
and some data as payload. NotificationData
accepts a both a payload
and some appData
along with the classic headers parameters. Refer to Chosing the kind of notification to see the accepted fields.
payload
key is splitted by the event
key: in fact, you can specify start
, update
or end
and send different parameters. When using plain Javascript, provided parameters not belonging to the right event
, will get ignored.
/**
* @TODO
*/
function LocationNotification(appBundleId: string, data: NotificationData): Notification;
/**
* @TODO
*/
function MDMNotification(mdmUid: string, data: NotificationData): Notification;
/**
* @TODO
*/
function PushToTalkNotification(appBundleId: string, data: NotificationData): Notification;
/**
* @TODO
*/
function VoipNotification(appBundleId: string, data: NotificationData): Notification;
/**
* @TODO
*/
function WidgetNotification(appBundleId: string, data: NotificationData): Notification;
/**
* @TODO
*/
A connector is the core component that handles the network communication. This package exposes two Connectors
to support both the way supported by Apple: a TokenConnector
and a CertificateConnector
. Both are accessible through these namespace:
import { TokenConnector } from "hapns/connectors/token";
import { CertificateConnector } from "hapns/connectors/certificate";
Chose one based on your needs.
Warning
Notifications own an association of the connectors they are compatible with. If such constraint is not respected, an error will be fired while sending the notification.
Each Connector
has its own parameters. This allows developers to import only dedicated things.
The chosen connector will have to be passes to the broadcasting functions (see Managing Broadcast channels) and to the send()
(see Sending the notification) function in order to allow them to perform the HTTP requests.
export function TokenConnector(details: TokenConnectorData): ConnectorProtocol;
Where TokenConnectorData
is an object containing the following contents:
Name | Type | Description | Mandatory |
---|---|---|---|
key |
Uint8Array |
PKCS 8 file content to be read and used as the private key. | YES |
keyId |
string |
A 10-character string Key ID provided by Apple. | YES |
teamIdentifier |
string |
The team ID of the Apple Developer Account. | YES |
The token connector handles JWT token creation, caching, regeneration after 58 minutes and the HTTP request performing.
Example:
import { TokenConnector } from "hapns/connectors/token";
const connector = TokenConnector({
key: new Uint8Array(fs.readFileSync(TOKEN_KEY_PATH)),
keyId: KEY_ID,
teamIdentifier: TEAM_ID,
});
function CertificateConnector(details: CertificateConnectorData): ConnectorProtocol;
Where CertificateConnectorData
is an object containing these properties:
Name | Type | Description | Mandatory |
---|---|---|---|
cert |
Uint8Array |
Certificate file buffer to be read sent when establishing an HTTP/2 connection to APNs. When sending notifications for Apple Wallet, this should be the certificate used to sign the pass itself. | YES |
key |
Uint8Array |
The private key file buffer for the certificate. When sending notifications for Apple Wallet, this should be the private key used to sign the pass itself. | YES |
passphrase |
string |
The passphrase for the private key. If omitted and the key is encrypted, error ERR_OSSL_BAD_DECRYPT might get thrown. |
NO |
The certificate connector handles sending the HTTP Request by attaching cert
and key
to the request.
Example:
import { CertificateConnector } from "hapns/connectors/certificate";
const connector = CertificateConnector({
cert: new Uint8Array(fs.readFileSync("...")),
key: new Uint8Array(fs.readFileSync("...")),
passphrase: "123456",
});
The targets are the notification receivers. You can create a target based on the notification you want to deliver. If you are going to deliver a notification to a device, Device
will have to be used. BroadcastChannel
, as the name says, represents a channel against which LiveActivity notifications can be delivered.
They are accessible from the following namespaces:
import { Device } from "hapns/targets/device";
import { BroadcastChannel } from "hapns/targets/broadcastchannel";
export function Device(deviceToken: string): NotificationTarget;
It accepts the deviceToken
the notifications should get delivered to, as parameter.
function BroadcastChannel(channelId: string, bundleId: string): BroadcastChannel;
It accepts the details that identify a channel, so channelId
and bundleId
for your application.
Note
You will likely won't need to use BroadcastChannel
function directly: creating a broadcast channel through createBroadcastChannel
, will return one directly. readAllBroadcastChannels
will return as well an array of channels. You can use these two to deliver a notification, to delete a channel or to retrieve its details.
Sending the notification is fairly easy, if you found easy the rest of the steps. The package exports one method, where everything was discussed until now, flows together: send()
. Using send with a connector, a notification, a target (so, answers the questions: "How", "what" and "who to?"), you'll be able to deliver a notification to clients.
function send(connector: ConnectorProtocol, notification: Notification<object>, target: NotificationTarget, settings?: SendingOptions): Promise<DeliveryResult>;
This functions accepts a connector
, a notification
, a target
and a fourth optional SendingOptions
object, which contains the following (all optional) properties:
Name | Type | Description |
---|---|---|
useSandbox |
boolean |
Set to true to optin with the usage of sandbox (development environment) for APNs |
apnsId |
string | Provide a custom apns-id that will be returned with the response |
This function returns a Promise with the details of the notification delivery, so:
Name | Type | Description |
---|---|---|
apnsId | string |
The notification id. Right now it is not possible to provide it manually. It will be in the future. |
apnsUniqueId | string |
Development (Sandbox) environment identifier that can help checking what happened to a notification in the Push Notification Console |
You can handle the channels management by following the dedicate documentation page @ Apple Developer and the following functions.
All the functions can be exported through the following namespace:
import { createBroadcastChannel } from "hapns/channels/broadcast";
async function createBroadcastChannel(connector: ConnectorProtocol, settings: BroadcastChannelSettings): Promise<BroadcastChannel>;
Provide a connector and some settings. The settings are an object with the following properties:
Name | Type | Description | Mandatory |
---|---|---|---|
bundleId |
string |
Bundle ID associated with the channel | YES |
messageStoragePolicy |
0 | 1 (number) |
How long the message should be kept by APN | NO |
apnsRequestId |
string |
Request Id to be sent with the request | NO |
useSandbox |
boolean |
Provide this flag to go on production or use the sandbox environment |
A BroadcastChannel
target object will be returned on completion, containing the bundleId
you provided and the channelId
.
You can use the whole object as a target for notifications and with the other broadcasting methods.
async function readBroadcastChannel(connector: ConnectorProtocol, bChannel: BroadcastChannel, settings?: ChannelReadSettings): Promise<ChannelReadResponseBody>
Provide a connector and a BroadcastChannel
in order to retrieve channel settings.
The settings object in the function signature, is an object contaning the following properties:
Name | Type | Description |
---|---|---|
apnsRequestId |
string |
Provide a custom apns-request-id that will be returned with the response |
useSandbox |
boolean |
Provide this flag to go on production or use the sandbox environment |
A ChannelReadResponseBody
will be returned. It consists in the following details:
Name | Type |
---|---|
messageStoragePolicy |
number |
pushType |
string |
async function deleteBroadcastChannel(connector: ConnectorProtocol, bChannel: BroadcastChannel, settings?: ChannelDeleteSettings): Promise<{ success: true; apnsRequestId: string }> {
Provide a connector and a BroadcastChannel
in order to delete the channel.
The settings object in the function signature, is an object contaning the following properties:
Name | Type | Description |
---|---|---|
apnsRequestId |
string |
Provide a custom apns-request-id that will be returned with the response |
useSandbox |
boolean |
Provide this flag to go on production or use the sandbox environment |
The returned response will contain the fields success
(always to true
) and the apnsRequestId
, which is autogenerated by Apple.
async function readAllBroadcastChannels(connector: ConnectorProtocol, bundleId: string, settings?: ChannelReadSettings): Promise<BroadcastChannel[]> {
Provide a connector and a bundleId
in order to retrieve all the channels in an environment for that bundleId
.
The settings object in the function signature, is an object contaning the following properties:
Name | Type | Description |
---|---|---|
apnsRequestId |
string |
Provide a custom apns-request-id that will be returned with the response |
useSandbox |
boolean |
Provide this flag to go on production or use the sandbox environment |
An array of BroadcastChannel
will be returned. Use this channels list to delete channels or ship notifications to them. It's up to you!