将对话与机器人配合使用

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的服务器往返。

重要

每个 urlfallbackUrl 都必须实现 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 客户端主机上呈现:

  1. 将 TeamsJS 库更新到 v.2.19.0 或更高版本。 有关最新版本的 TeamsJS 的详细信息,请参阅 Microsoft Teams JavaScript 客户端库

  2. 如果已为应用定义了 内容安全策略 (CSP) 标头,请更新 frame-ancestors 指令以包含域 *.cloud.microsoft 。 为确保迁移过程中的向后兼容性,请保留 CSP 标头中的现有 frame-ancestors 值。 此方法可确保应用继续跨现有和将来Microsoft 365 主机应用程序工作,并最大程度地减少后续更改的需求。

在应用的 CSP 标头的 指令中 frame-ancestors 更新以下域:

https://*.cloud.microsoft

任务/提取请求或答复

以下步骤说明如何使用 调用 TeamsJS v1.x) task/fetch中称为任务模块的对话 (:

  1. 此图显示了 Bot Framework 主卡,其中包含 “购买invoke卡片”操作type 属性的值是 task/fetchvalue 对象的其余部分可自行选择。

  2. 机器人接收 invoke HTTP POST 消息。

  3. 机器人将创建答复对象,并使用 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) 中的函数。

  4. Microsoft Teams 显示对话框。

下一部分提供有关提交对话结果的详细信息。

提交对话框的结果

用户完成对话框后,将结果提交回机器人的方式与使用选项卡的方式类似。 有关详细信息,请参阅 提交对话框结果的示例。 存在一些差异,见如下所示:

  • HTML 或 JavaScript,即 TaskInfo.url:验证用户输入的内容后,出于可读性目的,调用 microsoftTeams.tasks.submitTask() 下文中引用的 submitTask() 函数。 如果希望 Teams 关闭对话框 (TeamsJS v1.x) 中称为任务模块,则无需任何参数即可调用 submitTask() ,但必须将对象或字符串传递给 。submitHandler 将其作为第一个参数 result 传递。 Teams 调用 submitHandlererrnullresult 是传递给 submitTask() 的对象或字符串。 如果调用带 result 参数的 submitTask(),则必须传递 appIdappId 字符串的数组。 此操作允许 Teams 验证发送结果的应用是否为调用对话框的相同应用。 机器人收到一条 task/submit 消息,包括 result。 有关详细信息,请参阅 task/fetchtask/submit 消息的有效负载
  • 自适应卡片是 TaskInfo.card:当用户选择任何 Action.Submit 按钮时,用户填写的自适应卡片正文将通过 task/submit 消息发送到机器人。

下一部分详细介绍了如何响应 task/submit 消息。

响应 task/submit 消息

当用户完成从机器人调用的对话 (TeamsJS v1.x 中称为任务模块) 时,机器人始终会收到一 task/submit invoke 条消息。 答复 task/submit 消息时有多个选项,见如下所示:

HTTP 正文答复 应用场景
无人忽略 task/submit 消息 最简单的答复根本不是答复。 用户完成对话后,机器人无需做出响应。
{
“task”: {
“type”: “message”,
“value”:“消息文本”
}
}
Teams 显示弹出消息框中的 value 值。
{
“task”: {
“type”: “continue”,
“value”: <TaskInfo 对象>
}
}
允许在向导或多步骤体验中将自适应卡片序列链接到一起。

注意

将自适应卡片链接到序列中是一种高级应用场景。 Node.js 示例应用支持此操作。 有关详细信息,请参阅 Node.jsMicrosoft Teams 对话框

下节提供有关 task/fetchtask/submit 消息有效负载的详细信息。

task/submit 消息的有效task/fetch负载

本节定义机器人收到 task/fetchtask/submit Bot Framework Activity 对象时收到的内容架构。 下表提供了 task/fetchtask/submit 消息有效负载的属性:

属性 说明
type 始终为 invoke
name task/fetchtask/submit
value 是开发人员定义的有效负载。 value 对象的结构与从 Teams 发送的结构相同。 但是,在这种情况下,情况会有所不同。 它需要支持动态提取,即从机器人框架 task/fetch,也就是 value 和自适应卡片 Action.Submit 操作,即 data。 除了 valuedata 中包含的内容外,还需要一种 Teams context 与机器人通信的方法。

将“值”和“数据”组合到父对象中:

{
“context”: {
“theme”: “default” |“dark” |“contrast”,
},
“data”:[Bot Framework 卡片中的值字段] |[自适应卡片中的数据字段]
}

下节提供在 Node.js 中接收和答复 task/fetchtask/submit 调用消息的示例。

以下选项卡在 Node.js 和 C# 中提供 task/fetchtask/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 操作,调用对话的方式也不同。 中的 dataAction.Submit 对象包含对象 msteams ,因此它不会干扰卡片中的其他属性。 下表显示了每个卡片操作的示例:

Bot Framework 卡片操作 自适应卡片 Action.Submit 操作
{
“type”: “invoke”,
“title”: “Buy”,
“value”: {
“type”: “task/fetch”,
<...>
}
}
{
“type”: “Action.Submit”,
“id”: “btnBuy”,
“title”: “Buy”,
“data”: {
<...>,
“msteams”: {
“type”:“task/fetch”
}
}
}

代码示例

示例名称 Description .NET Node.js 清单
对话示例 bots-V4 此示例演示如何使用 Bot Framework v4 和 Teams 选项卡创建对话框。 View View View

分步指南

按照 分步指南 在 Teams 中创建和提取对话机器人。

另请参阅