简体   繁体   English

在 Microsoft Bot Framework v4 中处理自适应卡片 - Nodejs

[英]Handling Adaptive cards in Microsoft Bot Framework v4 - Nodejs

  return new Promise((resolve, reject) => {
                            x = context.sendActivity({
                            text: 'hi',
                             attachments: [CardFactory.adaptiveCard(menuJson)]
                            })

I am trying to send an adaptive card, which contains a Input.text field in it...Now my question is how to get the input data from the user in my program using a context object ?我正在尝试发送一个自适应卡,其中包含一个 Input.text 字段......现在我的问题是如何使用上下文对象从我的程序中的用户获取输入数据?

ie How to Handle adaptive cards in bot framework v4 using node js ?即如何使用 node js 在 bot framework v4 中处理自适应卡?

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 .当用户输入聊天内容并发送一条普通消息时,它最终会出现在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 menuJson and the values are the field values in the adaptive card.当用户在自适应卡片上填写输入时,它最终会出现在context.activity.value ,这是一个对象,其中键名是menuJson中的id ,值是自适应卡片中的字段值。

For example, the json:例如,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: .. 创建一张如下所示的卡片:

测试自适应卡

If a user enters "Testing Testing 123" in the text box and hits Submit, context.activity will look something like:如果用户在文本框中输入“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' }

The user submission can be seen in context.activity.value.userText .用户提交可以在context.activity.value.userText看到。

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.请注意,自适应卡片提交作为回发发送,这意味着提交数据不会作为对话的一部分出现在聊天窗口中——它保留在自适应卡片上。

Using Adaptive Cards with Waterfall Dialogs瀑布对话框中使用自适应卡片

Your question doesn't quite relate to this, but since you may end up attempting this, I thought it might be important to include in my answer.您的问题与此不太相关,但由于您最终可能会尝试这样做,因此我认为将其包含在我的答案中可能很重要。

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. Display the Adaptive Card显示自适应卡片
  2. Display a Text Prompt显示文本提示
  3. Convert the user's Adaptive Card input into the input of a Text Prompt将用户的 Adaptive Card 输入转换为 Text Prompt 的输入

In your Waterfall Dialog file (steps 1 and 2):在您的瀑布对话框文件中(步骤 1 和 2):

async displayCard(step) {
    // Display the Adaptive Card
    await step.context.sendActivity({
        text: 'Adaptive Card',
        attachments: [yourAdaptiveCard],
});
    // Display a Text Prompt
    return await step.prompt('textPrompt', 'waiting for user input...');
}

async handleResponse(step) {
    // Do something with step.result
    // Adaptive Card submissions are objects, so you likely need to JSON.parse(step.result)
    ...
    return await step.next();

In your bot.ts file (step 3):在您的bot.ts文件中(第 3 步):

const activity = dc.context.activity;

if (!activity.text && activity.value) {
    activity.text = JSON.stringify(activity.value);
}

I'm using Adaptive Card in a ComponentDialog with WaterfallDialog, I want to handle Input.submit action.我在带有 WaterfallDialog 的 ComponentDialog 中使用 Adaptive Card,我想处理 Input.submit 操作。

My problem is: How to handle the response, get the input value, and go to next dialog step correctly?我的问题是:如何处理响应、获取输入值并正确转到下一个对话步骤?

I try 2 ways to resolve my problem.我尝试了 2 种方法来解决我的问题。

My adaptive card's json like:我的自适应卡的 json 像:

{
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "type": "AdaptiveCard",
    "version": "1.0",
    "body": [
        {
            "type": "TextBlock",
            "text": "Create Schedule",
            "size": "large",
            "weight": "bolder"
        },
        {
            "type": "TextBlock",
            "text": "Name",
            "size": "small"
        },
        {
            "type": "Input.Text",
            "id": "name"
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Save",
            "data": {
                "result": "save"
            }
        },
        {
            "type": "Action.Submit",
            "title": "Cancel",
            "data": {
                "result": "cancel"
            }
        }
    ] 
}

1. Using prompt and prompt validate 1.使用提示和提示验证

This way uses prompt validate function to handle Input.submit postback action.这种方式使用提示验证功能来处理 Input.submit 回发操作。

Because postback action doesn't send a text message (not show in channel), that makes TextPrompt's default validate can't pass (send retryPrompt), so I write a prompt validate function and validate response is postback action.因为postback action不发送短信(不显示在channel中),这使得TextPrompt的默认validate无法通过(发送retryPrompt),所以我写了一个提示validate函数,validate响应是postback action。

class MyDialog extends ComponentDialog{
    constructor(dialogId) {
        // ...
        this.addDialog(new TextPrompt('textPropmt', this.promptValidator);
        this.addDialog(new WaterfallDailog(dialogId, [
            // dialog steps
            async function(step){
                await step.context.sendActivity({
                    attachments: [CardFactory.adaptiveCard(FormCard)]
                })
                await step.prompt('TextPrompt', 'waiting for your submit.')
            },

            async function(step){
                await step.context.sendActivity('get response.');

                // get adaptive card input value
                const resultValue = step.context.activity.value; 

                return await step.endDialog();
            }
        ]));
    }

    // prompt validate function
    async promptValidator(promptContext){
        const activity = promptContext.context.activity;
        return activity.type === 'message' && activity.channelData.postback;
    }

    // ..
}

2. Using Dialog.EndOfTurn 2. 使用 Dialog.EndOfTurn

This way uses Dialog.EndOfTurn to end turn.这种方式使用 Dialog.EndOfTurn 来结束转弯。 If user sends any response, the bot will go to next dialog step.如果用户发送任何响应,机器人将进入下一个对话步骤。

Please remember to check if the response is adaptive card submit action (postback), if not, do something to reject it or retry.请记住检查响应是否为自适应卡片提交操作(回发),如果不是,请执行某些操作以拒绝它或重试。

class MyDialog extends ComponentDialog{
    constructor(dialogId) {
        // ...

        this.addDialog(new WaterfallDialog(dialogId, [
            // dialog steps
            async function(step) {
                await step.context.sendActivity({
                    attachments: [CardFactory.adaptiveCard(FormCard)]
                });

                return Dialog.EndOfTurn;
            },

            async function(step) {
                await step.context.sendActivity('get response.');
                const activity = step.context.activity;

                if (activity.channelData.postback) {
                    // get adaptive card input value
                    const resultValue = activity.value;
                } else {
                    await step.context.sendActivity("Sorry, I don't understand.");
                }

                return await step.endDialog();
            }
        ]));
    }
    // ...
}

In the end, I would choose the second way (Dialog.EndOfTurn) to solve the problem, because I think it is easier to control the dialog step and handle user interrupt, for example, when user wants to cancel this action and return to main dialog.最后,我会选择第二种方式(Dialog.EndOfTurn)来解决这个问题,因为我认为控制对话步骤和处理用户中断更容易,例如当用户想要取消这个动作并返回到main时对话。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Microsoft Bot Framework v4 for NodeJS中处理HeroCards响应 - Handling HeroCards responses In Microsoft Bot Framework v4 for NodeJS 自适应卡上的 Action.Submit 不会调用下一步(仅在 Microsoft Teams 中有效,在 web 聊天中有效):Bot Framework V4 - Action.Submit on Adaptive cards is not calling the next step (not working only in Microsoft Teams works in web chat) : Bot Framework V4 在回调中使用await(Microsoft Bot Framework v4 nodejs) - use await inside callback (Microsoft Bot Framework v4 nodejs) Adaptive Cards 和 Microsoft Bot Framework:仅允许“openUrl”操作? - Adaptive Cards and Microsoft Bot Framework: will only permit 'openUrl' action? 欢迎消息 Bot Framework v4 nodejs - Welcome message Bot Framework v4 nodejs Bot Framework V4 UniversalBot nodejs - Bot Framework V4 UniversalBot nodejs 更新已在 javascript 的 Bot Framework v4 中发布 Adaptive Card - Update already posted Adaptive Card in Bot Framework v4 in javascript Bot框架中用于自适应卡的HostConfig - HostConfig for adaptive cards in bot framework 在AWS Lambda 401上运行的Microsoft Bot Framework NodeJS V4未授权错误 - Microsoft Bot Framework NodeJS V4 running on AWS Lambda 401 unauthorized error Microsoft Bot Framework V4 Appinsights 相关信息? 如何使用 Nodejs 将其用于自定义指标和自定义事件? - Microsoft Bot Framework V4 Appinsights related information ? How to use it for custom metric and custom events using Nodejs?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM