无Teams Phone许可证时,ACS Call Automation SDK接收Teams呼叫并转至SIP的配置与调用问题排查
无Teams Phone许可证时,ACS Call Automation SDK接收Teams呼叫并转至SIP的配置与调用问题排查
看起来你在尝试让仅拥有TEAMS1服务计划(无Teams Phone许可证)的Teams用户呼叫ACS Call Automation应用,并转接至SIP端点时遇到了两个核心问题,我来逐一帮你分析排查并给出解决方案:
问题1:Teams无法搜索到ACS用户ID(8:acs:...格式)
核心原因
ACS生成的用户ID(8:acs:<resource-id>:<user-id>)是ACS服务内部的唯一身份标识符,并不属于Teams的可搜索身份范围。Teams的搜索索引仅包含AAD组织内用户、已添加的外部联系人、联邦组织用户等,ACS用户不在这个索引里,所以直接搜索肯定会提示“找不到结果”。
解决方式:改用Teams可识别的呼叫目标
不要让用户搜索ACS用户ID,而是采用以下两种可靠的呼叫方式:
- 方式1:使用ACS关联的电话号码
在Azure门户的ACS资源中,进入「电话号码」选项卡申请一个可用号码,并将其分配给你的Call Automation应用。之后让Teams用户直接拨打这个电话号码即可发起呼叫(注意:无Teams Phone许可证的用户能否拨打外部号码需要结合呼叫策略验证,见下文)。 - 方式2:手动添加ACS用户为Teams联系人
将ACS用户ID转换为Teams可识别的格式:acs:<your-ACS-resource-id>:<user-id-suffix>(比如原ID是8:acs:xxxxxx-xxxx-xxxx-xxxx-xxxxxx:user-yyyyyy-yyyy-yyyy-yyyy-yyyyyy,提取后面的user-yyyyyy...部分,组合成acs:xxxxxx-xxxx-xxxx-xxxx-xxxxxx:user-yyyyyy-yyyy-yyyy-yyyy-yyyyyy),然后让Teams用户手动添加这个地址为外部联系人,之后就能从联系人列表发起呼叫。
问题2:呼叫失败提示「With your calling license, you can only call people within your organization.」
核心原因
这个提示的本质是Teams用户的呼叫权限与许可证限制:
- 仅拥有TEAMS1服务计划的用户,默认呼叫策略限制为仅允许组织内部的P2P/会议呼叫,无法发起跨组织(包括ACS联邦目标)的出站呼叫;
- 即使你配置了ACS-Teams联邦,若未调整用户的呼叫策略,许可证的默认限制依然会生效。
分步解决方案
步骤1:调整Teams用户的呼叫策略
通过PowerShell修改目标用户的呼叫策略,允许跨组织呼叫:
# 首先安装并连接Teams PowerShell模块 Install-Module -Name MicrosoftTeams Connect-MicrosoftTeams # 为指定用户开启跨组织呼叫权限 Set-CsUserCallingPolicy -Identity "user@your-domain.com" -AllowExternalCalling $true
步骤2:验证ACS-Teams联邦配置正确性
重新确认你的联邦配置是否有效:
- 确保
Set-CsTeamsAcsFederationConfiguration命令中指定的AllowedAcsResourceIdentifiers是完整的ACS资源ID(可从Azure门户ACS资源的「概述」页面复制,格式为xxxxxx-xxxx-xxxx-xxxx-xxxxxx); - 重新运行配置命令确保生效:
Set-CsTeamsAcsFederationConfiguration -AllowedAcsResourceIdentifiers "<your-full-ACS-resource-id>"
- 验证联邦状态:
Get-CsTeamsAcsFederationConfiguration
确认输出中的AllowedAcsResourceIdentifiers包含你的ACS资源ID。
步骤3:测试呼叫权限
先用拥有Teams Phone许可证的用户测试呼叫ACS应用:
- 如果测试成功,说明联邦配置正常,问题确实出在无许可证用户的呼叫策略限制;
- 如果测试失败,检查ACS的回调URI是否公网可访问、呼入处理代码是否能正常接收事件(可以添加日志记录
incomingCallContext和事件内容)。
代码逻辑优化建议
你的呼入处理流程整体正确,但可以添加错误捕获与日志记录,便于排查后续问题:
app.MapPost("/api/calls/incoming", async (HttpContext http, CallAutomationClient callClient) => { try { var body = await new StreamReader(http.Request.Body).ReadToEndAsync(); var incomingEvent = JsonDocument.Parse(body); var callContext = incomingEvent.RootElement.GetProperty("incomingCallContext").GetString(); // 记录呼入事件日志,便于排查 Console.WriteLine($"Received incoming call with context: {callContext}"); var answerResult = await callClient.AnswerCallAsync(callContext, new Uri(callbackUri)); var callConnection = answerResult.Value.CallConnection; var sipParticipant = new PhoneNumberIdentifier(sipTarget); var transferResult = await callConnection.TransferCallToParticipantAsync(sipParticipant); // 记录转接结果 Console.WriteLine($"Transfer call result: {transferResult.Value.OperationId}"); return Results.Ok(); } catch (Exception ex) { // 记录异常日志 Console.WriteLine($"Error handling incoming call: {ex.Message}"); return Results.BadRequest($"Call handling failed: {ex.Message}"); } });
额外注意事项
- 无Teams Phone许可证的用户即使开启了跨组织呼叫,依然无法拨打传统PSTN号码,但若你的SIP端点是与ACS联邦的企业SBC,转接流程可以正常执行;
- 确保ACS应用的回调URI是公网可访问的(可使用ngrok等工具在测试环境中转发本地端口),否则ACS无法将呼叫事件回调到你的服务,导致呼入处理失败。
内容来源于stack exchange
相关产品推荐
相关产品推荐

