Использование адаптивных карт с Диалоги водопада
Собственно, адаптивные карты не работают как подсказки.При появлении приглашения оно будет отображаться и ждать ввода пользователя, прежде чем продолжить.Но с адаптивными картами (даже если они содержат поле ввода и кнопку отправки), в адаптивной карте нет кода, который заставлял бы диалоговое окно «Водопад» ожидать ввода пользователя, прежде чем продолжить диалог.
Итак,если вы используете адаптивную карту, которая принимает пользовательский ввод, вы, как правило, хотите обрабатывать все, что пользователь отправляет вне контекста диалога водопада.
При этом, если вы хотите использовать адаптивную карту какчасть диалога водопада, есть обходной путь.По сути, вы:
- Отображение адаптивной карты
- Отображение текстовой подсказки
- Преобразование ввода адаптивной карты пользователя во ввод текстовой подсказки
В вашем классе Waterfall Dialog (шаги 1 и 2):
private async Task<DialogTurnResult> DisplayCardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Display the Adaptive Card
var cardPath = Path.Combine(".", "AdaptiveCard.json");
var cardJson = File.ReadAllText(cardPath);
var cardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(cardJson),
};
var message = MessageFactory.Text("");
message.Attachments = new List<Attachment>() { cardAttachment };
await stepContext.Context.SendActivityAsync(message, cancellationToken);
// Create the text prompt
var opts = new PromptOptions
{
Prompt = new Activity
{
Type = ActivityTypes.Message,
Text = "waiting for user input...", // You can comment this out if you don't want to display any text. Still works.
}
};
// Display a Text Prompt and wait for input
return await stepContext.PromptAsync(nameof(TextPrompt), opts);
}
private async Task<DialogTurnResult> HandleResponseAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Do something with step.result
// Adaptive Card submissions are objects, so you likely need to JObject.Parse(step.result)
await stepContext.Context.SendActivityAsync($"INPUT: {stepContext.Result}");
return await stepContext.NextAsync();
}
В вашем основном классе ботов (<your-bot>.cs
), под OnTurnAsync()
, около начала метода, где-топеред вызовом await dialogContext.ContinueDialogAsync(cancellationToken)
(шаг 3):
var activity = turnContext.Activity;
if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value != null)
{
activity.Text = JsonConvert.SerializeObject(activity.Value);
}
Дополнительный контекст
Адаптивные карты отправляют свои результаты отправки немного по-другому, чем текст обычного пользователя.Когда пользователь печатает в чате и отправляет обычное сообщение, оно заканчивается Context.Activity.Text
.Когда пользователь заполняет ввод на адаптивной карте, он заканчивается на Context.Activity.Value
, который является объектом, в котором имена ключей - id
на вашей карте, а значения - значения полей в адаптивной карте.
Например, json:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "Test Adaptive Card"
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"items": [
{
"type": "TextBlock",
"text": "Text:"
}
],
"width": 20
},
{
"type": "Column",
"items": [
{
"type": "Input.Text",
"id": "userText",
"placeholder": "Enter Some Text"
}
],
"width": 80
}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}
.. создает карту, которая выглядит следующим образом:
Если пользователь вводит «Testing Testing 123» в текстовое поле и нажимает «Отправить», Context.Activity
будет выглядеть примерно так:
{ type: 'message',
value: { userText: 'Testing Testing 123' },
from: { id: 'xxxxxxxx-05d4-478a-9daa-9b18c79bb66b', name: 'User' },
locale: '',
channelData: { postback: true },
channelId: 'emulator',
conversation: { id: 'xxxxxxxx-182b-11e9-be61-091ac0e3a4ac|livechat' },
id: 'xxxxxxxx-182b-11e9-ad8e-63b45e3ebfa7',
localTimestamp: 2019-01-14T18:39:21.000Z,
recipient: { id: '1', name: 'Bot', role: 'bot' },
timestamp: 2019-01-14T18:39:21.773Z,
serviceUrl: 'http://localhost:58453' }
Представление пользователя можно увидеть в Context.Activity.Value.userText
.
Обратите внимание, что отправка адаптивной карты отправляется как postBack, что означает, что данные отправки не отображаются в окне чата как часть разговора - они остаются на адаптивной карте.