如何在Teams中用任务模块展示交互式图表?Botframework SDK 4.0实现疑问
实现Teams机器人交互式图表任务模块步骤拆解
1. 开发带Chart.js的交互式图表页面
先做一个可公网访问的HTML页面(调试阶段可用ngrok代理本地服务),页面需包含Chart.js渲染逻辑和Teams环境适配:
<!DOCTYPE html> <html> <head> <title>交互式图表</title> <!-- 引入Teams JS SDK,确保页面适配Teams容器 --> <script src="https://statics.teams.cdn.office.net/sdk/v1.16.0/js/MicrosoftTeams.min.js"></script> <!-- 引入Chart.js --> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> </head> <body> <canvas id="myChart" width="400" height="200"></canvas> <script> // 初始化Teams环境 microsoftTeams.initialize(); // 渲染交互式图表 const ctx = document.getElementById('myChart').getContext('2d'); const myChart = new Chart(ctx, { type: 'bar', data: { labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'], datasets: [{ label: '# of Votes', data: [12, 19, 3, 5, 2, 3], backgroundColor: [ 'rgba(255, 99, 132, 0.2)', 'rgba(54, 162, 235, 0.2)', 'rgba(255, 206, 86, 0.2)', 'rgba(75, 192, 192, 0.2)', 'rgba(153, 102, 255, 0.2)', 'rgba(255, 159, 64, 0.2)' ], borderColor: [ 'rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)', 'rgba(75, 192, 192, 1)', 'rgba(153, 102, 255, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { responsive: true, // 添加图表点击交互逻辑 onClick: (e) => { const activePoints = myChart.getElementsAtEventForMode(e, 'nearest', { intersect: true }, true); if (activePoints.length > 0) { const index = activePoints[0].index; const label = myChart.data.labels[index]; const value = myChart.data.datasets[0].data[index]; // 可选:将点击数据传回Bot microsoftTeams.tasks.submitTask({label, value}); } } } }); </script> </body> </html>
2. 配置Teams应用清单
在manifest.json中添加图表页面的域名到validDomains,确保Teams允许加载该页面:
{ "validDomains": [ "your-chart-domain.com", "ngrok.io" // 调试时用ngrok生成的域名 ] }
3. 发送带任务模块按钮的自适应卡片
用Bot Framework SDK构造自适应卡片,添加触发任务模块的按钮:
// C#示例 var adaptiveCard = new AdaptiveCard(new AdaptiveSchemaVersion(1, 0)) { Body = new List<AdaptiveElement> { new AdaptiveTextBlock { Text = "点击查看交互式图表", Size = AdaptiveTextSize.Large } }, Actions = new List<AdaptiveAction> { new AdaptiveSubmitAction { Title = "打开图表", Data = new { msteams = new { type = "task/fetch", data = new { chartId = "sales-data" } // 可选:向任务模块传递自定义数据 } } } } }; var attachment = new Attachment { ContentType = AdaptiveCard.ContentType, Content = adaptiveCard }; await turnContext.SendActivityAsync(MessageFactory.Attachment(attachment), cancellationToken);
4. 处理Bot的任务模块请求
用户点击按钮后,Bot会收到task/fetch类型的Invoke请求,需返回任务模块配置;若图表页面有数据回传,还需处理task/submit请求:
// C#示例:在OnTurnAsync中处理Invoke请求 if (turnContext.Activity.Type == ActivityTypes.Invoke) { var invokeActivity = turnContext.Activity.AsInvokeActivity(); // 处理任务模块打开请求 if (invokeActivity.Name == "task/fetch") { var taskModuleResponse = new TaskModuleResponse { Task = new TaskModuleContinueResponse { Type = "continue", Value = new TaskModuleTaskInfo { Title = "交互式图表", Url = "https://your-chart-domain.com/chart.html", // 图表页面的公网URL Width = 600, Height = 400 } } }; await turnContext.SendActivityAsync(JsonConvert.SerializeObject(taskModuleResponse), cancellationToken: cancellationToken); return; } // 处理任务模块回传的数据 else if (invokeActivity.Name == "task/submit") { var submittedData = JsonConvert.DeserializeObject<Dictionary<string, object>>(invokeActivity.Value.ToString()); await turnContext.SendActivityAsync($"你点击了:{submittedData["label"]},数值:{submittedData["value"]}", cancellationToken: cancellationToken); return; } }
关键注意事项
- 调试时必须用ngrok将本地页面代理到公网,否则Teams无法访问
- 页面必须引入Teams JS SDK,否则无法调用
submitTask等API,也无法适配Teams容器环境 - 任务模块的宽高需根据图表内容调整,避免滚动条影响交互体验
- 若需动态传递数据到图表页面,可在任务模块的URL中拼接参数,或通过Teams SDK的
getContext获取Bot传递的自定义数据
内容的提问来源于stack exchange,提问作者user9262680
相关产品推荐
相关产品推荐

