### Create ApnsClient Instance Source: https://context7.com/andrewbarba/apns2/llms.txt Instantiate an ApnsClient for production or sandbox environments. Ensure the 'signingKey' is read from your .p8 file. The 'defaultTopic' is used if not specified per notification. ```typescript import fs from "fs" import { ApnsClient, Host } from "apns2" // Production client (default) const client = new ApnsClient({ team: "TFLP87PW54", // 10-character Apple Team ID keyId: "123ABC456", // 10-character Key ID from Apple Developer Portal signingKey: fs.readFileSync("./path/to/AuthKey_123ABC456.p8"), defaultTopic: "com.example.MyApp", requestTimeout: 5000, // ms; 0 = no timeout (default) keepAlive: true, // maintains connection pool (default: true) }) // Sandbox / development client const sandboxClient = new ApnsClient({ team: "TFLP87PW54", keyId: "123ABC456", signingKey: fs.readFileSync("./path/to/AuthKey_123ABC456.p8"), defaultTopic: "com.example.MyApp", host: Host.development, // "api.sandbox.push.apple.com" }) ``` -------------------------------- ### new ApnsClient(options) Source: https://context7.com/andrewbarba/apns2/llms.txt Instantiates an ApnsClient connected to either the production or sandbox APNS server. The client maintains a persistent HTTP/2 connection pool and handles JWT signing transparently. ```APIDOC ## new ApnsClient(options) — Create a push notification client Instantiates an `ApnsClient` connected to either the production or sandbox APNS server. The client maintains a persistent HTTP/2 connection pool (32 connections by default when `keepAlive` is enabled) and handles JWT signing transparently. The `signingKey` is the contents of the `.p8` file downloaded from Apple Developer Portal. ```typescript import fs from "fs" import { ApnsClient, Host } from "apns2" // Production client (default) const client = new ApnsClient({ team: "TFLP87PW54", // 10-character Apple Team ID keyId: "123ABC456", // 10-character Key ID from Apple Developer Portal signingKey: fs.readFileSync("./path/to/AuthKey_123ABC456.p8"), defaultTopic: "com.example.MyApp", requestTimeout: 5000, // ms; 0 = no timeout (default) keepAlive: true, // maintains connection pool (default: true) }) // Sandbox / development client const sandboxClient = new ApnsClient({ team: "TFLP87PW54", keyId: "123ABC456", signingKey: fs.readFileSync("./path/to/AuthKey_123ABC456.p8"), defaultTopic: "com.example.MyApp", host: Host.development, // "api.sandbox.push.apple.com" }) ``` ``` -------------------------------- ### Create APNS Client with Signing Key Source: https://github.com/andrewbarba/apns2/blob/main/README.md Instantiate the APNS client using your Apple developer team ID, key ID, and the content of your authentication key file. Configure default topic and optional request timeout or keep-alive settings. ```typescript import { ApnsClient } from 'apns2' const client = new ApnsClient({ team: `TFLP87PW54`, keyId: `123ABC456`, signingKey: fs.readFileSync(`${__dirname}/path/to/auth.p8`), defaultTopic: `com.tablelist.Tablelist`, requestTimeout: 0, // optional, Default: 0 (without timeout) keepAlive: true, // optional, Default: 5000 }) ``` -------------------------------- ### Connect to APNS Sandbox Environment Source: https://github.com/andrewbarba/apns2/blob/main/README.md To connect to the development (sandbox) push notification server, specify the `api.sandbox.push.apple.com` host in the client options. ```typescript const client = new ApnsClient({ host: 'api.sandbox.push.apple.com' ... }) ``` -------------------------------- ### Graceful Shutdown: client.close() and client.destroy() Source: https://context7.com/andrewbarba/apns2/llms.txt Methods for gracefully shutting down the APNS client. `client.close()` drains in-flight requests and closes connections, suitable for server graceful exits. `client.destroy()` immediately terminates all connections, useful for emergency cleanup. ```APIDOC ## `client.close()` and `client.destroy()` — Graceful shutdown `close()` gracefully drains all in-flight requests and closes the underlying HTTP/2 connection pool. `destroy()` immediately terminates all connections, optionally with an error. Both methods also clear the keep-alive ping interval. Use `close()` for clean shutdown (e.g., server graceful exit) and `destroy()` for emergency cleanup. ```typescript import { ApnsClient, Notification } from "apns2" const client = new ApnsClient({ /* ...options */ }) // Graceful shutdown — wait for in-flight requests to complete process.on("SIGTERM", async () => { console.log("Shutting down APNS client...") await client.close() console.log("APNS client closed") process.exit(0) }) // Force destroy on unhandled error process.on("uncaughtException", async (err) => { await client.destroy(err) process.exit(1) }) // Send some notifications, then close const notifications = Array.from({ length: 10 }, (_, i) => new Notification(`token_${i}`, { alert: `Message ${i}` }) ) await client.sendMany(notifications) await client.close() // clean up connection pool ``` ``` -------------------------------- ### Send Notification with Options Source: https://github.com/andrewbarba/apns2/blob/main/README.md Send a notification including additional options such as a badge count and custom data. This allows for richer notification content beyond a simple alert. ```typescript import { Notification } from 'apns2' const bn = new Notification(deviceToken, { alert: 'Hello, World', badge: 4, data: { userId: user.getUserId } }) try { await client.send(bn) } catch (err) { console.error(err.reason) } ``` -------------------------------- ### new Notification(deviceToken, options) Source: https://context7.com/andrewbarba/apns2/llms.txt Constructs an alert notification payload for a given device token. Supports string alerts, rich alert objects, and full manual control over the APS payload. ```APIDOC ## `new Notification(deviceToken, options)` — Build an alert notification Constructs a notification payload for the given device token. The `options` object maps to APNS payload keys; use `alert` for a simple string or an object with `title`, `subtitle`, and `body`. Set `aps` directly for full manual control over the payload. Default `pushType` is `"alert"` and default `priority` is `10` (immediate). ```typescript import { Notification, Priority, PushType } from "apns2" // String alert (most common) const n1 = new Notification("deviceToken123", { alert: "Your order has shipped!", badge: 1, sound: "default", }) // Rich alert object const n2 = new Notification("deviceToken456", { alert: { title: "Order Update", subtitle: "Estimated delivery: Today", body: "Your package is out for delivery." }, badge: 0, category: "ORDER_UPDATE", data: { orderId: "ord_789" }, priority: Priority.throttled, // 5 — sent at system's convenience }) // Critical alert with custom sound const n3 = new Notification("deviceToken789", { alert: "Low battery warning", sound: { critical: 1, name: "alarm.aiff", volume: 0.8 }, type: PushType.alert, }) // Full manual APS payload control const n4 = new Notification("deviceTokenABC", { aps: { alert: { "loc-key": "GAME_PLAY_REQUEST_FORMAT", "loc-args": ["Jenna", "Frank"] }, badge: 9, "content-available": 1, }, }) console.log(n2.pushType) // "alert" console.log(n2.priority) // 5 console.log(n2.buildApnsOptions()) // { // aps: { alert: { title: "Order Update", ... }, badge: 0, category: "ORDER_UPDATE" }, // orderId: "ord_789" // } ``` ``` -------------------------------- ### Send Basic Notification Source: https://github.com/andrewbarba/apns2/blob/main/README.md Send a simple notification with a basic alert message to a device token. Ensure the client is initialized and the notification object is correctly constructed. ```typescript import { Notification } from 'apns2' const bn = new Notification(deviceToken, { alert: 'Hello, World' }) try { await client.send(bn) } catch (err) { console.error(err.reason) } ``` -------------------------------- ### client.sendMany(notifications) Source: https://context7.com/andrewbarba/apns2/llms.txt Sends an array of notifications concurrently using `Promise.all`. Individual failures do not reject the returned promise; instead each failed send resolves to `{ error: ApnsError }` while successful sends resolve to the `Notification` instance. This makes it safe to fire large batches without a single bad token aborting the entire batch. ```APIDOC ## client.sendMany(notifications) — Send multiple notifications concurrently Sends an array of notifications concurrently using `Promise.all`. Individual failures do not reject the returned promise; instead each failed send resolves to `{ error: ApnsError }` while successful sends resolve to the `Notification` instance. This makes it safe to fire large batches without a single bad token aborting the entire batch. ```typescript import { ApnsClient, Notification, SilentNotification } from "apns2" const client = new ApnsClient({ /* ...options */ }) const tokens = [ "aaa111...", "bbb222...", "ccc333...", ] const notifications = tokens.map( (token) => new Notification(token, { alert: "Flash sale starts now!", badge: 1 }) ) const results = await client.sendMany(notifications) for (const result of results) { if ("error" in result) { console.error(`Send failed: ${result.error.reason} for token ${result.error.notification.deviceToken}`) } else { console.log(`Sent to: ${result.deviceToken}`) } } // Output: // Sent to: aaa111... // Sent to: bbb222... // Send failed: BadDeviceToken for token ccc333... ``` ``` -------------------------------- ### Graceful Client Shutdown with apns2 Source: https://context7.com/andrewbarba/apns2/llms.txt Implement graceful shutdown using `client.close()` to drain in-flight requests before closing connections. Use `client.destroy(err)` for immediate termination on unhandled exceptions. ```typescript import { ApnsClient, Notification } from "apns2" const client = new ApnsClient({ /* ...options */ }) // Graceful shutdown — wait for in-flight requests to complete process.on("SIGTERM", async () => { console.log("Shutting down APNS client...") await client.close() console.log("APNS client closed") process.exit(0) }) // Force destroy on unhandled error process.on("uncaughtException", async (err) => { await client.destroy(err) process.exit(1) }) // Send some notifications, then close const notifications = Array.from({ length: 10 }, (_, i) => new Notification(`token_${i}`, { alert: `Message ${i}` }) ) await client.sendMany(notifications) await client.close() // clean up connection pool ``` -------------------------------- ### client.send(notification) Source: https://context7.com/andrewbarba/apns2/llms.txt Sends one notification to APNS over HTTP/2 and returns a Promise that resolves to the notification on success, or throws an `ApnsError` on failure. The method automatically attaches the JWT authorization header, push type, topic, priority, expiration, and collapse ID based on the notification's options. ```APIDOC ## client.send(notification) — Send a single notification Sends one notification to APNS over HTTP/2 and returns a Promise that resolves to the notification on success, or throws an `ApnsError` on failure. The method automatically attaches the JWT authorization header, push type, topic, priority, expiration, and collapse ID based on the notification's options. ```typescript import { ApnsClient, Notification, Priority, PushType } from "apns2" const client = new ApnsClient({ /* ...options */ }) const deviceToken = "a1b2c3d4e5f6..." // 64-char hex device token // Simple alert const simple = new Notification(deviceToken, { alert: "Hello, World!" }) await client.send(simple) // Alert with badge, custom data, and expiration const rich = new Notification(deviceToken, { alert: { title: "New Message", subtitle: "From John", body: "Hey, are you free tonight?", }, badge: 3, sound: "default", data: { userId: "usr_123", screen: "inbox" }, expiration: new Date(Date.now() + 3600 * 1000), // expire in 1 hour collapseId: "messages-group", threadId: "conversation-42", mutableContent: true, topic: "com.example.MyApp", // override defaultTopic }) try { await client.send(rich) console.log("Notification sent successfully") } catch (err) { // err is an ApnsError console.error(`Failed: ${err.reason} (HTTP ${err.statusCode})`) console.error(`Device token: ${err.notification.deviceToken}`) } ``` ``` -------------------------------- ### new SilentNotification(deviceToken, options?) Source: https://context7.com/andrewbarba/apns2/llms.txt Creates a background/silent notification to wake the app without displaying an alert. Automatically sets necessary flags for background notifications. ```APIDOC ## `new SilentNotification(deviceToken, options?)` — Build a background/silent notification Creates a background notification that wakes the app without displaying any visible alert. Automatically sets `content-available: 1`, `push-type: background`, and `priority: 5` (throttled) as required by Apple. Optional `options` accepts `data`, `topic`, `expiration`, `collapseId`, and `threadId` — but not `alert`, `type`, `priority`, or `contentAvailable`, which are managed internally. ```typescript import { ApnsClient, SilentNotification } from "apns2" const client = new ApnsClient({ /* ...options */ }) // Basic silent notification — wake app to sync data const sn = new SilentNotification("deviceToken123") await client.send(sn) // Silent notification with a custom data payload const snWithData = new SilentNotification("deviceToken456", { data: { action: "sync", resource: "messages", since: 1700000000 }, topic: "com.example.MyApp", expiration: new Date(Date.now() + 60 * 1000), // expire in 60 seconds }) try { await client.send(snWithData) console.log("Silent notification sent") } catch (err) { console.error(err.reason) } // Verify internal flags console.log(snWithData.pushType) // "background" console.log(snWithData.priority) // 5 console.log(snWithData.buildApnsOptions()) // { aps: { "content-available": 1 }, action: "sync", resource: "messages", since: 1700000000 } ``` ``` -------------------------------- ### client.ping() — Send HTTP/2 ping frames Source: https://context7.com/andrewbarba/apns2/llms.txt Manually sends HTTP/2 PING frames to active connections to maintain keep-alive and detect dead connections. Useful for custom keep-alive strategies or verifying connectivity when `keepAlive` is disabled. ```APIDOC ## `client.ping()` — Send HTTP/2 ping frames Sends HTTP/2 PING frames to all active connections in the pool to keep them alive and detect dead connections. This is called automatically every 10 minutes when `keepAlive` is `true`. Call manually if you need to verify connectivity or implement a custom keep-alive strategy. ```typescript import { ApnsClient } from "apns2" const client = new ApnsClient({ team: "TFLP87PW54", keyId: "123ABC456", signingKey: process.env.APNS_SIGNING_KEY!, defaultTopic: "com.example.MyApp", keepAlive: false, // disable auto-ping to manage manually }) // Manual ping every 5 minutes setInterval(async () => { const results = await client.ping() const failures = results.filter((r) => r.status === "rejected") if (failures.length > 0) { console.warn(`${failures.length} ping(s) failed — connections may be stale`) } else { console.log(`All ${results.length} HTTP/2 sessions alive`) } }, 5 * 60 * 1000) ``` ``` -------------------------------- ### Manual Connection Pinging with apns2 Source: https://context7.com/andrewbarba/apns2/llms.txt Manually send HTTP/2 PING frames using `client.ping()` to maintain active connections and detect dead ones. This is useful when `keepAlive` is disabled and a custom keep-alive strategy is needed. ```typescript import { ApnsClient } from "apns2" const client = new ApnsClient({ team: "TFLP87PW54", keyId: "123ABC456", signingKey: process.env.APNS_SIGNING_KEY!, defaultTopic: "com.example.MyApp", keepAlive: false, // disable auto-ping to manage manually }) // Manual ping every 5 minutes setInterval(async () => { const results = await client.ping() const failures = results.filter((r) => r.status === "rejected") if (failures.length > 0) { console.warn(`${failures.length} ping(s) failed — connections may be stale`) } else { console.log(`All ${results.length} HTTP/2 sessions alive`) } }, 5 * 60 * 1000) ``` -------------------------------- ### Connect to APNS Production Environment Source: https://github.com/andrewbarba/apns2/blob/main/README.md By default, the APNS client connects to Apple's production push notification server. This can be explicitly set using the `host` option. ```typescript const client = new ApnsClient({ host: 'api.push.apple.com' ... }) ``` -------------------------------- ### Priority Constants Source: https://context7.com/andrewbarba/apns2/llms.txt Constants for the `apns-priority` header, controlling notification delivery urgency. `Priority.immediate` (10) for urgent delivery, `Priority.throttled` (5) for deferred delivery (required for background notifications), and `Priority.low` (1) for non-urgent content. ```APIDOC ## `Priority` — Notification delivery priority constants Numeric constants for the `apns-priority` header. `Priority.immediate` (10) requests delivery as soon as possible and is the default for alert notifications. `Priority.throttled` (5) defers delivery to save device power and is mandatory for background notifications. `Priority.low` (1) is the lowest priority for non-urgent content. ```typescript import { Notification, Priority } from "apns2" // Immediate delivery (default for alerts) const urgent = new Notification("deviceToken", { alert: "Your flight departs in 30 minutes!", priority: Priority.immediate, // 10 }) // Throttled — delivered at system convenience (required for background) const deferred = new Notification("deviceToken", { alert: "Here's your daily digest", priority: Priority.throttled, // 5 contentAvailable: true, }) // Low — very non-urgent, e.g. bulk marketing const low = new Notification("deviceToken", { alert: "Check out our new features", priority: Priority.low, // 1 }) console.log(urgent.priority) // 10 console.log(deferred.priority) // 5 console.log(low.priority) // 1 ``` ``` -------------------------------- ### Build Silent Notifications with apns2 Source: https://context7.com/andrewbarba/apns2/llms.txt Creates a background notification to wake the app without displaying an alert. Automatically sets 'content-available: 1', 'push-type: background', and 'priority: 5' (throttled). Optional data, topic, expiration, collapseId, and threadId can be provided. ```typescript import { ApnsClient, SilentNotification } from "apns2" const client = new ApnsClient({ /* ...options */ }) // Basic silent notification — wake app to sync data const sn = new SilentNotification("deviceToken123") await client.send(sn) // Silent notification with a custom data payload const snWithData = new SilentNotification("deviceToken456", { data: { action: "sync", resource: "messages", since: 1700000000 }, topic: "com.example.MyApp", expiration: new Date(Date.now() + 60 * 1000), // expire in 60 seconds }) try { await client.send(snWithData) console.log("Silent notification sent") } catch (err) { console.error(err.reason) } // Verify internal flags console.log(snWithData.pushType) // "background" console.log(snWithData.priority) // 5 console.log(snWithData.buildApnsOptions()) // { aps: { "content-available": 1 }, action: "sync", resource: "messages", since: 1700000000 } ``` -------------------------------- ### Send Single Notification Source: https://context7.com/andrewbarba/apns2/llms.txt Send a single push notification. The client automatically handles JWT, topic, and other headers. Errors are thrown as ApnsError, providing details on failure. ```typescript import { ApnsClient, Notification, Priority, PushType } from "apns2" const client = new ApnsClient({ /* ...options */ }) const deviceToken = "a1b2c3d4e5f6..." // 64-char hex device token // Simple alert const simple = new Notification(deviceToken, { alert: "Hello, World!" }) await client.send(simple) // Alert with badge, custom data, and expiration const rich = new Notification(deviceToken, { alert: { title: "New Message", subtitle: "From John", body: "Hey, are you free tonight?", }, badge: 3, sound: "default", data: { userId: "usr_123", screen: "inbox" }, expiration: new Date(Date.now() + 3600 * 1000), // expire in 1 hour collapseId: "messages-group", threadId: "conversation-42", mutableContent: true, topic: "com.example.MyApp", // override defaultTopic }) try { await client.send(rich) console.log("Notification sent successfully") } catch (err) { // err is an ApnsError console.error(`Failed: ${err.reason} (HTTP ${err.statusCode})`) console.error(`Device token: ${err.notification.deviceToken}`) } ``` -------------------------------- ### Send Multiple Notifications Concurrently Source: https://context7.com/andrewbarba/apns2/llms.txt Send an array of notifications concurrently using Promise.all. Individual failures are returned as { error: ApnsError } objects, allowing the batch to complete. ```typescript import { ApnsClient, Notification, SilentNotification } from "apns2" const client = new ApnsClient({ /* ...options */ }) const tokens = [ "aaa111...", "bbb222...", "ccc333...", ] const notifications = tokens.map( (token) => new Notification(token, { alert: "Flash sale starts now!", badge: 1 }) ) const results = await client.sendMany(notifications) for (const result of results) { if ("error" in result) { console.error(`Send failed: ${result.error.reason} for token ${result.error.notification.deviceToken}`) } else { console.log(`Sent to: ${result.deviceToken}`) } } // Output: // Sent to: aaa111... // Sent to: bbb222... // Send failed: BadDeviceToken for token ccc333... ``` -------------------------------- ### Configure Push Notification Types with PushType Constants Source: https://context7.com/andrewbarba/apns2/llms.txt Use the `PushType` constants to specify the correct `apns-push-type` header for different notification types. The correct type is mandatory for APNS to process notifications correctly across various platforms. ```typescript import { ApnsClient, Notification, PushType } from "apns2" const client = new ApnsClient({ /* ...options */ }) // Live Activity update const liveActivity = new Notification("deviceToken", { type: PushType.liveactivity, aps: { event: "update", "content-state": { score: 42 }, timestamp: Date.now() / 1000 }, topic: "com.example.MyApp.push-type.liveactivity", }) // VoIP push (requires VoIP Services certificate topic suffix) const voip = new Notification("deviceToken", { type: PushType.voip, data: { callId: "call_abc123", callerName: "Alice" }, topic: "com.example.MyApp.voip", }) // Push to Talk const ptt = new Notification("deviceToken", { type: PushType.pushtotalk, topic: "com.example.MyApp.voip-ptt", }) // Location push const location = new Notification("deviceToken", { type: PushType.location, topic: "com.example.MyApp", }) await client.send(liveActivity) // All PushType values: // PushType.alert — "alert" (default visible notification) // PushType.background — "background" (silent, no UI) // PushType.voip — "voip" // PushType.complication — "complication" // PushType.fileprovider — "fileprovider" // PushType.mdm — "mdm" // PushType.liveactivity — "liveactivity" // PushType.location — "location" // PushType.pushtotalk — "pushtotalk" ``` -------------------------------- ### Listen for APNS Errors Source: https://github.com/andrewbarba/apns2/blob/main/README.md Attach event listeners to the APNS client to handle specific errors like `badDeviceToken` or general errors. This allows for robust error management, such as removing invalid tokens from your database. ```typescript import { Errors } from 'apns2' // Listen for a specific error client.on(Errors.badDeviceToken, (err) => { // Handle accordingly... // Perhaps delete token from your database console.error(err.reason, err.statusCode, err.notification.deviceToken) }) // Listen for any error client.on(Errors.error, (err) => { console.error(err.reason, err.statusCode, err.notification.deviceToken) }) ``` -------------------------------- ### Build Alert Notifications with apns2 Source: https://context7.com/andrewbarba/apns2/llms.txt Constructs an alert notification payload for a given device token. Supports simple string alerts, rich alert objects with title/subtitle/body, and full manual control over the APS payload. Default pushType is 'alert' and priority is 10 (immediate). ```typescript import { Notification, Priority, PushType } from "apns2" // String alert (most common) const n1 = new Notification("deviceToken123", { alert: "Your order has shipped!", badge: 1, sound: "default", }) // Rich alert object const n2 = new Notification("deviceToken456", { alert: { title: "Order Update", subtitle: "Estimated delivery: Today", body: "Your package is out for delivery." }, badge: 0, category: "ORDER_UPDATE", data: { orderId: "ord_789" }, priority: Priority.throttled, // 5 — sent at system's convenience }) // Critical alert with custom sound const n3 = new Notification("deviceToken789", { alert: "Low battery warning", sound: { critical: 1, name: "alarm.aiff", volume: 0.8 }, type: PushType.alert, }) // Full manual APS payload control const n4 = new Notification("deviceTokenABC", { aps: { alert: { "loc-key": "GAME_PLAY_REQUEST_FORMAT", "loc-args": ["Jenna", "Frank"] }, badge: 9, "content-available": 1, }, }) console.log(n2.pushType) // "alert" console.log(n2.priority) // 5 console.log(n2.buildApnsOptions()) // { // aps: { alert: { title: "Order Update", ... }, badge: 0, category: "ORDER_UPDATE" }, // orderId: "ord_789" // } ``` -------------------------------- ### Send Multiple Notifications Concurrently Source: https://github.com/andrewbarba/apns2/blob/main/README.md Send an array of notifications in parallel to multiple device tokens. This is efficient for broadcasting messages to many users simultaneously. ```typescript import { Notification } from 'apns2' const notifications = [ new Notification(deviceToken1, { alert: 'Hello, World' }), new Notification(deviceToken2, { alert: 'Hello, World' }) ] try { await client.sendMany(notifications) } catch (err) { console.error(err.reason) } ``` -------------------------------- ### Notification Priorities in apns2 Source: https://context7.com/andrewbarba/apns2/llms.txt Use Priority constants to control notification delivery urgency. Priority.immediate (10) is for urgent alerts, Priority.throttled (5) defers delivery for background tasks, and Priority.low (1) is for non-urgent content. ```typescript import { Notification, Priority } from "apns2" // Immediate delivery (default for alerts) const urgent = new Notification("deviceToken", { alert: "Your flight departs in 30 minutes!", priority: Priority.immediate, // 10 }) // Throttled — delivered at system convenience (required for background) const deferred = new Notification("deviceToken", { alert: "Here's your daily digest", priority: Priority.throttled, // 5 contentAvailable: true, }) // Low — very non-urgent, e.g. bulk marketing const low = new Notification("deviceToken", { alert: "Check out our new features", priority: Priority.low, // 1 }) console.log(urgent.priority) // 10 console.log(deferred.priority) // 5 console.log(low.priority) // 1 ``` -------------------------------- ### Handle APNS Errors with EventEmitter Source: https://context7.com/andrewbarba/apns2/llms.txt Use the ApnsClient's EventEmitter to handle specific APNS errors or a general error event. This avoids wrapping send calls in try/catch blocks. Specific errors like `Errors.badDeviceToken` can be handled individually, while `Errors.error` acts as a catch-all. ```typescript import { ApnsClient, Errors, Notification } from "apns2" const client = new ApnsClient({ /* ...options */ }) // Handle a specific error — e.g., remove stale tokens from your database client.on(Errors.badDeviceToken, async (err) => { console.error(`Bad token: ${err.notification.deviceToken}`) await db.tokens.delete({ token: err.notification.deviceToken }) }) client.on(Errors.unregistered, async (err) => { // Device unregistered from APNS — clean up console.warn(`Unregistered token: ${err.notification.deviceToken} at ${err.timestamp}`) await db.tokens.delete({ token: err.notification.deviceToken }) }) client.on(Errors.tooManyRequests, (err) => { console.warn(`Rate limited for token ${err.notification.deviceToken}`) }) // Catch-all for any APNS error client.on(Errors.error, (err) => { console.error(`APNS error [${err.statusCode}]: ${err.reason}`) // err.reason — string, e.g. "BadDeviceToken" // err.statusCode — HTTP status code, e.g. 400 // err.notification.deviceToken — the target device token // err.timestamp — epoch ms from APNS response }) // Fire and forget — errors handled via event listeners const noti = new Notification("someDeviceToken", { alert: "Hello!" }) client.send(noti).catch(() => {}) // errors already handled above // All available Errors constants: // Errors.badCertificate, badCertificateEnvironment, badCollapseId, // badDeviceToken, badExpirationDate, badMessageId, badPath, badPriority, // badTopic, deviceTokenNotForTopic, duplicateHeaders, expiredProviderToken, // forbidden, idleTimeout, internalServerError, invalidProviderToken, // invalidPushType, invalidSigningKey, methodNotAllowed, missingDeviceToken, // missingProviderToken, missingTopic, payloadEmpty, payloadTooLarge, // serviceUnavailable, shutdown, tooManyProviderTokenUpdates, tooManyRequests, // topicDisallowed, unknownError, unregistered, error ``` -------------------------------- ### Send Silent Notification Source: https://github.com/andrewbarba/apns2/blob/main/README.md Send a silent notification using the `content-available` flag to wake up your app in the background without displaying an alert. This is recommended for background updates. ```typescript import { SilentNotification } from 'apns2' const sn = new SilentNotification(deviceToken) try { await client.send(sn) } catch (err) { console.error(err.reason) } ``` -------------------------------- ### Send Notification with Advanced APS Payload Source: https://github.com/andrewbarba/apns2/blob/main/README.md Utilize the base `Notification` class for complete control over the APNS payload, including custom `aps` dictionary configurations. Refer to Apple's documentation for available options. ```typescript import { Notification } from 'apns2' const notification = new Notification(deviceToken, { aps: { ... } }) try { await client.send(notification) } catch(err) { console.error(err.reason) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.