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

转移呼叫

在活动通话期间,你可能需要将通话转移到另一个人、号码或语音信箱。 让我们来了解如何操作。

先决条件

安装 SDK

使用 npm install 命令安装适用于 JavaScript 的 Azure 通信服务通用 SDK 和通话 SDK:

npm install @azure/communication-common --save
npm install @azure/communication-calling --save

初始化所需的对象

大多数通话操作需要 CallClient 实例。 创建新的 CallClient 实例时,可以使用自定义选项(如 Logger 实例)对其进行配置。

有了 CallClient 实例后,可以通过调用 createCallAgent 创建 CallAgent 实例。 此方法将异步返回 CallAgent 实例对象。

createCallAgent 方法使用 CommunicationTokenCredential 作为参数。 它接受用户访问令牌

可在 CallClient 实例上使用 getDeviceManager 方法来访问 deviceManager

const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");

// Set the logger's log level
setLogLevel('verbose');

// Redirect log output to console, file, buffer, REST API, or whatever location you want
AzureLogger.log = (...args) => {
    console.log(...args); // Redirect log output to console
};

const userToken = '<USER_TOKEN>';
callClient = new CallClient(options);
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const callAgent = await callClient.createCallAgent(tokenCredential, {displayName: 'optional Azure Communication Services user name'});
const deviceManager = await callClient.getDeviceManager()

如何最好地管理 SDK 与 Microsoft 基础结构的连接性

Call Agent 实例可帮助你管理通话(以加入或启动通话)。 通话 SDK 需要连接到 Microsoft 基础结构以获取传入通话通知并协调其他通话详细信息,否则无法工作。 你的 Call Agent 有两种可能的状态:

已连接 - Call Agent connectionStatue 值为 Connected 表示客户端 SDK 已连接,能够接收来自 Microsoft 基础结构的通知。

已断开连接 - Call Agent connectionStatue 值为 Disconnected 表示存在阻止 SDK 正确连接的问题。 应重新创建 Call Agent

  • invalidToken:如果令牌已过期或无效,Call Agent 实例会断开连接并出现此错误。
  • connectionIssue:如果客户端连接到 Microsoft 基础结构时出现问题,则在多次重试后,Call Agent 会显示 connectionIssue 错误。

可以通过检查 connectionState 属性的当前值来检查本地 Call Agent 是否已连接到 Microsoft 基础结构。 在通话过程中,可以侦听 connectionStateChanged 事件,以确定 Call Agent 是否从“已连接”状态更改为“已断开连接”状态。

const connectionState = callAgentInstance.connectionState;
console.log(connectionState); // it may return either of 'Connected' | 'Disconnected'

const connectionStateCallback = (args) => {
    console.log(args); // it will return an object with oldState and newState, each of having a value of either of 'Connected' | 'Disconnected'
    // it will also return reason, either of 'invalidToken' | 'connectionIssue'
}
callAgentInstance.on('connectionStateChanged', connectionStateCallback);

呼叫转移是核心 Call API 的扩展功能。 首先,需要从通话 SDK 导入通话功能:

import { Features} from "@azure/communication-calling";

然后,可从通话实例获取传输功能 API 对象:

const callTransferApi = call.feature(Features.Transfer);

呼叫转移涉及三个参与方:

  • 转移方:发起转移请求的人员。
  • 被转移方:被转移的人员。
  • 转移目标:被转移到的人员。

转移到参与者:

  1. 转移方和被转移方之间已经存在接通的电话。 转移方决定将呼叫从被转移方转移到转移目标
  2. 转移方调用 transfer API。
  3. 传输目标接收传入呼叫。

若要转移当前呼叫,可以使用 transfer API。 transfer 接受可选的 transferCallOptions,这允许你设置 disableForwardingAndUnanswered 标志:

  • disableForwardingAndUnanswered = false:如果转移目标未接听转移的呼叫,则转移方将遵循转移目标的转发设置和未接听设置。
  • disableForwardingAndUnanswered = true:如果转移目标未接听转移的呼叫,则转移尝试结束。
// transfer target can be an Azure Communication Services user
const id = { communicationUserId: <ACS_USER_ID> };
// call transfer API
const transfer = callTransferApi.transfer({targetParticipant: id});

转移到呼叫:

  1. 转移方和被转移方之间已经存在接通的电话。
  2. 转移方和转移目标之间已经存在接通的电话。
  3. 转移方决定将呼叫从被转移方转移到转移目标
  4. 转移方调用 transfer API。
  5. 传输目标接收传入呼叫。

若要转移当前呼叫,可以使用 transfer API。

// transfer to the target call specifying the call id
const id = { targetCallId: <CALL_ID> };
// call transfer API
const transfer = callTransferApi.transfer({ targetCallId: <CALL_ID> });

transfer API 支持订阅 stateChanged。 它还附带传输 stateerror 属性

// transfer state
const transferState = transfer.state; // None | Transferring | Transferred | Failed

// to check the transfer failure reason
const transferError = transfer.error; // transfer error code that describes the failure if a transfer request failed

被转移方可以侦听 transferAccepted 事件。 此事件的侦听器有一个 TransferEventArgs,其中包含被转移方与转移目标之间的新转移调用的调用对象。

// Transferee can subscribe to the transferAccepted event
callTransferApi.on('transferAccepted', args => {
    const newTransferCall =  args.targetCall;
});

转移方可以订阅转移状态更改事件。 如果对被转移方的呼叫已成功与转移目标连接,则转移方可以挂断对被转移方的原始呼叫。

transfer.on('stateChanged', () => {
   if (transfer.state === 'Transferred') {
       call.hangUp();
   }
});

转移到语音信箱:

  1. 转接人和被转接人之间有一个连接通话。
  2. 已知目标参与者语音信箱的 Teams 用户标识符。
  3. 转接人决定使用目标参与者的 Teams 用户标识符将与被转接人之间的通话转移到目标参与者的语音信箱。
  4. 转移方调用 transfer API。
  5. 被转移方接收转移请求。

若要转移当前呼叫,可以使用 transfer API。

// transfer to the target participant voicemail specified by their Teams User Identifier
const id: MicrosoftTeamsUserIdentifier = { microsoftTeamsUserId: userId}
// call transfer API
const transfer = callTransferApi.transfer({ targetParticipantVoicemail: id });

transfer API 支持订阅 stateChanged。 它还附带传输 stateerror 属性

// transfer state
const transferState = transfer.state; // None | Transferring | Transferred | Failed

// to check the transfer failure reason
const transferError = transfer.error; // transfer error code that describes the failure if a transfer request failed

被转移方可以侦听 transferAccepted 事件。 此事件的侦听器有一个 TransferEventArgs,其中包含被转移方与目标参与者语音信箱之间的新转移通话的通话对象。

// Transferee can subscribe to the transferAccepted event
callTransferApi.on('transferAccepted', args => {
    const newTransferCall =  args.targetCall;
});

转移方可以订阅转移状态更改事件。 如果与被转移方的通话已成功与目标参与者语音信箱连接,则转移方可以挂断与被转移方的原始通话。

transfer.on('stateChanged', () => {
   if (transfer.state === 'Transferred') {
       call.hangUp();
   }
});

后续步骤