你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

适用于 JavaScript 的 Azure 通知中心 SDK

Azure 通知中心提供横向扩展推送引擎,使你能够从任何后端(云或本地)向任何平台(Apple、Amazon Kindle、Firebase、百度、小米、Web、Windows 等)发送通知。 通知中心适用于企业和使用者方案。 下面是几个示例方案:

  • 以低延迟向数百万人发送突发新闻通知。
  • 向感兴趣的用户群发送基于位置的优惠券。
  • 向媒体/体育/金融/游戏应用程序的用户或组发送与事件相关的通知。
  • 将促销内容推送到应用程序,以吸引客户并向客户进行营销。
  • 通知用户企业事件,例如新消息和工作项。
  • 发送多重身份验证的代码。

关键链接:

注意:如果您来自使用该 azure-sb 软件包,请参阅 migration guide to move from azure-sb to @azure/notification-hubs

入门指南

当前支持的环境

有关更多详细信息,请参阅 我们的支持策略

安装软件包

npm install @azure/notification-hubs

先决条件

创建 Azure 通知中心资源

可以使用以下方法创建 Azure 通知中心:

  1. Azure 门户
  2. Azure CLI
  3. 肱二头肌
  4. ARM 模板

创建后,可以使用 Azure 门户或 Azure CLI 配置通知中心。

导入客户端

此 SDK for JavaScript 提供两种与 Azure 通知中心交互的方式,一种是基于类的方法,另一种是模块化设计方法。 基于类的方法在所有包中都是一致的,用于创建客户端,然后与客户端上的方法进行交互。

import { NotificationHubsClient, createAppleInstallation } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const installation = createAppleInstallation({
  installationId: "<installation-id>",
  pushChannel: "<push-channel>",
  tags: ["likes_javascript"],
});

const result = await client.createOrUpdateInstallation(installation);

模块化方法允许开发人员挑选要导入的函数,因为每个方法都是单独公开的。 此方法使用带有 ES-Modules 的子路径导出,通过直接导入公开方法。 通过单独的导出,这可以创建更好的树摇动体验和更小的捆绑包大小,开发人员可以利用这些体验。

请注意,创建客户端是通过子路径公开 "@azure/notification-hubs/api" 的,所有客户端方法都通过子路径公开 "@azure/notification-hubs/api" 。 导出的每个函数都以 作为 client 第一个参数,其余参数保持不变。

公开以下子路径:

  • @azure/notification-hubs/api - 客户端的主要 createClientContext 入口点 via 和客户端方法,例如 getInstallationsendNotification
  • @azure/notification-hubs/models - 通知中心模型和工厂方法。

上面的代码片段如下:

import { createClientContext, createOrUpdateInstallation } from "@azure/notification-hubs/api";
import { createAppleInstallation } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const installation = createAppleInstallation({
  installationId: "<installation-id>",
  pushChannel: "<push-channel>",
  tags: ["likes_javascript"],
});

const result = await createOrUpdateInstallation(context, installation);

验证客户端

与 Azure 通知中心的交互从 NotificationHubsClient 支持 共享访问签名连接字符串的 开始。 这包括以下权限级别: 侦听管理发送

监听允许客户端通过注册和安装 API 进行自我注册。 发送允许客户端使用发送 API 向设备发送通知。 最后,“管理”允许用户进行注册和安装管理,例如查询。

可以使用具有连接字符串和通知中心名称的构造函数创建新 NotificationHubsClient 客户端。

import { NotificationHubsClient } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

使用模块化方法,可以通过子路径导入"@azure/notification-hubs/api"createClientContext

import { createClientContext } from "@azure/notification-hubs/api";

const context = createClientContext("<connection string>", "<hub name>");

重要概念

初始化后 NotificationHubClient ,可以探索以下概念。

  • 通过安装和注册进行设备管理说明
  • 向设备发送通知

设备管理

设备管理是通知中心的核心概念,能够存储来自本机平台通知服务 (PNS)(如 APN 或 Firebase)的唯一标识符,以及关联的元数据(例如用于向受众发送推送通知的标记)。 这是通过两个 API 完成的,安装 API 是较新且首选的机制,以及注册。

安装 API

安装是一种较新的原生 JSON 设备管理方法,其中包含其他属性,例如可用于发送给受众的安装 ID 和用户 ID。 与现有注册 API 相比,安装 API 在以下方面具有一些优势:

  • 完全幂等的 API,因此在安装时调用 create,因此可以重试作而不必担心重复。
  • 支持 userIdinstallationId 属性,这些属性随后可用于标签表达式,例如 $InstallationId:{myInstallId}$UserId:{bob@contoso.com}
  • 模板现在是安装的一部分,而不是单独的注册,并且可以通过名称作为发送标签进行引用。
  • JSON 补丁标准支持部分更新,该标准允许添加标记和更改其他数据,而无需先查询安装。

可以通过以下方法创建 createOrUpdateInstallation 安装:

import { NotificationHubsClient, createAppleInstallation } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

// Create an installation for APNs
const installation = createAppleInstallation({
  installationId: "0d8ab095-c449-493f-9195-17e4917806c4", // Must be unique
  pushChannel: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0", // PNS specific handle
  tags: ["likes_hockey", "likes_football"],
});

const response = await client.createOrUpdateInstallation(installation);

使用模块化方法,代码如下:

import { createClientContext, createOrUpdateInstallation } from "@azure/notification-hubs/api";
import { createAppleInstallation } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

// Create an installation for APNs
const installation = createAppleInstallation({
  installationId: "0d8ab095-c449-493f-9195-17e4917806c4", // Must be unique
  pushChannel: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0", // PNS specific handle
  tags: ["likes_hockey", "likes_football"],
});

const response = await createOrUpdateInstallation(context, installation);

可以通过 JSON 补丁架构对安装进行更新,例如使用该 updateInstallation 方法添加标记和用户 ID。

import { NotificationHubsClient, JsonPatch } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const installationId = "<unique installation ID>";
const updates: JsonPatch[] = [
  { op: "add", path: "/tags", value: "likes_baseball" },
  { op: "add", path: "/userId", value: "bob@contoso.com" },
];

const installation = await client.updateInstallation(installationId, updates);

使用模块化方法,代码如下:

import { createClientContext, updateInstallation } from "@azure/notification-hubs/api";
import { JsonPatch } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const installationId = "<unique installation ID>";

const updates: JsonPatch[] = [
  { op: "add", path: "/tags", value: "likes_baseball" },
  { op: "add", path: "/userId", value: "bob@contoso.com" },
];

const installation = await updateInstallation(context, installationId, updates);

若要检索现有安装,请将该 getInstallation 方法与现有的唯一安装 ID 一起使用。

import { NotificationHubsClient } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const installationId = "<unique installation ID>";

const installation = client.getInstallation(installationId);

使用模块化方法,代码如下:

import { createClientContext, getInstallation } from "@azure/notification-hubs/api";

const context = createClientContext("<connection string>", "<hub name>");

const installationId = "<unique installation ID>";

const installation = getInstallation(context, installationId);

注册 API

注册与 PNS 相关联,就像上面的安装一样,与 PNS 中的唯一设备标识符和关联的标记相关联。 模板注册是一种创建预定义正文模板的方法,然后可以在发送时使用属性进行自定义,以填充消息。 有关模板的更多信息,请参阅 模板文档

可以通过以下两种方式之一创建安装,首先是使用 和 createOrUpdateRegistrationgetInstallationId通过该createRegistration方法从服务器获取注册 ID。

import {
  NotificationHubsClient,
  createAppleRegistrationDescription,
} from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const registration = createAppleRegistrationDescription({
  deviceToken: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0",
  tags: ["likes_hockey", "likes_football"],
});
const updatedRegistration = await client.createRegistration(registration);

使用模块化方法,代码如下:

import { createClientContext, createRegistration } from "@azure/notification-hubs/api";
import { createAppleRegistrationDescription } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const registration = createAppleRegistrationDescription({
  deviceToken: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0",
  tags: ["likes_hockey", "likes_football"],
});

const updatedRegistration = await createRegistration(context, registration);

可以通过该 updateRegistration 方法完成更新,但与安装不同,它不支持增量更新。 可以使用该 getRegistration 方法查询现有注册。

import { NotificationHubsClient } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const registrationId = "<unique Registration ID>";

const registration = await client.getRegistration(registrationId);

if (registration.tags) {
  registration.tags.push("likes_sports");
} else {
  registration.tags = ["likes_sports"];
}

const updatedRegistration = await client.updateRegistration(registration);

使用模块化方法,代码如下:

import {
  createClientContext,
  getRegistration,
  updateRegistration,
} from "@azure/notification-hubs/api";

const context = createClientContext("<connection string>", "<hub name>");

const registrationId = "<unique Registration ID>";

const registration = await getRegistration(context, registrationId);

if (registration.tags) {
  registration.tags.push("likes_sports");
} else {
  registration.tags = ["likes_sports"];
}

const updatedRegistration = await updateRegistration(context, registration);

与安装不同,可以查询注册以获取所有注册、将注册与条件匹配或按标记。 可以使用 和 listRegistrationsByChannellistRegistrationsByTag 方法查询listRegistrations注册。 所有方法都支持通过选项进行 top 限制,并支持异步分页。

import { NotificationHubsClient } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const registrations = client.listRegistrationsByTag("likes_hockey");

let page = 0;
for await (const pages of registrations.byPage()) {
  console.log(`Page number ${page++}`);
  for (const item of pages) {
    console.log(JSON.stringify(item, null, 2));
  }
}

使用模块化方法,代码如下:

import { createClientContext, listRegistrationsByTag } from "@azure/notification-hubs/api";

const context = createClientContext("<connection string>", "<hub name>");

const registrations = await listRegistrationsByTag(context, "likes_hockey");

let page = 0;
for await (const pages of registrations.byPage()) {
  console.log(`Page number ${page++}`);
  for (const item of pages) {
    console.log(JSON.stringify(item, null, 2));
  }
}

发送操作

通知中心支持直接使用唯一 PNS 提供的标识符向设备发送通知,使用标记进行受众发送,或向所有设备进行常规广播。 使用标准 SKU 及更高版本时, 计划发送 允许用户最多提前 7 天安排通知。 所有发送作都返回跟踪 ID 和关联 ID,可用于通知中心支持案例。 对于标准 SKU 及更高版本,还会返回通知 ID,该 ID 可用于通过该 getNotificationOutcomeDetails 方法获取通知遥测数据。

出于调试目的, enableTestSend 可以将选项设置为 true 从方法的 sendNotification PNS 获取即时反馈,但是在生产方案中不支持。 计划发送方法不支持此功能。

可以将原始 JSON 或 XML 字符串发送到发送或计划发送方法,或者可以使用通知生成器来帮助根据 PNS (例如 APNs、Firebase、百度、ADM 和 WNS)构造消息。 这些构建器将构建本机消息格式,因此无需猜测每个 PNS 可用的字段。

import { createAppleNotificationBody, createAppleNotification } from "@azure/notification-hubs";

const apnsBody = createAppleNotificationBody({
  alert: {
    title: "Notification Title",
    subtitle: "Notification Subtitle",
    body: "Notification body goes here",
  },
  sound: "default",
  interruptionLevel: "time-sensitive",
});

// Send the message using the modular approach
const notification = createAppleNotification({
  body: apnsBody,
});

广播发送

通知中心可用于通过该 sendBroadcastNotification 方法使用广播发送将通知发送到每个平台的所有已注册设备。

import { NotificationHubsClient, createAppleNotification } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const message = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await client.sendBroadcastNotification(message);

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Only available in Standard SKU and above
if (result.notificationId) {
  console.log(`Notification ID: ${result.notificationId}`);
}

使用模块化方法,代码如下:

import { createClientContext, sendBroadcastNotification } from "@azure/notification-hubs/api";
import { createAppleNotification } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const message = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await sendBroadcastNotification(context, message);

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Only available in Standard SKU and above
if (result.notificationId) {
  console.log(`Notification ID: ${result.notificationId}`);
}

直接发送

要直接发送设备,用户可以通过调用 sendNotification 带有参数的方法 deviceHandle ,使用平台提供的唯一标识符(例如 APNs 设备令牌)进行发送。

import { NotificationHubsClient, createAppleNotification } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const deviceHandle = "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const message = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await client.sendNotification(message, { deviceHandle });

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Only available in Standard SKU and above
if (result.notificationId) {
  console.log(`Notification ID: ${result.notificationId}`);
}

使用模块化方法,代码如下:

import { createClientContext, sendNotification } from "@azure/notification-hubs/api";
import { createAppleNotification } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const deviceHandle = "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const message = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await sendNotification(context, message, { deviceHandle });

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Only available in Standard SKU and above
if (result.notificationId) {
  console.log(`Notification ID: ${result.notificationId}`);
}

受众发送

除了定位到单个设备之外,用户还可以使用标记定位到多个设备。 这些标记可以作为标记列表提供,然后创建一个标记表达式以匹配已注册的设备,或者通过标记表达式提供,然后可以使用布尔逻辑来定位正确的受众。 有关标记和标记表达式的详细信息,请参阅 路由和标记表达式

如果您希望从标签数组创建标签表达式,则可以使用一个标签表达式生成器,该方法在 createTagExpression 顶级导入或 @azure/notification-hubs/models/tagExpressionBuilder 模块化导入中公开,该方法从标签创建“或标签表达式”。

import { createTagExpression } from "@azure/notification-hubs";

const tags = ["likes_football", "likes_hockey"];
const tagExpression = createTagExpression(tags);

console.log(tagExpression);

可以使用以下代码发送标记表达式消息:

import { NotificationHubsClient, createAppleNotification } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const tagExpression = "likes_hockey && likes_football";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const notification = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await client.sendNotification(notification, { tagExpression });

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Only available in Standard SKU and above
if (result.notificationId) {
  console.log(`Notification ID: ${result.notificationId}`);
}

使用模块化方法,代码如下:

import { createClientContext, sendNotification } from "@azure/notification-hubs/api";
import { createAppleNotification } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const tagExpression = "likes_hockey && likes_football";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const notification = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await sendNotification(context, notification, { tagExpression });

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Only available in Standard SKU and above
if (result.notificationId) {
  console.log(`Notification ID: ${result.notificationId}`);
}

定时发送

使用标准 SKU 命名空间及更高版本最多可以提前 7 天安排推送通知,使用该方法发送 scheduleNotification 到带有标记的设备或使用 scheduleBroadcastNotification的常规广播。 这将返回一个通知 ID,然后可以在必要时通过该方法取消 cancelScheduledNotification 该通知 ID。

import { NotificationHubsClient, createAppleNotification } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const tagExpression = "likes_hockey && likes_football";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

// Schedule 8 hours from now
const scheduledTime = new Date(Date.now() + 8 * 60 * 60 * 1000);

const message = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await client.scheduleNotification(scheduledTime, message, { tagExpression });

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Can be used to cancel via the cancelScheduledSend method
console.log(`Notification ID: ${result.notificationId}`);

使用模块化方法,代码如下:

import { createClientContext, scheduleNotification } from "@azure/notification-hubs/api";
import { createAppleNotification } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const tagExpression = "likes_hockey && likes_football";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

// Schedule 8 hours from now
const scheduledTime = new Date(Date.now() + 8 * 60 * 60 * 1000);

const message = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await scheduleNotification(context, scheduledTime, message, { tagExpression });

console.log(`Tracking ID: ${result.trackingId}`);
console.log(`Correlation ID: ${result.correlationId}`);

// Can be used to cancel via the cancelScheduledSend method
console.log(`Notification ID: ${result.notificationId}`);

Troubleshooting

React Native 支持

React Native 目前不支持 Azure 通知中心 SDK 使用的 [URLSearchParams]。 为了在 React Native 中使用 SDK,您需要在使用 SDK 之前安装 url-search-params-polyfill 包并导入它。

我们还需要为 API 和异步迭代器 API 提供 TextEncoder polyfill。 有关更多详细信息,请参阅我们的 React Native 示例与 Expo

诊断已删除的通知

Azure 通知中心在诊断 Azure 通知中心中删除的通知指南中提供了解决已删除通知问题的完整指南。

和方法支持sendNotificationsendBroadcastNotification测试发送,并带有以下enableTestSend选项:

import { NotificationHubsClient, createAppleNotification } from "@azure/notification-hubs";

const client = new NotificationHubsClient("<connection string>", "<hub name>");

const tagExpression = "likes_hockey && likes_football";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const notification = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await client.sendNotification(notification, {
  tagExpression,
  enableTestSend: true,
});
import { createClientContext, sendNotification } from "@azure/notification-hubs/api";
import { createAppleNotification } from "@azure/notification-hubs";

const context = createClientContext("<connection string>", "<hub name>");

const tagExpression = "likes_hockey && likes_football";
const messageBody = `{ "aps" : { "alert" : "Hello" } }`;

const notification = createAppleNotification({
  body: messageBody,
  headers: {
    "apns-priority": "10",
    "apns-push-type": "alert",
  },
});

const result = await sendNotification(context, notification, {
  tagExpression,
  enableTestSend: true,
});

伐木业

启用日志记录可能有助于发现有关故障的有用信息。 若要查看 HTTP 请求和响应的日志,请将 AZURE_LOG_LEVEL 环境变量设置为 info。 或者,可以通过在 setLogLevel中调用 @azure/logger 在运行时启用日志记录:

import { setLogLevel } from "@azure/logger";

setLogLevel("info");

有关如何启用日志的更详细说明,可以查看 @azure/记录器包文档

后续步骤

以下示例演示了与 Azure 通知中心交互的各种方式:

设备管理:

发送作:

管理运营:

Contributing

若要参与此库,请阅读 参与指南 ,详细了解如何生成和测试代码。

本模块的测试混合了实时测试和单元测试,这要求你具有 Azure 通知中心实例。 要执行测试,您需要运行:

  1. pnpm install
  2. pnpm build --filter @azure/notification-hubs...
  3. 在文件夹中 sdk\notificationhubs\notification-hubs 创建一个包含以下内容的 .env 文件: NOTIFICATIONHUBS_CONNECTION_STRING=connection string for your Notification Hubs instanceNOTIFICATION_HUB_NAME=Notification Hub name
  4. cd sdk\notificationhubs\notification-hubs
  5. npm run test

查看我们的 测试 文件夹了解更多详细信息。