我正在使用Bot Framework V4.3,我想检索自适应卡提交值 [英] I am using Bot framework V4.3, I want to retrieve adaptive card submit values

查看:50
本文介绍了我正在使用Bot Framework V4.3,我想检索自适应卡提交值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Bot框架V4.3,我一直在瀑布对话框中使用自适应卡来获取用户信息,我想在用户单击提交"按钮后获取值,并且我想返回上一步如果用户单击后退"按钮.

I'm using Bot framework V4.3, I have been using adaptive card in waterfall dialog, to get user information, I would want to get values once user clicks submit button and also I would like to go back to previous step if user click back button.

这是我的自适应卡的样子

Here is how my adaptive card looks like

我尝试了@mdrichardson在

I have tried the solution given by @mdrichardson in Stack Overflow But the adaptive card re-prompts again.

下面的代码帮助我们返回上一步,但如何将其实现到自适应卡的后退按钮上.

And the below code help us to go back to previous step but how to implement it to back button of adaptive card.

stepContext.ActiveDialog.State["stepIndex"] =(int)stepContext.ActiveDialog.State["stepIndex"] - 2;

将自适应卡添加到对话框. 我什至用TextPrompt代替ChoicePrompt

Adding adaptive card to dialog. I had even used TextPrompt instead of ChoicePrompt

AddDialog(new ChoicePrompt("AdaptiveCardPrompt") { Style = ListStyle.None });

这就是我显示自适应卡的方式.我的自适应卡为Json格式

This is how I'm displaying adaptive card. My adaptive card is in Json format

cardAttachment = CreateAdaptiveCardAttachment();

return await stepContext.PromptAsync("AdaptiveCardPrompt",
    new PromptOptions
    {
        Prompt = (Activity)MessageFactory.Attachment(new Attachment
        {
            ContentType = AdaptiveCard.ContentType,
            Content = cardAttachment.Content
        }),
    }, cancellationToken);

请帮助我解决此问题.预先谢谢你

Kindly help me in solving this issue. Thank you in advance

if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value != null)
{
    activity.Text = JsonConvert.SerializeObject(activity.Value);
}

编辑1 :@mdrichardson这是我设置对话框调用的方式

Edit 1: @mdrichardson Here is how I have setup the dialog call

        public static async Task Run(this Dialog dialog, ITurnContext turnContext,IStatePropertyAccessor<DialogState> accessor, CancellationToken cancellationToken = default(CancellationToken))
        {
            var dialogSet = new DialogSet(accessor);
            dialogSet.Add(dialog);

            var dialogContext = await dialogSet.CreateContextAsync(turnContext, cancellationToken);
            // Ensure that message is a postBack (like a submission from Adaptive Cards)
            if (dialogContext.Context.Activity.GetType().GetProperty("ChannelData") != null)
            {
                var channelData = JObject.Parse(dialogContext.Context.Activity.ChannelData.ToString());
                if (channelData.ContainsKey("postBack"))
                {
                    var postbackActivity = dialogContext.Context.Activity;
                    // Convert the user's Adaptive Card input into the input of a Text Prompt
                    // Must be sent as a string
                    postbackActivity.Text = postbackActivity.Value.ToString();
                    await dialogContext.Context.SendActivityAsync(postbackActivity);
                }
            }
            var results = await dialogContext.ContinueDialogAsync(cancellationToken);
            if (results.Status == DialogTurnStatus.Empty)
            {
                await dialogContext.BeginDialogAsync(dialog.Id, null, cancellationToken);
            }
        }

并且在OnTurnAsync方法中

 if (turnContext.Activity.Type == ActivityTypes.Message)
 {
      await Dialog.Run(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
 }

编辑2 :我修改了代码,然后可以转到下一个瀑布步骤.但是我在这里面临另一个问题. 下一个提示没有显示,但我可以在日志中看到它 这就是在模拟器中显示的方式

Edit 2 : I modified the code and I was able to go to next waterfall step. But I'm facing another issue here. Next prompt is not getting displayed but I can see it in Log This is how it shows in Emulator

仿真器视图

用户点击MoreInfoAsync方法中的按钮控件即可登陆

Once user clicks the button control lands in MoreInfoAsync method

 private async Task<DialogTurnResult> MoreInfoAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
 {
            var goback = JObject.Parse(stepContext.Result.ToString());
            stepContext.Values["AdaptiveCardDetails"] = stepContext.Result.ToString();

            if (goback.ContainsKey("goBack"))
            {
                return await stepContext.ReplaceDialogAsync(InitialDialogId);
            }
            // stepContext.ActiveDialog.State["stepIndex"] = (int)stepContext.ActiveDialog.State["stepIndex"] - 2;

            else
                return await stepContext.PromptAsync("MoreInfo", new PromptOptions { Prompt = MessageFactory.Text("Tell Me more.") }, cancellationToken);
 }

我想进入初始对话框,所以我正在使用ReplaceDialogAsync.

I would like to go to initial dialog so I'm using ReplaceDialogAsync.

MoreInfo对话框未显示在模拟器中,但显示在日志中

MoreInfo dialog is not displayed in emulator but its shown in log

编辑3 :这是瀑布台阶的完整代码

Edit 3: Here is the complete code of waterfall steps

          // This array defines how the Waterfall will execute.
                        var waterfallSteps = new WaterfallStep[]
                        {
                            ChoiceAsync,
                            CardAsync,
                            MoreInfoAsync,
                            ConfirmAsync
                        };
                        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
                        AddDialog(new ChoicePrompt("ChoiceType"));
                        AddDialog(new TextPrompt("AdaptiveCardPrompt"));
                        AddDialog(new TextPrompt("MoreInfo"));
                        InitialDialogId = nameof(WaterfallDialog);

            private async Task<DialogTurnResult> ChoiceAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {
                options = new PromptOptions()
                {
                    Prompt = MessageFactory.Text("Select the Choice"),
                    RetryPrompt = MessageFactory.Text("That was not a valid choice."),
                    Choices = GetChoices(),
                    Style = ListStyle.HeroCard
                };
                return await stepContext.PromptAsync("ChoiceType", options, cancellationToken);
            }


            private  async Task<DialogTurnResult> CardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {

                var cardAttachment = new Attachment();
                stepContext.Values["leaveType"] = stepContext.Result.ToString();
                cardAttachment = CreateAdaptiveCardAttachment();
                return await stepContext.PromptAsync("AdaptiveCardPrompt",
                new PromptOptions
                {
                     Prompt = (Activity)MessageFactory.Attachment(new Attachment
                     {
                         ContentType = AdaptiveCard.ContentType,
                         Content = cardAttachment.Content,
                     }),
                }, cancellationToken);
            }

            private async Task<DialogTurnResult> MoreInfoAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {
                var goback = JObject.Parse(stepContext.Result.ToString());
                stepContext.Values["AdaptiveCardDetails"] = stepContext.Result.ToString();

                if (goback.ContainsKey("goBack"))
                {
                    return await stepContext.ReplaceDialogAsync(InitialDialogId);
                }
                else return await stepContext.PromptAsync("MoreInfo", new PromptOptions { Prompt = MessageFactory.Text("Tell Me more.") }, cancellationToken);
            }

            private async Task<DialogTurnResult> ConfirmAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
            {
                stepContext.Values["MoreInfo"] = stepContext.Result;
                //As of now I wouldn't perform any task here so I'll end
                return await stepContext.EndDialogAsync();
            }

推荐答案

重新提示处理

问题出在您的OnTurnAsync()方法上

 if (turnContext.Activity.Type == ActivityTypes.Message)
 {
      await Dialog.Run(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
 }

每次用户发送消息时,都会导致运行对话框的新实例.由于自适应卡输入是作为回发消息(仍然是消息)发送的,因此它将导致对话框再次运行,从而再次提示用户.

Every time a user sends a message, it causes a new instance of your dialog to be run. Since Adaptive Card Input gets sent as a PostBack message (which is still a message), it causes the Dialog to run again, re-prompting the user.

如果要从OnTurnAsync()OnMessageAsync()运行对话框,则应该执行以下几项操作:

If you're going to run dialogs from OnTurnAsync() or OnMessageAsync(), there's a couple of different things you should do, either:

  1. 使用if/switch语句.例如,如果消息包含帮助",请运行帮助对话框",或者

  1. Use if/switch statements. For example, if the message contains "help", run the HelpDialog, or

启动一个对话框,该对话框保存用户响应并根据需要跳过步骤.您可以在 Core Bot的预订对话框.请注意,它如何在每个步骤中使用诸如bookingDetails.TravelDate = (string)stepContext.Result;之类的内容保存用户响应,并在提示诸如if (bookingDetails.TravelDate == null)之类的内容之前检查它是否存在于上一步中.对于您来说,您可以存储诸如userProfile.AdaptiveCardDetails之类的东西.

Start a dialog that saves user responses and skips steps as necessary. You can see an example of this in Core Bot's Booking Dialog. Notice how it's saving the user response in each step with something like bookingDetails.TravelDate = (string)stepContext.Result; and checks to see if it exists in the previous step before prompting with something like if (bookingDetails.TravelDate == null). For yours, you might store something like userProfile.AdaptiveCardDetails or something.

返回按钮

要使后退按钮正常工作,假设您的自适应卡中的后退按钮看起来像这样:

Back Button

To get the back button working, let's say it looks like this in your Adaptive Card:

{
    "type": "Action.Submit",
    "title": "Back",
    "data": {
        "goBack": "true",
    }
},

当用户单击返回"时,机器人将收到带有以下内容的活动:

When the user clicks "Back", the bot will receive an activity with:

由于用户想返回而您不需要数据,因此您可以执行以下操作:

Since the user wants to go back and you don't need the data, you could do something like:

var activity = turnContext.Activity;

if (string.IsNullOrWhiteSpace(activity.Text) && activity.Value.GetType().GetProperty("goBack"))
{
    dc.Context.Activity.Text = "Back";
}

,然后在对话"步骤中:

and then in your Dialog step:

if (stepContext.Result == "Back")
{
    stepContext.ActiveDialog.State["stepIndex"] = (int)stepContext.ActiveDialog.State["stepIndex"] - 2;
}

这篇关于我正在使用Bot Framework V4.3,我想检索自适应卡提交值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆