如何通过Azure Communication JS Bundle以Teams用户身份加入Teams会议
问题分析与解决方案
核心问题
你遇到的CallAgent must be created only with ACS token错误,本质是Azure Communication Services(ACS)JavaScript Bundle版本的CallWithChat Composite仅支持使用ACS身份令牌创建CallAgent,不直接兼容Teams用户身份令牌(即通过Teams身份管理生成的令牌)。
外部用户成功的原因
外部用户使用的是ACS身份令牌,对应communicationUserId,完全符合Bundle的接入要求,因此可以正常加入已启动的会议。但这类外部未验证身份不具备会议启动权限——即使设置了全员绕开lobby,会议启动权限仍仅对Teams验证用户开放。
可行替代方案
方案1:ACS用户关联Teams身份(推荐)
通过后端将Teams用户的Azure AD身份关联到ACS用户,生成关联后的ACS令牌,前端仍沿用外部用户的接入逻辑,此时该ACS用户将具备Teams用户的会议权限(包括启动会议)。
实现步骤:
- 后端调用ACS身份服务,将Teams用户的
microsoftTeamsUserId与新创建的ACS用户关联(遵循Teams身份管理的关联流程)。 - 为关联后的ACS用户生成包含
voip和chat权限的ACS访问令牌。 - 前端使用该令牌、关联后的ACS用户ID,结合会议的
groupId和chatThreadId接入Composite。
方案2:直接跳转Teams会议链接
若无法实现身份关联,可让Teams用户直接通过Teams客户端或浏览器打开会议原生链接,前端仅为外部用户提供Composite接入入口,完全利用Teams原生会议能力。
关键代码示例
后端(.NET)关联身份并生成令牌
// 创建ACS用户 var acsUserId = await communicationIdentityClient.CreateUserAsync(); // 关联Teams用户身份 var teamsUserId = new MicrosoftTeamsUserId("<Teams用户Azure ID>", "public"); await communicationIdentityClient.UpgradeTeamsUserAsync(acsUserId, teamsUserId); // 生成带VoIP和Chat权限的ACS令牌 var tokenResponse = await communicationIdentityClient.GetTokenAsync(acsUserId, new[] { CommunicationTokenScope.VoIP, CommunicationTokenScope.Chat }); var acsToken = tokenResponse.Token;
前端接入代码(与外部用户逻辑一致)
const callComposite = await callWithChatComposite.loadCallWithChatComposite( { locator: { callLocator: { groupId: "<会议ACS群组ID>" }, chatThreadId: "<会议聊天线程ID>" }, displayName: this.displayName, userId: { communicationUserId: "<关联后的ACS用户ID>", }, token: "<关联后的ACS令牌>", endpoint: this.baseUrl }, document.getElementById('call-container'), { key: new Date() } );
结论
当前JavaScript Bundle版本的CallWithChat Composite不支持直接使用Teams身份令牌接入,必须通过ACS用户关联Teams身份的方式,让ACS令牌继承Teams用户的会议权限,才能实现以Teams身份启动/加入会议的需求。
内容的提问来源于stack exchange,提问作者Udara Chandimal
相关产品推荐
相关产品推荐

