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

使用通话自动化将 Microsoft Teams 用户添加到现有通话

在本快速入门中,我们使用 Azure 通信服务通话自动化 API 向 Teams 用户添加、删除和转移通话。

先决条件

  • 具有活动订阅的 Azure 帐户。
  • 具有管理权限的 Microsoft Teams 电话许可证和 Teams 租户。 Teams 电话许可证是使用此功能的必备条件,请在此处了解有关 Teams 许可证的详细信息。 Microsoft Teams 用户还必须启用 voice,请参阅设置手机系统。 授权通信服务资源呼叫 Teams 用户需要管理权限,步骤 1 稍后将介绍此内容。
  • 在 Azure 门户上的左侧菜单中选择“密钥”找到的已部署的通信服务资源和有效连接字符串。
  • 从通信服务资源获取 PSTN 电话号码。 记下获取的电话号码以便在本快速入门中使用。
  • 用于接收 IncomingCall 事件的 Azure 事件网格订阅。
  • 适用于操作系统的最新 Azure 通信服务通话自动化 API 库
  • 实现通话自动化 API 库的 Web 服务,请遵循此教程

步骤 1:向 Azure 通信服务资源授权以允许呼叫 Microsoft Teams 用户

若要通过通话自动化 API 允许呼叫,Microsoft Teams 管理员全局管理员必须显式许可通信服务资源对其租户的访问权限,才能允许呼叫。

Set-CsTeamsAcsFederationConfiguration (MicrosoftTeamsPowerShell) 租户级设置,可启用/禁用其租户与特定通信服务资源之间的联合。

Set-CsExternalAccessPolicy (SkypeForBusiness) 用户策略,允许管理员进一步控制组织中的哪些用户可以参与与通信服务用户的联合通信。

请注意,Teams 用户需要有 Phone 许可证才能使用此功能。 要分配许可证,请使用 Set-CsPhoneNumberAssignment cmdlet 并将 EnterpriseVoiceEnabled 参数设置为 $true。 有关详细信息,请参阅在组织中设置 Teams 电话

步骤 2:使用图形 API 获取 Teams 用户的 Microsoft Entra 对象 ID,并根据需要检查其状态

将 Teams 用户添加到通信服务通话或从通信服务通话转移到该用户需要该用户的 Microsoft Entra 对象 ID (OID)。 可通过以下方式检索 OID 1) Office 门户,2) Microsoft Entra 管理中心,3) Microsoft Entra Connect;或 4) 图形 API。 下面的示例使用图形 API。

Microsoft Entra 管理员必须许可同意,然后才能使用 Graph 搜索用户,请参阅 Microsoft Graph 安全 API 概述文档了解详细信息。 可以使用列表用户 API 检索 OID 以搜索用户。 下面按显示名称显示搜索结果,但也可以搜索其他属性:

使用 Microsoft Graph v1.0 列出用户

Request:
	https://graph.microsoft.com/v1.0/users?$search="displayName:Art Anderson"
Permissions:
	Application and delegated. Refer to documentation.
Response:
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users",
    "value": [
        {
            "displayName": "Art Anderson",
            "mail": "artanderson@contoso.com",
            "id": "fc4ccb5f-8046-4812-803f-6c344a5d1560"
        }

(可选)可以使用获取状态 API 和用户 ObjectId 检索用户的状态。 请参阅 Microsoft Graph v1.0 文档了解详细信息。

Request:
https://graph.microsoft.com/v1.0/users/fc4ccb5f-8046-4812-803f-6c344a5d1560/presence
Permissions:
Delegated only. Application not supported.  Refer to documentation.
Response:
    "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('fc4ccb5f-8046-4812-803f-6c344a5d1560')/presence/$entity",
    "id": "fc4ccb5f-8046-4812-803f-6c344a5d1560",
    "availability": "Offline",
    "activity": "Offline"

步骤 3:将 Teams 用户添加到由通话自动化 API 控制的现有通信服务通话

需要完成先决条件步骤,并让 Web 服务应用控制通信服务通话。 使用 callConnection 对象,将参与者添加到通话。

CallAutomationClient client = new CallAutomationClient('<Connection_String>');
AnswerCallResult answer = await client.AnswerCallAsync(incomingCallContext, new Uri('<Callback_URI>'));
await answer.Value.CallConnection.AddParticipantAsync(
    new CallInvite(new MicrosoftTeamsUserIdentifier('<Teams_User_Guid>'))
    {
        SourceDisplayName = "Jack (Contoso Tech Support)"
    });
CallAutomationClient client = new CallAutomationClientBuilder().connectionString("<resource_connection_string>").buildClient();
AnswerCallResult answer = client.answerCall(incomingCallContext, "<Callback_URI>"));
answer.getCallConnection().addParticipant(
    new CallInvite(new MicrosoftTeamsUserIdentifier("<Teams_User_Guid>"))
        .setSourceDisplayName("Jack (Contoso Tech Support)"));
const client = new CallAutomationClient("<resource_connection_string>");
const answer = await client.answerCall(incomingCallContext, "<Callback_URI>"));
answer.callConnection.addParticipant({
    targetParticipant: { microsoftTeamsUserId: "<Teams_User_Guid>" },
    sourceDisplayName: "Jack (Contoso Tech Support)"
});
call_automation_client = CallAutomationClient.from_connection_string("<resource_connection_string>")
answer = call_automation_client.answer_call(incoming_call_context = incoming_call_context, callback_url = "<Callback_URI>")
call_connection_client = call_automation_client.get_call_connection(answer.call_connection_id)
call_connection_client.add_participant(target_participant = CallInvite(
    target = MicrosoftTeamsUserIdentifier(user_id="<USER_ID>"),
    source_display_name = "Jack (Contoso Tech Support)"))

在 Microsoft Teams 桌面客户端上,Jack 的通话将通过传入通话 toast 通知发送到 Microsoft Teams 用户。

Microsoft Teams 桌面客户端的屏幕截图,Jack 的通话通过传入通话 toast 通知发送到 Microsoft Teams 用户。

Microsoft Teams 用户接听通话后,Microsoft Teams 用户的通话内体验将在 Microsoft Teams 名单中显示所有参与者。 请注意,使用通话自动化 API 管理通话的应用程序将会在通话屏幕上对 Teams 用户保持隐藏,但发起与 Teams 用户的一对一通话时除外。
接听通话并进入 Microsoft Teams 用户的通话内体验的 Microsoft Teams 用户的屏幕截图。

步骤 4:从由通话自动化 API 控制的现有通信服务通话中删除 Teams 用户

await answer.Value.CallConnection.RemoveParticipantAsync(new MicrosoftTeamsUserIdentifier('<Teams_User_Guid>'));
answer.getCallConnection().removeParticipant(new MicrosoftTeamsUserIdentifier("<Teams_User_Guid>"));
answer.callConnection.removeParticipant({ microsoftTeamsUserId: "<Teams_User_Guid>" });
call_connection_client.remove_participant(target_participant = MicrosoftTeamsUserIdentifier(user_id="<USER_ID>"))

可选功能:从由通话自动化 API 控制的现有通信服务通话转移到 Teams 用户

await answer.Value.CallConnection.TransferCallToParticipantAsync(new MicrosoftTeamsUserIdentifier('<Teams_User_Guid>'));
answer.getCallConnection().transferCallToParticipant(new MicrosoftTeamsUserIdentifier("<Teams_User_Guid>"));
answer.callConnection.transferCallToParticipant({ microsoftTeamsUserId: "<Teams_User_Guid>" });
call_connection_client.transfer_call_to_participant(target_participant = MicrosoftTeamsUserIdentifier(user_id = "<USER_ID>"))

清理资源

如果想要清理并删除通信服务订阅,可以删除资源或资源组。 删除资源组同时也会删除与之相关联的任何其他资源。 了解有关清理资源的详细信息。

后续步骤