@flink-app/apn-plugin
v0.12.1-alpha.45
Published
Flink plugin to send push notifications to APN
Readme
APN Plugin
A Flink plugin for sending push notifications to iOS devices via Apple Push Notification service (APNs) using certificate-based authentication.
Installation
npm install @flink-app/apn-pluginUsage
Add and configure the plugin in your app startup:
import { apnPlugin } from "@flink-app/apn-plugin";
import { FlinkApp } from "@flink-app/flink";
import AppContext from "./ApplicationContext";
async function start() {
await new FlinkApp<AppContext>({
name: "My app",
plugins: [
apnPlugin({
certificate: {
cert: process.env.APNS_CERT_BASE64, // Base64 encoded certificate (PEM format)
key: process.env.APNS_KEY_BASE64, // Base64 encoded private key (PEM format)
passphrase: process.env.APNS_PASSPHRASE, // Optional: key passphrase
},
production: false, // Set to true for production APNs server
topic: "com.example.app.voip", // Your app's bundle ID or VoIP topic
defaultPriority: 10, // Optional: default notification priority (1-10)
}),
],
}).start();
}Add the plugin context to your application context:
import { ApnPluginContext } from "@flink-app/apn-plugin";
import { FlinkContext } from "@flink-app/flink";
interface ApplicationContext extends FlinkContext<ApnPluginContext> {
// your context here
}
export default ApplicationContext;Configuration Options
interface ApnPluginOptions {
certificate: {
cert: string; // Base64 encoded APNs certificate (PEM format)
key: string; // Base64 encoded private key (PEM format)
passphrase?: string; // Optional: key passphrase if encrypted
};
production: boolean; // Use production APNs server (default: false)
topic: string; // Default APNs topic (typically your app's bundle ID)
defaultPriority?: number; // Default notification priority 1-10 (default: 10)
}Sending Push Notifications
From a Handler
import { Handler } from "@flink-app/flink";
import AppContext from "../ApplicationContext";
const SendNotification: Handler<AppContext, SendNotificationReq, SendNotificationRes> = async ({ ctx, req }) => {
await ctx.plugins.apn.send({
to: ["device-token-1", "device-token-2"], // Array of device tokens
alert: "Hello from APN!", // Alert text to display
payload: { // Custom data payload
messageId: "123",
action: "view",
},
topic: "com.example.app.voip", // Optional: override default topic
pushType: "alert", // Optional: "alert", "background", or "voip"
priority: 10, // Optional: override default priority
});
return {
status: 200,
data: { success: true },
};
};
export default SendNotification;Message Schema
interface ApnMessage {
to: string[]; // Array of device tokens to send to
alert?: string; // Alert text to display to user
payload: { // Custom data payload (key-value pairs)
[x: string]: string;
};
topic?: string; // Optional: override default topic
pushType?: "alert" | "background" | "voip" | "complication" | "fileprovider" | "mdm";
priority?: number; // Optional: override default priority (1-10)
}Certificate Setup
1. Generate Certificate from Apple Developer Portal
- Go to Apple Developer Portal → Certificates, Identifiers & Profiles
- Create a new APNs certificate (or VoIP Services certificate)
- Download the certificate (.cer file)
2. Convert to PEM Format
# Convert certificate
openssl x509 -in aps_certificate.cer -inform DER -out cert.pem -outform PEM
# Export private key from keychain (if not already exported)
# This step depends on how the certificate was created
# Encode to base64
cat cert.pem | base64
cat key.pem | base643. Set Environment Variables
export APNS_CERT_BASE64="<base64-encoded-cert>"
export APNS_KEY_BASE64="<base64-encoded-key>"
export APNS_PASSPHRASE="<passphrase-if-any>"Push Types
- alert: Standard push notification (default)
- background: Silent push notification
- voip: VoIP push notification
- complication: Update a watchOS complication
- fileprovider: Signal a file provider app
- mdm: Mobile device management
Priority Levels
- 10: High priority - delivered immediately (default)
- 5: Low priority - delivered based on device power considerations
Context API
The plugin exposes the following method through your application context:
ctx.plugins.apn.send(message: ApnMessage): Promise<any>Features
- ✅ Certificate-based authentication
- ✅ Batch sending to multiple devices
- ✅ Support for all push types (alert, VoIP, background, etc.)
- ✅ Automatic base64 certificate/key decoding
- ✅ Detailed logging of send results
- ✅ Production and sandbox environment support
Error Handling
The plugin logs detailed information about send successes and failures:
try {
await ctx.plugins.apn.send({
to: ["device-token"],
alert: "Test notification",
payload: { test: "data" },
});
} catch (error) {
// Handle errors
console.error("Failed to send push notification:", error);
}Requirements
- Valid APNs certificate and private key
- Device tokens from your iOS app
- Correct app bundle ID configured as topic
