将对话与机器人配合使用
Microsoft 使用自适应卡片和 Bot Framework 卡片上的按钮调用 (称为 TeamsJS v1.x) 中的任务模块的对话,这些按钮是 Microsoft 365 组的 hero、缩略图和连接器。 对话通常比多个对话步骤更好的用户体验。 跟踪机器人状态,并允许用户中断或取消序列。
有两种调用对话的方法:
- 新的调用消息
task/fetch
:使用invoke
Bot Framework 卡的卡片操作或Action.Submit
自适应卡片的卡片操作(带有task/fetch
),将从机器人动态提取基于 HTML 或自适应卡片的对话框。 - 深层链接 URL:使用对话的深层链接语法,可以分别使用 Bot Framework 卡片的
openUrl
卡片操作或Action.OpenUrl
自适应卡片的卡片操作。 使用深层链接 URL 时,对话 URL 或自适应卡片正文已已知,以避免相对于task/fetch
的服务器往返。
重要
每个 url
和 fallbackUrl
都必须实现 HTTPS 加密协议。
使用 调用对话框 task/fetch
当 invoke
卡片操作的 value
对象或 Action.Submit
已初始化,且当用户选择该按钮时,会向机器人发送一条 invoke
消息。 在对消息的 invoke
HTTP 响应中,包装器对象中嵌入了 一个 TaskInfo 对象 ,Teams 使用该对象在 TeamsJS v1.x) 中显示对话框 (称为任务模块。
警告
Microsoft的云服务(包括 Web 版本的 Teams、Outlook 和 Microsoft 365 域)正在迁移到域 *.cloud.microsoft
。 在 2024 年 9 月之前执行以下步骤,确保应用继续在受支持的 Microsoft 365 Web 客户端主机上呈现:
将 TeamsJS 库更新到 v.2.19.0 或更高版本。 有关最新版本的 TeamsJS 的详细信息,请参阅 Microsoft Teams JavaScript 客户端库。
如果已为应用定义了 内容安全策略 (CSP) 标头,请更新 frame-ancestors 指令以包含域
*.cloud.microsoft
。 为确保迁移过程中的向后兼容性,请保留 CSP 标头中的现有frame-ancestors
值。 此方法可确保应用继续跨现有和将来Microsoft 365 主机应用程序工作,并最大程度地减少后续更改的需求。
在应用的 CSP 标头的 指令中 frame-ancestors
更新以下域:
https://*.cloud.microsoft
以下步骤说明如何使用 调用 TeamsJS v1.x) task/fetch
中称为任务模块的对话 (:
此图显示了 Bot Framework 主卡,其中包含 “购买
invoke
卡片”操作。type
属性的值是task/fetch
,value
对象的其余部分可自行选择。机器人接收
invoke
HTTP POST 消息。机器人将创建答复对象,并使用 HTTP 200 答复代码在 POST 答复正文中将其返回。 有关响应架构的详细信息,请参阅 有关任务/提交的讨论。 以下代码提供了 HTTP 答复正文的示例,其中包含嵌入到包装器对象中的 TaskInfo 对象:
{ "task": { "type": "continue", "value": { "title": "Task module title", "height": 500, "width": "medium", "url": "https://contoso.com/msteams/taskmodules/newcustomer", "fallbackUrl": "https://contoso.com/msteams/taskmodules/newcustomer" } } }
机器人
task/fetch
的事件及其响应类似于microsoftTeams.tasks.startTask()
Microsoft Teams JavaScript 客户端库中 (TeamsJS) 中的函数。Microsoft Teams 显示对话框。
下一部分提供有关提交对话结果的详细信息。
提交对话框的结果
用户完成对话框后,将结果提交回机器人的方式与使用选项卡的方式类似。 有关详细信息,请参阅 提交对话框结果的示例。 存在一些差异,见如下所示:
- HTML 或 JavaScript,即
TaskInfo.url
:验证用户输入的内容后,出于可读性目的,调用microsoftTeams.tasks.submitTask()
下文中引用的submitTask()
函数。 如果希望 Teams 关闭对话框 (TeamsJS v1.x) 中称为任务模块,则无需任何参数即可调用submitTask()
,但必须将对象或字符串传递给 。submitHandler
将其作为第一个参数result
传递。 Teams 调用submitHandler
,err
是null
,result
是传递给submitTask()
的对象或字符串。 如果调用带result
参数的submitTask()
,则必须传递appId
或appId
字符串的数组。 此操作允许 Teams 验证发送结果的应用是否为调用对话框的相同应用。 机器人收到一条task/submit
消息,包括result
。 有关详细信息,请参阅task/fetch
和task/submit
消息的有效负载。 - 自适应卡片是
TaskInfo.card
:当用户选择任何Action.Submit
按钮时,用户填写的自适应卡片正文将通过task/submit
消息发送到机器人。
下一部分详细介绍了如何响应 task/submit
消息。
响应 task/submit
消息
当用户完成从机器人调用的对话 (TeamsJS v1.x 中称为任务模块) 时,机器人始终会收到一 task/submit invoke
条消息。 答复 task/submit
消息时有多个选项,见如下所示:
HTTP 正文答复 | 应用场景 |
---|---|
无人忽略 task/submit 消息 |
最简单的答复根本不是答复。 用户完成对话后,机器人无需做出响应。 |
{ |
Teams 显示弹出消息框中的 value 值。 |
{ |
允许在向导或多步骤体验中将自适应卡片序列链接到一起。 |
注意
将自适应卡片链接到序列中是一种高级应用场景。 Node.js 示例应用支持此操作。 有关详细信息,请参阅 Node.jsMicrosoft Teams 对话框 。
下节提供有关 task/fetch
和 task/submit
消息有效负载的详细信息。
和 task/submit
消息的有效task/fetch
负载
本节定义机器人收到 task/fetch
或 task/submit
Bot Framework Activity
对象时收到的内容架构。 下表提供了 task/fetch
和 task/submit
消息有效负载的属性:
属性 | 说明 |
---|---|
type |
始终为 invoke 。 |
name |
是 task/fetch 或 task/submit 。 |
value |
是开发人员定义的有效负载。
value 对象的结构与从 Teams 发送的结构相同。 但是,在这种情况下,情况会有所不同。 它需要支持动态提取,即从机器人框架 task/fetch ,也就是 value 和自适应卡片 Action.Submit 操作,即 data 。 除了 value 或 data 中包含的内容外,还需要一种 Teams context 与机器人通信的方法。将“值”和“数据”组合到父对象中: { |
下节提供在 Node.js 中接收和答复 task/fetch
和 task/submit
调用消息的示例。
以下选项卡在 Node.js 和 C# 中提供 task/fetch
并 task/submit
调用消息:
handleTeamsTaskModuleFetch(context, taskModuleRequest) {
// Called when the user selects an options from the displayed HeroCard or
// AdaptiveCard. The result is the action to perform.
const cardTaskFetchValue = taskModuleRequest.data.data;
var taskInfo = {}; // TaskModuleTaskInfo
if (cardTaskFetchValue === TaskModuleIds.YouTube) {
// Display the YouTube.html page
taskInfo.url = taskInfo.fallbackUrl = this.baseUrl + '/' + TaskModuleIds.YouTube + '.html';
this.setTaskInfo(taskInfo, TaskModuleUIConstants.YouTube);
} else if (cardTaskFetchValue === TaskModuleIds.CustomForm) {
// Display the CustomForm.html page, and post the form data back via
// handleTeamsTaskModuleSubmit.
taskInfo.url = taskInfo.fallbackUrl = this.baseUrl + '/' + TaskModuleIds.CustomForm + '.html';
this.setTaskInfo(taskInfo, TaskModuleUIConstants.CustomForm);
} else if (cardTaskFetchValue === TaskModuleIds.AdaptiveCard) {
// Display an AdaptiveCard to prompt user for text, and post it back via
// handleTeamsTaskModuleSubmit.
taskInfo.card = this.createAdaptiveCardAttachment();
this.setTaskInfo(taskInfo, TaskModuleUIConstants.AdaptiveCard);
}
return TaskModuleResponseFactory.toTaskModuleResponse(taskInfo);
}
async handleTeamsTaskModuleSubmit(context, taskModuleRequest) {
// Called when data is being returned from the selected option (see `handleTeamsTaskModuleFetch').
// Echo the users input back. In a production bot, this is where you'd add behavior in
// response to the input.
await context.sendActivity(MessageFactory.text('handleTeamsTaskModuleSubmit: ' + JSON.stringify(taskModuleRequest.data)));
// Return TaskModuleResponse
return {
// TaskModuleMessageResponse
task: {
type: 'message',
value: 'Thanks!'
}
};
}
setTaskInfo(taskInfo, uiSettings) {
taskInfo.height = uiSettings.height;
taskInfo.width = uiSettings.width;
taskInfo.title = uiSettings.title;
}
Bot Framework 卡片操作与自适应卡片操作。提交操作
Bot Framework 卡片操作的架构不同于自适应卡片 Action.Submit
操作,调用对话的方式也不同。 中的 data
Action.Submit
对象包含对象 msteams
,因此它不会干扰卡片中的其他属性。 下表显示了每个卡片操作的示例:
Bot Framework 卡片操作 | 自适应卡片 Action.Submit 操作 |
---|---|
{ |
{ |
代码示例
示例名称 | Description | .NET | Node.js | 清单 |
---|---|---|---|---|
对话示例 bots-V4 | 此示例演示如何使用 Bot Framework v4 和 Teams 选项卡创建对话框。 | View | View | View |
分步指南
按照 分步指南 在 Teams 中创建和提取对话机器人。