Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этой статье описывается, как вызывать и закрывать диалоговые окна (ранее известные как модули задач) с помощью пакета SDK (библиотека ИИ Teams). В пакете SDK для Teams диалоговые окна вызываются из действий адаптивной карточки с помощью TaskFetchAction событий открытия диалогового окна и отправки в классе App .
Регистрация на мероприятие зависит от языка:
-
TypeScript:
app.on('dialog.open', ...)иapp.on('dialog.submit', ...) -
C#:
teams.OnTaskFetch(...)иteams.OnTaskSubmit(...) -
Python:
@app.on_dialog_openи@app.on_dialog_submit
Содержимое диалогового окна может быть адаптивной карточкой или веб-страницей на основе URL-адреса.
Диалоговые окна также можно вызывать другими способами в зависимости от архитектуры приложения:
- Из вкладок с помощью клиентской библиотеки TeamsJS. См. статью "Использование диалоговых окон на вкладках".
- От ботов, использующих Bot Framework или диплинки. См. статью Использование диалоговых окон с ботами.
- С URL-адреса прямой ссылки. См. Прямая ссылка для открытия диалогового окна.
Инструкции по миграции из Bot Framework в Teams SDK см. в статье Миграция из BotBuilder.
В следующей таблице обобщено, как работают диалоговые окна в пакете SDK для Teams:
| Шаг | Диалоговое окно с адаптивной карточкой | Диалоговое окно с URL-адресом веб-страницы |
|---|---|---|
| Запуск диалогового окна | 1. Отправьте пользователю адаптивную карточку с TaskFetchAction кнопкой. Данные действия value определяют тип открываемого диалогового окна. 2. Когда пользователь нажимает кнопку, Teams отправляет вызов задачи в приложение. |
1. Отправьте пользователю адаптивную карточку с TaskFetchAction кнопкой. 2. Когда пользователь нажимает кнопку, Teams отправляет вызов задачи в приложение. |
| Обработка события открытия диалогового окна | 3. В обработчике открытия диалогового окна верните ответ модуля задач, содержащий метаданные диалогового окна (название, измерения и адаптивную карточку для отображения). В C# используйте TaskInfo с оболочкой ContinueTask . В TypeScript используйте CardTaskModuleTaskInfo. В Python используйте CardTaskModuleTaskInfo в TaskModuleContinueResponse. |
3. В обработчике открытия диалогового окна верните ответ модуля задачи, содержащий метаданные диалогового окна со свойством url , указывающим на веб-страницу. URL-домен должен находиться в массиве validDomains в манифесте приложения. В C# используйте TaskInfo. В TypeScript используйте UrlTaskModuleTaskInfo. В Python используйте UrlTaskModuleTaskInfo в TaskModuleContinueResponse. |
| Обработка отправки диалогового окна | 4. Когда пользователь нажимает Action.Submit кнопку, Teams отправляет вызов отправки задачи в ваше приложение с данными формы. 5. Вы можете ответить: • Ничего не делать (задача выполнена) • Отображение сообщения (C#: MessageTask, TypeScript/Python: TaskModuleMessageResponse) • Цепочка с другим диалоговым окном (C#: ContinueTask, TypeScript/Python: TaskModuleContinueResponse) |
4. Веб-страница вызывает клиентскую библиотеку JS Teams для отправки данных обратно. Teams отправляет вызов задачи в приложение с результатом. |
В следующем разделе описаны метаданные диалогового окна, определяющие содержимое и внешний вид диалогового окна.
Метаданные диалогового окна
Метаданные диалогового окна определяют содержимое и внешний вид диалогового окна. Каждый язык использует свои собственные типы для представления этих метаданных:
-
C#:
TaskInfo(сMicrosoft.Teams.Api.TaskModules) -
TypeScript:
CardTaskModuleTaskInfoилиUrlTaskModuleTaskInfo(от@microsoft/teams.api) -
Python:
CardTaskModuleTaskInfoилиUrlTaskModuleTaskInfo(сmicrosoft_teams.api)
В следующей таблице перечислены общие свойства для всех языков.
| Атрибут | Тип | Описание |
|---|---|---|
title |
string | Этот атрибут выводится под названием приложения, справа от его значка. |
height |
number или string | Этот атрибут может быть числом, представляющим высоту диалогового окна в пикселях, или small, medium, или large. В C# используйте Union<int, Size>. |
width |
number или string | Этот атрибут может быть числом, представляющим ширину диалогового окна в пикселях, или small, medium, или large. В C# используйте Union<int, Size>. |
url |
string | URL-адрес страницы, загруженной <iframe> в диалоговом окне. Домен URL-адреса должен находиться в массиве приложения validDomains в манифесте приложения. Используйте UrlTaskModuleTaskInfo в TypeScript/Python или установите свойство Url в TaskInfo C#. |
card |
Вложение | Адаптивная карточка для отображения в диалоговом окне. В C# задайте свойство Card с TaskInfo помощью Attachment. В TypeScript используйте cardAttachment() с CardTaskModuleTaskInfo. В Python используйте card_attachment(AdaptiveCardAttachment(...)) с CardTaskModuleTaskInfo. |
Примечание.
Функция диалогового окна требует, чтобы домены всех URL-адресов, которые вы хотите загрузить, были включены в validDomains массив в манифесте вашего приложения.
В следующем разделе указаны размеры диалоговых окон, позволяющие пользователю задать высоту и ширину диалогового окна.
Изменение размеров диалогового окна
Значения диалогового width окна и height установка высоты и ширины в пикселях. В зависимости от размера окна Teams и разрешения экрана эти значения могут быть пропорционально уменьшены при сохранении пропорций.
Если width и height представляют собой small, mediumили large, размер красного прямоугольника на следующем изображении пропорционален размерам доступного пространства, а именно 20 %, 50 % и 60 % для width и 20 %, 50 % и 66 % для height:
В следующем разделе приводятся примеры запуска и обработки диалоговых окон с помощью пакета SDK для Teams.
Запуск диалогового окна с помощью TaskFetchAction
Чтобы открыть диалоговое окно, отправьте адаптивную карточку с кнопкой TaskFetchAction . Когда пользователь нажимает кнопку, Teams отправляет вызов задачи в ваше приложение. Данные value каждой кнопки определяют тип открываемого диалогового окна (например, { "data": "AdaptiveCard" }).
using System.Text.Json;
using Microsoft.Teams.Apps;
using Microsoft.Teams.Apps.Schema;
using Microsoft.Teams.Cards;
teams.OnMessage(async (context, cancellationToken) =>
{
var card = new AdaptiveCard
{
Body = new List<CardElement>
{
new TextBlock("Task Module Invocation from Adaptive Card")
{
Weight = TextWeight.Bolder,
Size = TextSize.Large
}
},
Actions = new List<Action>
{
new TaskFetchAction(new Dictionary<string, object?> { { "data", "AdaptiveCard" } })
{ Title = "Adaptive Card" },
new TaskFetchAction(new Dictionary<string, object?> { { "data", "CustomForm" } })
{ Title = "Custom Form" },
new TaskFetchAction(new Dictionary<string, object?> { { "data", "MultiStep" } })
{ Title = "Multi-step Form" }
}
};
TeamsAttachment attachment = TeamsAttachment.CreateBuilder()
.WithAdaptiveCard(JsonSerializer.SerializeToElement(card))
.Build();
await context.SendAsync(new MessageActivityInput().AddAttachment(attachment), cancellationToken);
});
Обработка события открытия диалогового окна
Когда Teams отправляет вызов задачи, ваше приложение возвращает содержимое диалогового окна. Содержимое может быть адаптивной карточкой или URL-адресом веб-страницы. В C# оберните метаданные диалогового окна в ответ.ContinueTask В TypeScript верните a TaskModuleResponse с type: 'continue'помощью . В Python верните содержащий InvokeResponse .TaskModuleContinueResponse
using System.Text.Json;
using Microsoft.Teams.Apps;
using Microsoft.Teams.Apps.Schema;
using Microsoft.Teams.Apps.TaskModules;
using Microsoft.Teams.Cards;
teams.OnTaskFetch(async (context, cancellationToken) =>
{
await Task.CompletedTask;
// The button's Action.Submit payload arrives on the invoke value, nested under "data".
string? data = context.Activity.Value?.Data is JsonElement value
&& value.TryGetProperty("data", out JsonElement dataProp)
? dataProp.GetString()
: null;
if (data == "CustomForm")
{
return TaskModuleResponse.CreateBuilder()
.WithType(TaskModuleResponseTypes.Continue)
.WithTitle("Custom Form")
.WithWidth(510)
.WithHeight(450)
.WithUrl($"{botEndpoint}/customform")
.WithFallbackUrl($"{botEndpoint}/customform")
.Build();
}
if (data == "MultiStep")
{
var step1Card = new AdaptiveCard
{
Version = "1.5",
Body = new List<CardElement>
{
new TextBlock("Multi-step Form: Step 1") { Wrap = true },
new TextInput { Id = "name", Label = "Name" }
},
Actions = new List<Microsoft.Teams.Cards.Action>
{
new SubmitAction { Title = "Next" }
}
};
TeamsAttachment step1Attachment = TeamsAttachment.CreateBuilder()
.WithAdaptiveCard(JsonSerializer.SerializeToElement(step1Card))
.Build();
return TaskModuleResponse.CreateBuilder()
.WithType(TaskModuleResponseTypes.Continue)
.WithTitle("Multi-step Form")
.WithWidth(400)
.WithHeight(300)
.WithCard(step1Attachment)
.Build();
}
var dialogCard = new AdaptiveCard
{
Version = "1.5",
Body = new List<CardElement>
{
new TextInput { Id = "usertext", Label = "Enter text" }
},
Actions = new List<Microsoft.Teams.Cards.Action>
{
new SubmitAction { Title = "Submit" }
}
};
TeamsAttachment attachment = TeamsAttachment.CreateBuilder()
.WithAdaptiveCard(JsonSerializer.SerializeToElement(dialogCard))
.Build();
return TaskModuleResponse.CreateBuilder()
.WithType(TaskModuleResponseTypes.Continue)
.WithTitle("Adaptive Card: Inputs")
.WithWidth(400)
.WithHeight(200)
.WithCard(attachment)
.Build();
});
Обработка отправки диалогового окна
Когда пользователь нажимает Action.Submit в диалоговом окне, Teams отправляет вызов отправки задачи в ваше приложение. Вы можете ответить, выполнив задачу, отобразив сообщение или открыв другое диалоговое окно (например, чтобы связать многошаговые формы).
using System.Text.Json;
using Microsoft.Teams.Apps.TaskModules;
using Microsoft.Teams.Cards;
teams.OnTaskSubmit(async (context, cancellationToken) =>
{
var activity = context.Activity;
var json = JsonSerializer.Deserialize<JsonElement>(JsonSerializer.Serialize(activity));
var submitData = JsonSerializer.Deserialize<Dictionary<string, object>>(
json.GetProperty("value").GetProperty("data").GetRawText());
var submissionType = submitData?.GetValueOrDefault("submissiontype")?.ToString();
if (submissionType == "multi_step_1")
{
var name = submitData["name"]?.ToString();
var step2Card = new AdaptiveCard
{
Body = new List<CardElement>
{
new TextBlock("Step 2 of 2 - Your Email") { Size = TextSize.Large, Weight = TextWeight.Bolder },
new TextInput { Id = "email", Label = "Email", Placeholder = "Enter your email", IsRequired = true }
},
Actions = new List<Action>
{
new SubmitAction().WithTitle("Submit").WithData(
new Union<string, SubmitActionData>(new SubmitActionData
{
NonSchemaProperties = new Dictionary<string, object?>
{
{ "submissiontype", "multi_step_2" },
{ "name", name! }
}
}))
}
};
TeamsAttachment step2Attachment = TeamsAttachment.CreateBuilder()
.WithAdaptiveCard(JsonSerializer.SerializeToElement(step2Card))
.Build();
return TaskModuleResponse.CreateBuilder()
.WithType(TaskModuleResponseTypes.Continue)
.WithTitle("Multi-step Form: Step 2")
.WithWidth(400)
.WithHeight(300)
.WithCard(step2Attachment)
.Build();
}
if (submissionType == "multi_step_2")
{
await context.SendAsync($"Hi {submitData["name"]}, thanks for submitting! Your email is {submitData["email"]}", cancellationToken);
return TaskModuleResponse.CreateBuilder()
.WithType(TaskModuleResponseTypes.Message)
.WithMessage("Multi-step form completed!")
.Build();
}
var usertext = submitData?.GetValueOrDefault("usertext")?.ToString();
await context.SendAsync($"You submitted: {usertext}", cancellationToken);
return TaskModuleResponse.CreateBuilder()
.WithType(TaskModuleResponseTypes.Message)
.WithMessage("Thanks for submitting!")
.Build();
});
Рекомендации по использованию клавиатуры и специальных возможностей
Для диалоговых окон на основе URL-адресов, загружающих HTML-содержимое, обеспечьте специальные возможности клавиатуры:
- Используйте атрибут tabindex в тегах HTML для управления тем, на каких элементах можно сосредоточить внимание, и для определения последовательной навигации с помощью клавиатуры с помощью клавиш TAB и SHIFT-TAB .
- Правильно обработайте клавишу ESC в JavaScript для вашей диалоговой страницы.
Microsoft Teams обеспечивает правильную навигацию с помощью клавиатуры из заголовка диалогового окна в HTML и наоборот.
Пример кода
| Название примера | Описание | .NET | Node.js | Python |
|---|---|---|---|---|
| Модули задач бота | В этом примере приложения демонстрируется, как использовать диалоговые окна (называемые модулями задач в TeamsJS v1.x) с помощью пакета SDK для ИИ в Teams. | Просмотр | Просмотр | Просмотр |
Следующий этап
См. также
Platform Docs