apns2 icon indicating copy to clipboard operation
apns2 copied to clipboard

APNS Error when Sending Live Activity Notification in Node.js

Open ragul-pr opened this issue 1 year ago • 1 comments

I'm working on a Node.js application that sends live activity notifications using the apns2 library. However, I'm encountering an error when trying to send a notification. Below is the relevant code from my apns2_function.js file:

import { Host, Notification, Priority, PushType } from "apns2";
import { ApnsClient } from "apns2";
import * as fs from "fs";
import * as path from "path";
import { fileURLToPath } from "url";

export const sendLiveActivityNotification = async (deviceToken, options) => {
  try {
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);

    console.log("Sending live activity notification", {
      deviceToken,
      options,
    });

    if (!deviceToken) {
      throw new Error("Device token is required");
    }

    const {
      chargingTime = 0,
      soc = 0,
      energyDelivered = 0,
      chargingSpeed = 0,
      isEndEvent = false,
    } = options || {};

    const payload = {
      aps: {
        event: isEndEvent ? "end" : "update",
        ...(isEndEvent && {
          "dismissal-date": Math.floor(Date.now() / 1000),
        }),
        "content-state": {
          appGroupId: "group.charge_liveactivity",
          time: Number(chargingTime),
          soc: Number(soc),
          energyDelivered: Number(energyDelivered),
          chargingSpeed: Number(chargingSpeed),
        },
        timestamp: Math.floor(Date.now() / 1000),
      },
    };

    // Create the notification payload
    const notification = new Notification({
      token: deviceToken,
      pushType: PushType.liveactivity,
      topic: "topic",
      priority: Priority.immediate,
      expiration: 0,
      payload: payload,
    });

    const client = new ApnsClient({
      team: "*****",
      keyId: "*****",
      signingKey: fs.readFileSync(
        path.join(__dirname, "AuthKey_****.p8")
      ),
      defaultTopic: "topic",
      requestTimeout: 10000,
      keepAlive: true,
      host: Host.development,
    });

    console.log("Notification Payload:", JSON.stringify(payload, null, 2));

    try {
      const result = await client.send(notification);

      console.log("Live activity notification sent successfully", result);

      return {
        status: "success",
        data: result,
        timestamp: new Date().toISOString(),
      };
    } catch (sendError) {
      console.error("Notification Send Error:", {
        message: sendError.message,
        name: sendError.name,
        code: sendError.code,
        stack: sendError.stack,
      });

      if (sendError.response) {
        console.error("APNS Response Details:", {
          status: sendError.response.status,
          headers: sendError.response.headers,
          body: sendError.response.body,
        });
      }

      throw {
        status: "error",
        message: sendError.message || "Failed to send notification",
        details: sendError,
        timestamp: new Date().toISOString(),
      };
    }
  } catch (err) {
    // Catch-all error handling
    console.error("Comprehensive Notification Error", {
      message: err.message,
      name: err.name,
      code: err.code,
      stack: err.stack,
      fullError: err,
    });

    throw {
      status: "error",
      message: err.message || "Failed to send notification",
      details: err,
      timestamp: new Date().toISOString(),
    };
  }
};

When I attempt to send a notification, I receive the following error:

Notification Send Error: {
  message: 'APNS Error',
  name: 'Error',
  code: undefined,
  stack: 'Error: APNS Error\n' +
    '    at ApnsClient._handleServerResponse (file:///path/to/apns.js:84:23)\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
    '    at async sendLiveActivityNotification (file:///path/to/apns2_function.js:71:22)'
}

Additionally, I see an unhandled promise rejection warning:

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch().]

ragul-pr avatar Dec 13 '24 09:12 ragul-pr

Hey @ragul-steamA can you try installing 12.1.0-beta.2 and running this again? I added more details to the APNS error that I need to see. You didn't log error.reason which would tell us what the error from apple is. It should be logged for you now on that beta version

AndrewBarba avatar Dec 18 '24 15:12 AndrewBarba