问题描述
我有一个日期选择器自适应卡,可以在意向通话中调用它.我不知道如何获取用户输入的值并将其传递给我的机器人路易斯,在那里我将有一个意图被这些值触发
I have a date picker adaptive card which I call during an intent call.I am not getting as to how can I get value entered by the user and pass it to my bot luis where I will be having an intent which will get triggered with those values
我尝试解析自适应卡json,但是我希望在单击提交按钮时在其中输入用户输入的值来更新json.
I have tried parsing the adaptive card json but I want the updated json with user entered values in it on submit button click.
private Attachment CreateAdaptiveCardAttachment()
{
// combine path for cross platform support
string[] paths = { ".", "Cards", "AddingLeaveDetails.json" };
string fullPath = Path.Combine(paths);
var adaptiveCard = File.ReadAllText(fullPath);
return new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCard),
};
}
private Activity CreateResponse(IActivity activity, Attachment attachment)
{
var response = ((Activity)activity).CreateReply();
response.Attachments = new List<Attachment>() { attachmen`enter code here`t };
return response;
}
推荐答案
@NikhilBansal,您可以跳过此答案的瀑布对话框"部分(更多用于后代),然后转到捕获用户输入"部分.同样,阅读其他上下文"和其他资源"链接也可能会有所帮助.
@NikhilBansal, You can skip the "Waterfall Dialog" part of this answer (it's more for posterity), and head to the "Capture User Input" section. It will likely be helpful to read the "Additional Context" and "Additional Resources" links, as well.
从本质上讲,自适应卡不能像提示一样工作.带有提示,提示将显示并等待用户输入,然后继续.但是对于自适应卡(即使它包含一个输入框和一个提交按钮),自适应卡中也没有代码,这会使瀑布对话框在继续对话框之前先等待用户输入.
Natively, Adaptive Cards don't work like prompts. With a prompt, the prompt will display and wait for user input before continuing. But with Adaptive Cards (even if it contains an input box and a submit button), there is no code in an Adaptive Card that will cause a Waterfall Dialog to wait for user input before continuing the dialog.
因此,如果您使用的是接受用户输入的自适应卡,则通常要处理用户在瀑布对话框"上下文之外提交的所有内容.
So, if you're using an Adaptive Card that takes user input, you generally want to handle whatever the user submits outside of the context of a Waterfall Dialog.
话虽如此,如果您想在瀑布对话框中使用自适应卡,则有一种解决方法.基本上,您:
That being said, if you want to use an Adaptive Card as part of a Waterfall Dialog, there is a workaround. Basically, you:
- 显示自适应卡
- 显示文字提示
- 将用户的自适应卡输入转换为文本提示输入
在瀑布对话框"类中(步骤1和2):
In your Waterfall Dialog class (steps 1 and 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();
}
捕获用户输入
在您的主要bot类(<your-bot>.cs
)中的OnTurnAsync()
下,靠近方法开头的位置,在await dialogContext.ContinueDialogAsync(cancellationToken)
之前的某个位置(步骤3):
In your main bot class (<your-bot>.cs
), under OnTurnAsync()
, near the beginning of the method, somewhere before await dialogContext.ContinueDialogAsync(cancellationToken)
is called (step 3):
var activity = turnContext.Activity;
if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value != null)
{
activity.Text = JsonConvert.SerializeObject(activity.Value);
}
更新:具体来说,对于您的代码,您需要直接修改turnContext
,然后再将其发送到识别器.由于RecognizeAsync
不适用于对象,因此我们需要确保发送适当的值.像这样:
Update: For your code, specifically, you need to directly modify turnContext
before sending it to your recognizer. Since RecognizeAsync
doesn't work with objects, we need to ensure we send the appropriate value. Something like:
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
// Capture input from adaptive card
if (string.IsNullOrEmpty(turnContext.Activity.Text) && turnContext.Activity.Value != null)
{
// Conditionally convert based off of input ID of Adaptive Card
if ((turnContext.Activity.Value as JObject)["<adaptiveCardInputId>"] != null)
{
turnContext.Activity.Text = (turnContext.Activity.Value as JObject)["<adaptiveCardInputId>"].ToString();
}
}
// First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
var recognizerResult = await _botServices.Dispatch.RecognizeAsync(turnContext, cancellationToken);
// Top intent tell us which cognitive service to use.
var topIntent = recognizerResult.GetTopScoringIntent();
// Next, we call the dispatcher with the top intent.
await DispatchToTopIntentAsync(turnContext, topIntent.intent, recognizerResult, cancellationToken);
}
上面两个代码块不起作用的原因仅仅是因为没有为您的代码设置代码. RecognizeAsync
查看turnContext.Activity.Text
,对于自适应卡,该字段为null(因为自适应卡输入来自Activity.Value
.因此,此新代码将turnContext.Activity.Text
设置为turnContext.Activity.Value
.但是,要将其发送到识别器,您需要将其作为字符串而不是对象,因此请确保将<adaptiveCardInputId>
更改为自适应卡上的ID.
The reason the code two blocks above didn't work is just because it wasn't set up for your code. RecognizeAsync
looks at turnContext.Activity.Text
, which is null for an adaptive card (since adaptive card inputs come in Activity.Value
. So, this new code sets turnContext.Activity.Text
to turnContext.Activity.Value
. However, to send it to the recognizer, you need it to be a string and not an object, so be sure to change <adaptiveCardInputId>
to whatever ID you have on your adaptive card.
自适应卡发送的提交"结果与常规用户文本略有不同.当用户键入聊天并发送普通消息时,它最终以Context.Activity.Text
结尾.当用户填写自适应卡上的输入时,它会以Context.Activity.Value
结尾,该对象的键名是卡中的id
,值是自适应卡中的字段值.
Adaptive Cards send their Submit results a little different than regular user text. When a user types in the chat and sends a normal message, it ends up in Context.Activity.Text
. When a user fills out an input on an Adaptive Card, it ends up in Context.Activity.Value
, which is an object where the key names are the id
in your card and the values are the field values in the adaptive card.
例如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"
}
..创建一张看起来像这样的卡片:
.. creates a card that looks like:
如果用户在文本框中输入"Testing Testing 123",然后单击Submit,则Context.Activity
将类似于:
If a user enters "Testing Testing 123" in the text box and hits Submit, Context.Activity
will look something like:
{ 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
中看到用户提交的内容.
The user submission can be seen in Context.Activity.Value.userText
.
请注意,自适应卡的提交是作为postBack发送的,这意味着提交数据不会作为对话的一部分出现在聊天窗口中,而是保留在自适应卡上.
Note that adaptive card submissions are sent as a postBack, which means that the submission data doesn't appear in the chat window as part of the conversation--it stays on the Adaptive Card.
- 博客文章使用自适应卡的说明
-
AdaptiveCardPrompt
-有一天可能会添加到SDK中.同时,您可以将其用作开发参考
这篇关于如何检索用户在自适应卡中输入的C#代码输入,以及如何调用“提交"按钮上的下一个意图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!