通过机器人使用对话

在 TeamsJS v1.x 中调用对话框 (称为任务模块,) 使用自适应卡上的按钮从 TaskFetchAction Microsoft Teams 机器人中调用。 对话框通过为用户打开弹出窗口来提供集中的交互,使其成为复杂表单或多步骤工作流程的理想选择。

可通过两种方法调用对话框:

  • 新的调用消息 task/fetch:使用Action.Execute自适应卡task/fetch的卡操作 ,将从机器人中动态提取 HTML 或基于自适应卡的对话框。
  • 深层链接 URL:使用对话的深层链接语法,可以对Action.OpenUrl自适应卡使用卡片操作。 使用深层链接 URL,已知对话框 URL 或自适应卡正文可避免相对于 task/fetch的服务器往返。

重要

每个 url 和 fallbackUrl 都必须实现 HTTPS 加密协议。

注意

在 Teams 客户端 v1 中,对话框被称为任务模块。 它们有时可能被当作同义词使用。

创建对话框启动器

若要从机器人调用对话,请发送带有按钮的 TaskFetchAction 自适应卡。 每个按钮都包含机器人用于确定要返回的对话框内容的数据。

警告

Microsoft 的云服务(包括 Teams 的 Web 版本、Outlook 和 Microsoft 365 域)正在迁移到该 *.cloud.microsoft 域。 请尽快执行以下步骤,以确保应用继续在受支持的 Microsoft 365 Web 客户端主机上呈现:

  1. 将 TeamsJS 库更新到 v.2.19.0 或更高版本。 必须致电 microsoftTeams.app.initialize() 以避免在新域中看到警告。 有关最新版本 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. 此图显示了具有购买Action.Execute卡操作的自适应卡。 type 属性的值是 task/fetch,data 对象的其余部分可自行选择。

  2. 机器人接收活动 card.action 。 在 Teams SDK 中,可以使用处理程序对 OnAdaptiveCardAction 此进行处理。 有关详细信息,请参阅 执行操作。

  3. 机器人创建一个 ActionResponse 对象并返回它。 有关响应架构的详细信息,请参阅 有关任务/提交的讨论。 以下代码提供了一个响应正文的示例,其中包含包装器对象中嵌入的 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() TeamsJS) (Microsoft Teams JavaScript 客户端库中的函数。

  4. Microsoft Teams 将显示该对话框。

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

提交对话框的结果

当用户完成对话框时,结果将提交回您的应用。 提交的工作方式取决于对话框内容类型:

  • TaskInfo (自适应卡。卡) :当用户选择Action.Submit按钮时,Teams 会向应用发送对话框提交事件。 对话框提交处理程序从卡接收窗体数据。 在 C# 中,使用以下 [TaskSubmit] 属性: 在 TypeScript 中,使用 app.on('dialog.submit', ...). 在 Python 中,使用 @app.on_dialog_submit.
  • 网页 (TaskInfo.url) :网页从 TeamsJS 客户端库调用 microsoftTeams.tasks.submitTask(formData) ,这会在应用中触发相同的对话框提交事件。

处理对话框提交事件

当用户提交对话时,机器人会收到一条 task/submit 调用消息。 响应时有多个选项:

响应类型 应用场景
无响应 最简单的答复根本不是答复。 当用户完成对话框时,机器人不需要响应。
MessageTask Teams 会在对话框中的弹出消息框中显示一条消息。
ContinueTask 允许在向导或多步骤体验中将自适应卡片序列链接到一起。

以下选项卡演示如何在 .NET、TypeScript 和 Python 中处理对话框提交事件:

using System.Text.Json;
using Microsoft.Teams.Apps;
using Microsoft.Teams.Apps.TaskModules;

teams.OnTaskSubmit(async (context, cancellationToken) =>
{
  var data = context.Activity.Value?.Data as JsonElement?;
    if (data == null)
    {
    return TaskModuleResponse.CreateBuilder()
      .WithType(TaskModuleResponseTypes.Message)
      .WithMessage("No data found in the activity value")
      .Build();
    }

    var submissionType = data.Value.TryGetProperty("submissiondialogtype", out var submissionTypeObj) && submissionTypeObj.ValueKind == JsonValueKind.String
        ? submissionTypeObj.ToString()
        : null;

    string? GetFormValue(string key)
    {
        if (data.Value.TryGetProperty(key, out var val))
        {
            if (val is JsonElement element)
                return element.GetString();
            return val.ToString();
        }
        return null;
    }

    switch (submissionType)
    {
        case "simple_form":
            var name = GetFormValue("name") ?? "Unknown";
            await context.SendAsync($"Hi {name}, thanks for submitting the form!", cancellationToken);
            return TaskModuleResponse.CreateBuilder()
              .WithType(TaskModuleResponseTypes.Message)
              .WithMessage("Form was submitted")
              .Build();
        default:
            return TaskModuleResponse.CreateBuilder()
              .WithType(TaskModuleResponseTypes.Message)
              .WithMessage("Unknown submission type")
              .Build();
    }
      });

多步骤对话框链接

可以通过从提交处理程序返回 ContinueTask 响应来将自适应卡链接到多步骤向导中。 每个步骤返回一个新卡,最后一步返回 a MessageTask 以关闭对话框。

using System.Text.Json;
using Microsoft.Teams.Apps;
using Microsoft.Teams.Apps.Schema;
using Microsoft.Teams.Apps.TaskModules;
using Microsoft.Teams.Cards;

// Add these cases to your OnTaskSubmit method
case "webpage_dialog_step_1":
    var nameStep1 = GetFormValue("name") ?? "Unknown";
    var nextStepCardJson = $$"""
    {
        "type": "AdaptiveCard",
        "version": "1.4",
        "body": [
            {
                "type": "TextBlock",
                "text": "Email",
                "size": "Large",
                "weight": "Bolder"
            },
            {
                "type": "Input.Text",
                "id": "email",
                "label": "Email",
                "placeholder": "Enter your email",
                "isRequired": true
            }
        ],
        "actions": [
            {
                "type": "Action.Submit",
                "title": "Submit",
                "data": {"submissiondialogtype": "webpage_dialog_step_2", "name": "{{nameStep1}}"}
            }
        ]
    }
    """;

    var nextStepCard = JsonSerializer.Deserialize<AdaptiveCard>(nextStepCardJson)
        ?? throw new InvalidOperationException("Failed to deserialize next step card");

    TeamsAttachment nextStepAttachment = TeamsAttachment.CreateBuilder()
      .WithAdaptiveCard(JsonSerializer.SerializeToElement(nextStepCard))
      .Build();

    return TaskModuleResponse.CreateBuilder()
      .WithType(TaskModuleResponseTypes.Continue)
      .WithTitle($"Thanks {nameStep1} - Get Email")
      .WithCard(nextStepAttachment)
      .Build();

case "webpage_dialog_step_2":
    var nameStep2 = GetFormValue("name") ?? "Unknown";
    var emailStep2 = GetFormValue("email") ?? "No email";
    await context.SendAsync($"Hi {nameStep2}, thanks for submitting the form! We got that your email is {emailStep2}", cancellationToken);
    return TaskModuleResponse.CreateBuilder()
      .WithType(TaskModuleResponseTypes.Message)
      .WithMessage("Multi-step form completed successfully")
      .Build();

Bot Framework 卡片操作与自适应卡片操作。提交操作

Bot Framework 卡操作的架构不同于自适应卡Action.Submit操作,调用对话框的方式也不同。 data中的Action.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 清单 Python
对话框示例 bots-V4 此示例应用演示如何在 TeamsJS v1.x 中使用对话框 (称为任务模块,) 使用 Bot Framework v4。 View View 不适用 View

另请参阅