在 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 客户端主机上呈现:
将 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:
此图显示了具有购买
Action.Execute卡操作的自适应卡。type属性的值是task/fetch,data对象的其余部分可自行选择。机器人接收活动
card.action。 在 Teams SDK 中,可以使用处理程序对OnAdaptiveCardAction此进行处理。 有关详细信息,请参阅 执行操作。机器人创建一个
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 客户端库中的函数。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 操作 |
|---|---|
{ |
{ |
代码示例
| 示例名称 | Description | .NET | Node.js | 清单 | Python |
|---|---|---|---|---|---|
| 对话框示例 bots-V4 | 此示例应用演示如何在 TeamsJS v1.x 中使用对话框 (称为任务模块,) 使用 Bot Framework v4。 | View | View | 不适用 | View |