首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在后续瀑布步骤中检索自适应卡片的表单提交

如何在后续瀑布步骤中检索自适应卡片的表单提交
EN

Stack Overflow用户
提问于 2019-03-08 10:32:44
回答 2查看 3.7K关注 0票数 3

我正在使用Bot (Bot,V4),我得到了一个包含两个步骤的WaterfallDialog;第一步是捕获表单数据,第二步是处理表单数据。

第一步发送答复:

代码语言:javascript
复制
private async Task<DialogTurnResult> CaptureFormStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    var reply = await stepContext.Context.Activity.GetReplyFromCardAsync("BusinessyForm");
    await stepContext.Context.SendActivityAsync(reply, cancellationToken);
}

GetReplyFromCardAsync是一种扩展方法,它使用带有自适应卡的Activity的JSON表示作为附加。自适应卡是一种类似于的形式。自适应卡还具有提交操作。

我的问题是,这些资料应如何传递至下一步?

在以前的尝试中,我返回了一个提示:

代码语言:javascript
复制
return await stepContext.PromptAsync(
    "custom-prompt-id", 
    new PromptOptions { Prompt = MessageFactory.Text("Hello!") }, 
    cancellationToken);

但在这种情况下,我不想提示用户提供更多信息。理想情况下,我希望为响应“保持”对话框状态,当检测到一个对话框状态时,下一步将处理提交结果。

我尝试过的事情:

  • 回顾了例子这里这里。这两种方法都显示了如何呈现卡片,而不是如何在后续步骤中处理输入。
  • 检查输入这里的卡片架构文档。
  • 回顾了GitHub's AdaptiveCard repo 这里中类似问题的讨论。

这可行吗?任何帮助都将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-08 16:07:48

自适应卡发送的提交结果与普通用户文本略有不同。当用户键入聊天并发送正常消息时,它将以Context.Activity.Text结束。当用户在自适应卡上填写输入时,它将以Context.Activity.Value结束,它是一个对象,其中键名是卡中的id,值是自适应卡中的字段值。

例如,json:

代码语言:javascript
复制
{
    "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"
}

。。创建一个如下所示的卡片:

如果用户在文本框中输入“测试测试123”并点击Submit,Context.Activity将类似于:

代码语言:javascript
复制
{ 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发送的,这意味着提交数据不会作为对话的一部分出现在聊天窗口中--它停留在自适应卡上。

使用带有 瀑布对话的自适应卡

就本机而言,自适应卡不像提示符那样工作。使用提示符,提示符将在继续之前显示并等待用户输入。但是使用Adaptive (即使包含输入框和提交按钮),Adaptive中没有代码会导致瀑布对话框在继续对话框之前等待用户输入。

因此,如果您使用的是接受用户输入的Adaptive,您通常希望处理在瀑布对话框上下文之外用户提交的任何内容。

话虽如此,如果您想使用自适应卡作为瀑布对话框的一部分,有一个解决办法。基本上,你:

  1. 显示适配卡
  2. 显示文本提示符
  3. 将用户的自适应卡输入转换为文本提示的输入

在瀑布对话框类中(步骤1和2):

代码语言:javascript
复制
private async Task<DialogTurnResult> DisplayCardAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    // Create 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),
    };

    // Create the text prompt
    var opts = new PromptOptions
    {
        Prompt = new Activity
        {
            Attachments = new List<Attachment>() { cardAttachment },
            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):

代码语言:javascript
复制
var activity = turnContext.Activity;

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

Stack Overflow用户

发布于 2019-05-17 16:04:27

以下是nodejs版本:

您的bot.ts文件:

代码语言:javascript
复制
 this.onTurn(async (context, next) => {
  if (context.activity.type == ActivityTypes.Message) {
    // Ensure that message is a postBack (like a submission from Adaptive Cards)
    if (context.activity.channelData != null) {
      if (context.activity.channelData.postBack === true) {
        const postbackActivity = context.activity;
        // Convert the user's Adaptive Card input into the input of a Text Prompt
        // Must be sent as a string
        postbackActivity.text = JSON.stringify(postbackActivity.value);
        // context.activity.text = postbackActivity.value
        await context.sendActivity(postbackActivity);
      }
    }
  }
  await next();
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55061325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档