在本练习中,你将使用 Azure Functions 和 Microsoft Graph 自动创建 Microsoft Teams 会议链接并传递给 ACS 的过程。
需要为守护程序应用身份验证创建Microsoft Entra ID 应用。 在此步骤中,将使用 应用凭据在后台处理身份验证,Microsoft Entra ID 应用将使用应用程序权限进行Microsoft图形 API 调用。 Microsoft Graph 将用于动态创建 Microsoft Teams 会议并返回 Teams 会议 URL。
执行以下步骤创建Microsoft Entra ID 应用:
- 转到 Azure 门户 并选择 Microsoft Entra ID。
- 选择 “应用注册 ”选项卡,后跟 “+ 新建注册”。
- 填写新的应用注册表单详细信息,如下所示,然后选择 “注册” :
- 名称:ACS Teams 互操作应用
- 支持的帐户类型: 任何组织目录中的帐户(任何Microsoft Entra ID 目录 - 多租户)和个人Microsoft帐户(例如 Skype、Xbox)
- 重定向 URI:将此保留为空
- 注册应用后,转到 API 权限 并选择“ + 添加权限”。
- 选择 Microsoft Graph,然后选择 应用程序权限。
- 选择权限
Calendars.ReadWrite
,然后选择“ 添加”。 - 添加权限后,为YOUR_ORGANIZATION_NAME<选择“授予管理员许可>”。
- 转到“ 证书和机密 ”选项卡,选择“ + 新建客户端密码”,然后选择“ 添加”。
- 将机密的值复制到本地文件中。 你将在本练习后续部分使用此值。
- 转到“ 概述 ”选项卡,将
Application (client) ID
和Directory (tenant) ID
值复制到上一步中使用的同一本地文件中。
创建 local.settings.json 文件
在 Visual Studio 中打开
samples/acs-to-teams-meeting/server/csharp/GraphACSFunctions.sln
或在 Visual Studio Code 中打开GraphACSFunctions文件夹。转到
GraphACSFunctions
项目并创建具有以下local.settings.json
值的文件:{ "IsEncrypted": false, "Values": { "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated", "TENANT_ID": "", "CLIENT_ID": "", "CLIENT_SECRET": "", "USER_ID": "", "ACS_CONNECTION_STRING": "" }, "Host": { "LocalHttpPort": 7071, "CORS": "*", "CORSCredentials": false }, "watchDirectories": [ "Shared" ] }
- 使用在前面的练习中复制到本地文件中的值,来更新
TENANT_ID
、CLIENT_ID
和CLIENT_SECRET
的值。 - 使用要创建 Microsoft Teams 会议的用户 ID 进行定义
USER_ID
。
可以从 Azure 门户获取用户 ID。
- 使用 Microsoft 365 开发人员租户管理员帐户登录。
- 选择 Microsoft Entra ID
- 导航到侧栏上的“ 用户 ”选项卡。
- 搜索用户名并选择它以查看用户详细信息。
- 在用户详细信息中,
Object ID
表示User ID
。 将Object ID
的值复制并用于USER_ID
中的 值。
注释
ACS_CONNECTION_STRING
将在下一个练习中使用,因此你尚不需要更新它。- 使用在前面的练习中复制到本地文件中的值,来更新
打开
GraphACSFunctions.sln
位于 acs-to-teams-meeting/server/csharp 文件夹中,并请注意,它包含以下 Microsoft Graph 和身份验证包:<PackageReference Include="Azure.Communication.Identity" Version="1.3.1" /> <PackageReference Include="Azure.Identity" Version="1.11.2" /> <PackageReference Include="Microsoft.Graph" Version="5.51.0" />
转到 Program.cs ,并在方法中
ConfigureServices
记下以下代码:var host = new HostBuilder() .ConfigureFunctionsWebApplication() .ConfigureServices(services => { services.AddApplicationInsightsTelemetryWorkerService(); services.ConfigureFunctionsApplicationInsights(); services.AddSingleton(static p => { var config = p.GetRequiredService<IConfiguration>(); var clientSecretCredential = new ClientSecretCredential( config.GetValue<string>("TENANT_ID"), config.GetValue<string>("CLIENT_ID"), config.GetValue<string>("CLIENT_SECRET") ); return new GraphServiceClient( clientSecretCredential, ["https://graph.microsoft.com/.default"] ); }); ... services.AddSingleton<IGraphService, GraphService>(); }) .Build(); }
打开 服务/GraphService.cs。
花点时间探索
CreateMeetingEventAsync
方法:using System; using System.Threading.Tasks; using Microsoft.Graph; using Microsoft.Extensions.Configuration; namespace GraphACSFunctions.Services; public class GraphService : IGraphService { private readonly GraphServiceClient _graphServiceClient; private readonly IConfiguration _configuration; public GraphService(GraphServiceClient graphServiceClient, IConfiguration configuration) { _graphServiceClient = graphServiceClient; _configuration = configuration; } public async Task<string> CreateMeetingAsync() { var userId = _configuration.GetValue<string>("USER_ID"); var newMeeting = await _graphServiceClient .Users[userId] .Calendar .Events .PostAsync(new() { Subject = "Customer Service Meeting", Start = new() { DateTime = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss"), TimeZone = "UTC" }, End = new() { DateTime = DateTime.UtcNow.AddHours(1).ToString("yyyy-MM-ddTHH:mm:ss"), TimeZone = "UTC" }, IsOnlineMeeting = true }); return newMeeting.OnlineMeeting.JoinUrl; } }
-
GraphServiceClient
和IConfiguration
对象将注入构造函数并分配给字段。 - 该
CreateMeetingAsync()
函数将数据发布到 Microsoft Graph 日历事件 API,该 API 在用户的日历中动态创建事件并返回联接 URL。
-
打开 TeamsMeetingFunctions.cs 并花点时间检查它的构造函数。
GraphServiceClient
您之前查看的内容被注入并分配给_graphService
字段。private readonly IGraphService _graphService; public TeamsMeetingFunction(IGraphService graphService) => _graphService = graphService;
定位
Run
方法:[Function("HttpTriggerTeamsUrl")] public async Task<HttpResponseData> Run( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequestData req, ILogger log) { var response = req.CreateResponse(HttpStatusCode.OK); await response.WriteStringAsync(await _graphService.CreateMeetingAsync()); return response; }
- 它定义可以使用 HTTP GET 请求调用的
HttpTriggerTeamsUrl
函数名称。 - 它调用
_graphService.CreateMeetingAsync()
,这将创建新事件并返回联接 URL。
- 它定义可以使用 HTTP GET 请求调用的
在 Visual Studio 中按 F5 或选择 “调试”来运行程序 -> 从菜单中选择“开始调试 ”。 此作将启动 Azure Functions 项目并使其
ACSTokenFunction
可供调用。
注释
如果使用 VS Code,可以在 GraphACSFunctions 文件夹中打开终端窗口并运行 func start
。 这假定已在计算机上安装 了 Azure Functions Core Tools 。
从 React 调用 Azure 函数
现在,函数
httpTriggerTeamsUrl
已准备好使用,接下来让我们从 React 应用调用它。展开 客户端/react 文件夹。
使用以下值将 .env 文件添加到文件夹中:
REACT_APP_TEAMS_MEETING_FUNCTION=http://localhost:7071/api/httpTriggerTeamsUrl REACT_APP_ACS_USER_FUNCTION=http://localhost:7071/api/httpTriggerAcsToken
这些值将在生成时传递到 React 中,以便在生成过程中根据需要轻松更改它们。
在 VS Code 中打开 client/react/App.tsx 文件。
在
teamsMeetingLink
组件中找到状态变量。 删除硬编码的团队链接,并将其替换为空引号:const [teamsMeetingLink, setTeamsMeetingLink] = useState<string>('');
找到函数
useEffect
并将其更改为如下所示。 这将处理调用你之前查看的 Azure 函数,该函数用于创建 Teams 会议并返回会议的加入链接。useEffect(() => { const init = async () => { /* Commenting out for now setMessage('Getting ACS user'); //Call Azure Function to get the ACS user identity and token const res = await fetch(process.env.REACT_APP_ACS_USER_FUNCTION as string); const user = await res.json(); setUserId(user.userId); setToken(user.token); */ setMessage('Getting Teams meeting link...'); //Call Azure Function to get the meeting link const resTeams = await fetch(process.env.REACT_APP_TEAMS_MEETING_FUNCTION as string); const link = await resTeams.text(); setTeamsMeetingLink(link); setMessage(''); console.log('Teams meeting link', link); } init(); }, []);
保存文件,然后再继续。
打开终端窗口,
cd
进入 *react 文件夹,然后运行npm start
以生成和运行应用程序。应用程序生成并加载后,应会看到显示 ACS 调用 UI,然后可以调用由 Microsoft Graph 动态创建的 Teams 会议。
通过在终端窗口中输入 Ctrl + C 来停止终端进程。
停止 Azure Functions 项目。
下一步
注释
请访问 Azure 通信服务文档,详细了解如何以其他方式 扩展 Microsoft Teams 会议 。