使用自适应卡片和 Bot Framework 卡片上的按钮(即用于) Microsoft 365 组的 hero、缩略图和连接器)从 Microsoft Teams 机器人调用 (称为 TeamsJS v1.x 中的任务模块的对话。 对话通常比多个对话步骤更好的用户体验。 跟踪机器人状态,并允许用户中断或取消序列。
有两种调用对话的方法:
- 新的调用消息task/fetch:使用invokeBot Framework 卡的 卡作或Action.Submit自适应卡片的卡作,以及task/fetch从机器人动态提取基于 HTML 或自适应卡片的对话。
- 深层链接 URL:使用对话的深层链接语法,可以分别使用 openUrlBot Framework 卡的卡作或自适应卡片的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 。 请尽快执行以下步骤,确保应用继续在受支持的 Microsoft 365 Web 客户端主机上呈现:
- 将 TeamsJS 库更新到 v.2.19.0 或更高版本。 必须调用 - microsoftTeams.app.initialize()以避免在新域中看到警告。 有关最新版本的 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 hero 卡,其中包含“购买 - invoke卡”作。- type属性的值是- task/fetch,- value对象的其余部分可自行选择。
- 机器人接收 - invokeHTTP 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中包含的内容外,还需要一种 Teamscontext与机器人通信的方法。将“值”和“数据”组合到父对象中: { | 
下节提供在 Node.js 中接收和答复 task/fetch 和 task/submit 调用消息的示例。
以下选项卡在 .NET、Node.js 和 task/submit python 中提供task/fetch并调用消息:
protected override Task<TaskModuleResponse> OnTeamsTaskModuleFetchAsync(ITurnContext<IInvokeActivity> turnContext, TaskModuleRequest taskModuleRequest, CancellationToken cancellationToken)
{
    var asJobject = JObject.FromObject(taskModuleRequest.Data);
    var value = asJobject.ToObject<CardTaskFetchValue<string>>()?.Data;
    var taskInfo = new TaskModuleTaskInfo();
    switch (value)
    {
        case TaskModuleIds.YouTube:
            taskInfo.Url = taskInfo.FallbackUrl = _baseUrl + "/" + TaskModuleIds.YouTube;
            SetTaskInfo(taskInfo, TaskModuleUIConstants.YouTube);
            break;
        case TaskModuleIds.CustomForm:
            taskInfo.Url = taskInfo.FallbackUrl = _baseUrl + "/" + TaskModuleIds.CustomForm;
            SetTaskInfo(taskInfo, TaskModuleUIConstants.CustomForm);
            break;
        case TaskModuleIds.AdaptiveCard:
            taskInfo.Card = CreateAdaptiveCardAttachment();
            SetTaskInfo(taskInfo, TaskModuleUIConstants.AdaptiveCard);
            break;
        default:
            break;
    }
    return Task.FromResult(taskInfo.ToTaskModuleResponse());
}
protected override async Task<TaskModuleResponse> OnTeamsTaskModuleSubmitAsync(ITurnContext<IInvokeActivity> turnContext, TaskModuleRequest taskModuleRequest, CancellationToken cancellationToken)
{
    var reply = MessageFactory.Text("OnTeamsTaskModuleSubmitAsync Value: " + JsonConvert.SerializeObject(taskModuleRequest));
    await turnContext.SendActivityAsync(reply, cancellationToken);
    return TaskModuleResponseFactory.CreateResponse("Thanks!");
}
private static void SetTaskInfo(TaskModuleTaskInfo taskInfo, UISettings uIConstants)
{
    taskInfo.Height = uIConstants.Height;
    taskInfo.Width = uIConstants.Width;
    taskInfo.Title = uIConstants.Title.ToString();
}
Bot Framework 卡片操作与自适应卡片操作。提交操作
Bot Framework 卡作的架构不同于自适应卡片Action.Submit作,调用对话的方式也不同。 中的 dataAction.Submit 对象包含一个 msteams 对象,因此它不会干扰卡中的其他属性。 下表显示了每个卡片操作的示例:
| Bot Framework 卡片操作 | 自适应卡片 Action.Submit 操作 | 
|---|---|
| { | { | 
代码示例
| 示例名称 | Description | .NET | Node.js | 清单 | 
|---|---|---|---|---|
| 对话示例 bots-V4 | 此示例应用演示如何使用 Bot Framework v4 在 TeamsJS v1.x) 中使用对话框 (称为任务模块。 | View | View | View |