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

适用于 JavaScript 的 Azure 通信电话号码客户端库 - 版本 1.3.0

电话号码库提供电话号码管理功能。

购买的电话号码可以附带许多功能,具体取决于国家/地区、号码类型和分配类型。 功能的示例包括短信入站和出站使用情况、PSTN 入站和出站使用情况。 还可以通过 Webhook URL 将电话号码分配给机器人。

开始

先决条件

安装

npm install @azure/communication-phone-numbers

浏览器支持

JavaScript 捆绑包

若要在浏览器中使用此客户端库,首先需要使用捆绑程序。 有关如何执行此作的详细信息,请参阅我们的 捆绑文档

关键概念

此 SDK 提供轻松管理 direct offerdirect routing 数字的功能。

direct offer 数字分为两种类型:地理和免费。 地理电话计划是与某个位置关联的电话计划,其电话号码的区号与地理位置的区号相关联。 Toll-Free 电话计划是未关联位置的电话计划。 例如,在美国,免费号码可以附带 800 或 888 等区号。 它们使用 PhoneNumbersClient 进行管理

direct routing 功能使现有电话基础结构能够连接到 ACS。 配置使用 SipRoutingClient进行管理,该配置提供设置 SIP 中继和语音路由规则的方法,以便正确处理电话子网的呼叫。

电话号码客户端

电话号码类型

电话号码分为两种类型:地理和免费。 地理电话号码是与某个位置关联的电话号码,其区号与地理位置的区号相关联。 Toll-Free 电话号码与位置无关。 例如,在美国,免费号码可以附带 800 或 888 等区号。

同一国家/地区中的所有地理电话号码都分组为具有地理电话号码类型的电话计划组。 同一国家/地区的所有 Toll-Free 电话号码都分组为电话计划组。

搜索和获取数字

可以通过搜索创建 API 搜索电话号码,方法是提供电话号码类型(地理或免费)、分配类型(人员或应用程序)、呼叫和短信功能、区号和电话号码数量。 提供的电话号码数量将保留 15 分钟。 可以取消或购买此电话号码搜索。 如果搜索被取消,则电话号码将可供其他人使用。 如果购买了搜索,则会为 Azure 资源获取电话号码。

配置电话号码

电话号码可以组合使用功能。 可以将其配置为支持入站和/或出站呼叫,或者如果不使用电话号码进行呼叫,则两者均不能。 这同样适用于短信功能。

请务必考虑电话号码的分配类型。 某些功能仅限于特定分配类型。

SIP 路由客户端

直接路由功能允许将客户提供的电话基础结构连接到 Azure 通信资源。 为了正确设置路由配置,客户需要为呼叫提供 SIP 中继配置和 SIP 路由规则。 SIP 路由客户端提供设置此配置所需的接口。

进行调用时,系统会尝试将目标号码与定义的路由的正则表达式编号模式匹配。 要匹配号码的第一个路由将被选中。 正则表达式匹配的顺序与配置中的路由顺序相同,因此路由顺序很重要。 匹配路由后,呼叫将路由到路由中继列表中的第一个中继。 如果中继不可用,则选择列表中的下一个中继。

例子

认证

若要创建用于访问通信服务 API 的客户端对象,需要 connection string 或通信服务资源的 endpoint 以及 credential。 电话号码客户端可以使用 Azure Active Directory 凭据或 API 密钥凭据进行身份验证。

可以从 Azure 门户中的通信服务资源获取密钥和/或连接字符串。 还可以在 Azure 门户中找到通信服务资源的终结点。

获得密钥后,可以使用以下任一方法对客户端进行身份验证:

使用连接字符串

import { PhoneNumbersClient } from "@azure/communication-phone-numbers";

const connectionString = "endpoint=<endpoint>;accessKey=<accessKey>";
const client = new PhoneNumbersClient(connectionString);
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const connectionString = "endpoint=<endpoint>;accessKey=<accessKey>";
const client = new SipRoutingClient(connectionString);

将访问密钥用于 AzureKeyCredential

如果使用密钥初始化客户端,则还需要提供相应的终结点。 可以从 Azure 门户中的通信服务资源获取此终结点。 获得密钥和终结点后,可以使用以下代码进行身份验证:

import { AzureKeyCredential } from "@azure/core-auth";
import { PhoneNumbersClient } from "@azure/communication-phone-numbers";

const credential = new AzureKeyCredential("<key-from-resource>");
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);
import { AzureKeyCredential } from "@azure/core-auth";
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const credential = new AzureKeyCredential("<key-from-resource>");
const client = new SipRoutingClient("<endpoint-from-resource>", credential);

使用 Azure Active Directory 凭据

大多数示例中都使用连接字符串身份验证,但也可以使用 Azure 标识库通过 Azure Active Directory 进行身份验证。 若要使用如下所示的 DefaultAzureCredential 提供程序,或 Azure SDK 提供的其他凭据提供程序,请安装 @azure/identity 包:

npm install @azure/identity

@azure/identity 包提供了应用程序可用于执行此作的各种凭据类型。 @azure/identity 自述文件提供了更多详细信息和示例来帮助你入门。

import { DefaultAzureCredential } from "@azure/identity";
import { PhoneNumbersClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);
import { DefaultAzureCredential } from "@azure/identity";
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new SipRoutingClient("<endpoint-from-resource>", credential);

用法

以下部分提供了代码片段,这些代码片段涵盖了使用 Azure 通信服务电话号码客户端完成的一些常见任务。 此处介绍的方案包括:

PhoneNumbersClient

SipRoutingClient

PhoneNumbersClient

搜索可用的电话号码

使用 beginSearchAvailablePhoneNumbers 方法搜索电话号码并保留电话号码。 返回的电话号码保留 15 分钟,可通过向 beginPurchasePhoneNumbers 方法提供 searchId 在此期间购买。

beginSearchAvailablePhoneNumbers 是长时间运行的作,并返回一个轮询器。

import { DefaultAzureCredential } from "@azure/identity";
import {
  PhoneNumbersClient,
  SearchAvailablePhoneNumbersRequest,
} from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);

const searchRequest: SearchAvailablePhoneNumbersRequest = {
  countryCode: "US",
  phoneNumberType: "tollFree",
  assignmentType: "application",
  capabilities: {
    sms: "outbound",
    calling: "none",
  },
  quantity: 1,
};

const searchPoller = await client.beginSearchAvailablePhoneNumbers(searchRequest);

// The search is underway. Wait to receive searchId.
const searchResults = await searchPoller.pollUntilDone();
console.log(`Found phone number: ${searchResults.phoneNumbers[0]}`);
console.log(`searchId: ${searchResults.searchId}`);

使用 beginPurchasePhoneNumbers 方法从搜索中购买电话号码。 购买的电话号码将分配给启动客户端时使用的通信服务资源。 需要从 beginSearchAvailablePhoneNumbers 返回 searchId

beginPurchasePhoneNumbers 是长时间运行的作,并返回一个轮询器。

import { DefaultAzureCredential } from "@azure/identity";
import {
  PhoneNumbersClient,
  SearchAvailablePhoneNumbersRequest,
} from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);

const searchRequest: SearchAvailablePhoneNumbersRequest = {
  countryCode: "US",
  phoneNumberType: "tollFree",
  assignmentType: "application",
  capabilities: {
    sms: "outbound",
    calling: "none",
  },
  quantity: 1,
};

const searchPoller = await client.beginSearchAvailablePhoneNumbers(searchRequest);

// The search is underway. Wait to receive searchId.
const { searchId, phoneNumbers } = await searchPoller.pollUntilDone();

const purchasePoller = await client.beginPurchasePhoneNumbers(searchId);

// Purchase is underway.
await purchasePoller.pollUntilDone();
console.log(`Successfully purchased ${phoneNumbers[0]}`);

释放购买的电话号码

使用 beginReleasePhoneNumber 方法释放以前购买的电话号码。 已发布的电话号码将不再与通信服务资源关联,并且不能与其他作(例如)一起使用。资源的 SMS。 需要释放的电话号码。

beginReleasePhoneNumber 是长时间运行的作,并返回一个轮询器。

import { DefaultAzureCredential } from "@azure/identity";
import { PhoneNumbersClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);

const phoneNumberToRelease = "<phone-number-to-release>";

const releasePoller = await client.beginReleasePhoneNumber(phoneNumberToRelease);

// Release is underway.
await releasePoller.pollUntilDone();
console.log("Successfully release phone number.");

更新电话号码功能

使用 beginUpdatePhoneNumberCapabilities 方法更新购买的电话号码的功能。 电话号码可配置为支持入站和/或出站呼叫和短信,或者两者均不支持。

beginUpdatePhoneNumberCapabilities 是长时间运行的作,并返回一个轮询器。

import { DefaultAzureCredential } from "@azure/identity";
import {
  PhoneNumbersClient,
  PhoneNumberCapabilitiesRequest,
} from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);

const phoneNumberToUpdate = "<phone-number-to-update>";

// This will update phone number to send and receive sms, but only send calls.
const updateRequest: PhoneNumberCapabilitiesRequest = {
  sms: "inbound+outbound",
  calling: "outbound",
};

const updatePoller = await client.beginUpdatePhoneNumberCapabilities(
  phoneNumberToUpdate,
  updateRequest,
);

// Update is underway.
const { capabilities } = await updatePoller.pollUntilDone();
console.log(`These are the update capabilities: ${capabilities}`);

获取购买的电话号码

使用 getPurchasedPhoneNumber 方法获取有关已购买电话号码的信息。 此信息包括电话号码的类型、功能、成本和购买日期。

import { DefaultAzureCredential } from "@azure/identity";
import { PhoneNumbersClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);

const phoneNumberToGet = "<phone-number-to-get>";

const phoneNumber = await client.getPurchasedPhoneNumber(phoneNumberToGet);

console.log(`The id is the same as the phone number: ${phoneNumber.id}`);
console.log(`Phone number type is ${phoneNumber.phoneNumberType}`);

列出购买的电话号码

使用 listPurchasedPhoneNumbers 方法可翻阅所有购买的电话号码。

import { DefaultAzureCredential } from "@azure/identity";
import { PhoneNumbersClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new PhoneNumbersClient("<endpoint-from-resource>", credential);

const phoneNumbers = client.listPurchasedPhoneNumbers();

for await (const phoneNumber of phoneNumbers) {
  console.log(`The id is the same as the phone number: ${phoneNumber.id}`);
  console.log(`Phone number type is ${phoneNumber.phoneNumberType}`);
}

SipRoutingClient

检索 SIP 中继和路由

获取当前配置的中继或路由的列表。

import { DefaultAzureCredential } from "@azure/identity";
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new SipRoutingClient("<endpoint-from-resource>", credential);

const trunks = client.listTrunks();
const routes = client.listRoutes();
for await (const trunk of trunks) {
  console.log(`Trunk ${trunk.fqdn}:${trunk.sipSignalingPort}`);
}

for await (const route of routes) {
  console.log(`Route ${route.name} with pattern ${route.numberPattern}`);
  console.log(`Route's trunks: ${route.trunks?.join()}`);
}

替换 SIP 中继和路由

将当前配置的中继或路由列表替换为新值。

import { DefaultAzureCredential } from "@azure/identity";
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new SipRoutingClient("<endpoint-from-resource>", credential);

await client.setTrunks([
  {
    fqdn: "sbc.one.domain.com",
    sipSignalingPort: 1234,
  },
  {
    fqdn: "sbc.two.domain.com",
    sipSignalingPort: 1234,
  },
]);

await client.setRoutes([
  {
    name: "First Route",
    description: "route's description",
    numberPattern: "^+[1-9][0-9]{3,23}$",
    trunks: ["sbc.one.domain.com"],
  },
  {
    name: "Second Route",
    description: "route's description",
    numberPattern: "^.*$",
    trunks: ["sbc.two.domain.com", "sbc.one.domain.com"],
  },
]);

检索单个中继

import { DefaultAzureCredential } from "@azure/identity";
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new SipRoutingClient("<endpoint-from-resource>", credential);

const trunk = await client.getTrunk("sbc.one.domain.com");
if (trunk) {
  console.log(`Trunk ${trunk.fqdn}:${trunk.sipSignalingPort}`);
} else {
  console.log("Trunk not found");
}

设置单个中继

import { DefaultAzureCredential } from "@azure/identity";
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new SipRoutingClient("<endpoint-from-resource>", credential);

await client.setTrunk({
  fqdn: "sbc.one.domain.com",
  sipSignalingPort: 4321,
});

删除单个中继

import { DefaultAzureCredential } from "@azure/identity";
import { SipRoutingClient } from "@azure/communication-phone-numbers";

const credential = new DefaultAzureCredential();
const client = new SipRoutingClient("<endpoint-from-resource>", credential);

await client.deleteTrunk("sbc.one.domain.com");

故障 排除

伐木

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

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

setLogLevel("info");

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

后续步骤

有关如何使用此库的详细示例,请查看 示例 目录。

贡献

若要参与此库,请阅读 贡献指南 了解有关如何生成和测试代码的详细信息。