你当前正在访问 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

先决条件

Create Azure 通知中心资源

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

  1. Azure 门户
  2. Azure CLI
  3. Bicep
  4. ARM 模板

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

导入客户端

此适用于 JavaScript 的 SDK 提供了两种与 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- main客户端的入口点,以及createClientContext客户端方法,如 getInstallationsendNotification
  • @azure/notification-hubs/models - 通知中心模型和工厂方法。

然后,上述代码片段将变为以下内容:

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

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>");

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

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

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

关键概念

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

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

设备管理

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

安装 API

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

  • 完全幂等 API,因此在安装时调用 create,因此可以重试操作,而无需担心重复。
  • userId支持 和 installationId 属性,这些属性随后可在 标记表达式(如 和 $UserId:{bob@contoso.com}$InstallationId:{myInstallId}中使用。
  • 模板现在是安装的一部分,而不是单独的注册,可以按名称引用作为要发送的标记。
  • JSON 修补程序标准支持部分更新,它允许添加标记和更改其他数据,而无需先查询安装。

可以通过 方法创建安装, createOrUpdateInstallation 如下所示:

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

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

// Create an installation for APNs
let installation = createAppleInstallation({
  installationId: uuid(), // Must be unique
  pushChannel: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0", // PNS specific handle
  tags: ["likes_hockey", "likes_football"],
});

installation = await client.createOrUpdateInstallation(installation);

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

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

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

// Create an installation for APNs
let installation = createAppleInstallation({
  installationId: uuid(), // Must be unique
  pushChannel: "00fc13adff785122b4ad28809a3420982341241421348097878e577c991de8f0", // PNS specific handle
  tags: ["likes_hockey", "likes_football"],
});

installation = 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/models";

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 中的唯一设备标识符和关联的标记。 模板注册是创建预定义正文模板的一种方式,可以在发送时使用属性进行自定义,以填充消息。 有关模板的详细信息,请参阅 模板文档

可以通过以下两种方式之一创建安装:首先,使用 getInstallationId 和 ,然后 createOrUpdateRegistration 或通过 createRegistration 方法从服务器获取注册 ID。

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

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

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

registration = await client.createRegistration(registration);

console.log(`New Registration ID: ${registration.registrationId}`);

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

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

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

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

registration = await createRegistration(context, registration);

console.log(`New Registration ID: ${registration.registrationId}`);

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

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

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

const registrationId = "<unique Registration ID>";

let registration = await client.getRegistration(registrationId);

registration.tags.push("likes_sports");

registration = 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>";

let registration = await getRegistration(context, registrationId);

registration.tags.push("likes_sports");

registration = await updateRegistration(context, registration);

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

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

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

const registrations = await 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 及更高版本, 计划发送 允许用户最多提前七天安排通知。 所有发送操作都返回可用于通知中心支持案例的跟踪 ID 和相关 ID。 使用标准 SKU 及更高版本时,还会返回通知 ID,可用于通过 getNotificationOutcomeDetails 方法获取通知遥测数据。

出于调试目的, enableTestSend 可以设置 true 选项,以便从 PNS 立即获取方法反馈 sendNotification ,但在生产方案中不受支持。 这在计划的发送方法上不受支持。

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

// Using the class-based approach
import { createAppleNotificationBody } from "@azure/notification-hubs";

// Using the modular approach
import { createAppleNotification, createAppleNotificationBody } from "@azure/notification-hubs/models";

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
})

const result = await sendNotification(context, notification);

广播发送

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

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

const context = createClientContext(connectionString, hubName);

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

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

const result = await client.sendNotification(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, sendNotification } from "@azure/notification-hubs/api";
import { createAppleNotification } from "@azure/notification-hubs/models";

const context = createClientContext(connectionString, hubName);

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

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

const result = await sendNotification(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 方法,使用平台提供的唯一标识符(例如 APNs 设备令牌) deviceHandle 发送。

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

const client = new NotificationHubsClient(connectionString, hubName);

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, sendDirectNotification } from "@azure/notification-hubs/api";
import { createAppleNotification } from "@azure/notification-hubs/models";

const context = createClientContext(connectionString, hubName);

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 模块化导入中公开,该方法从标记创建“或标记表达式”。

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

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

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

console.log(tagExpression);
// likes_football||likes_hockey

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

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/models";

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}`);
}

计划的发送

可以使用 方法将推送通知提前 7 天计划为标准 SKU 命名空间及更高 scheduleBroadcastNotification 命名空间,以发送到具有标记或常规广播的设备。 这会返回一个通知 ID,如有必要,可以通过 方法使用该 ID 取消 cancelScheduledNotification

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/models";

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}`);

故障排除

React Native支持

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

import 'url-search-params-polyfill';

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

诊断丢弃的通知

Azure 通知中心在 Azure 通知中心诊断已删除的 通知指南中提供了排查丢弃通知问题的完整指南。

方法支持sendNotification测试发送enableTestSend选项如下:

// Using the client
const result = await client.sendNotification(notification, { tags, enableTestSend: true });

// Using the modular approach
const result = await sendNotification(context, notification, { tags, enableTestSend: true });

日志记录

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

const { setLogLevel } = require("@azure/logger");

setLogLevel("info");

有关如何启用日志的更详细说明,请查看 @azure/logger 包文档

后续步骤

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

设备管理:

发送操作:

管理操作:

贡献

若要为此库做出贡献,请阅读贡献指南,详细了解如何生成和测试代码。

此模块的测试是实时测试和单元测试的混合体,这要求拥有 Azure 通知中心实例。 若要执行测试,需要运行:

  1. rush update
  2. rush build -t @azure/notification-hubs
  3. Create文件夹中包含以下内容的 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. rushx test.

有关更多详细信息 ,请查看测试 文件夹。

曝光数