首页 > 解决方案 > 如何仅使用自适应卡片创建对话流?

问题描述

我正在尝试使用自适应卡片引导用户输入,以便用户在聊天机器人最终引用 Qna Maker 之前选择一些预定义的案例。我想从一张自适应卡中捕获用户选择以生成另一张自适应卡,但我不知道如何将多个自适应卡链接在一起。

在 C# 中使用来自 Azure 的 Web 应用程序机器人的问答基本代码。

我首先尝试通过根对话框执行此操作,方法是获取用户选择的内容,调用新对话框,然后打开新的自适应卡。但是,我不知道如何捕捉用户为第二张自适应卡选择的内容。

我目前正在尝试通过 MessagesController.cs 来完成它,但我无法弄清楚如何链接自适应卡。当用户第一次连接到机器人时,我创建了一张自适应卡,但是一旦我捕捉到用户在自适应卡上选择的内容,我不知道如何显示新卡然后从该自适应卡获取输入最后转到根对话框。

我捕获了作为 ActivityTypes.Message 发送的用户选择。我不知道要调用什么来发布新的自适应卡并将来自新自适应卡的输入用作 ActivityTypes.Message 直到最终到达某个用例时,它才会进入根对话框。如果有人可以帮助如何实现它,或者可能建议一种新的方法来实现它,因为我不确定我的方法是否是最好的方法,甚至可能,我将不胜感激。我曾尝试以 contososcubabot 实现为例,但我的知识并不足以理解它们是如何工作的。

public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
        {
            // check if activity is of type message
            if (activity.GetActivityType() == ActivityTypes.Message)
            {

                JToken valueToken = JObject.Parse(activity.Value.ToString());
                string actionValue = valueToken.SelectToken("property") != null ? valueToken.SelectToken("property").ToString() : string.Empty;

                var reply = activity.CreateReply();

                if (!string.IsNullOrEmpty(actionValue))
                {
                    switch (valueToken.SelectToken("property").ToString())
                    {
                        case "1":


                            string json = File.ReadAllText(HttpContext.Current.Request.MapPath("~\\AdaptiveCards\\card2.json"));
                            AdaptiveCards.AdaptiveCard card = JsonConvert.DeserializeObject<AdaptiveCards.AdaptiveCard>(json);

                            reply.Attachments.Add(new Attachment
                            {
                                ContentType = AdaptiveCard.ContentType,
                                Content = card
                            });

                            break;

                        default:

                            break;
                    }

                    //posts the new adaptive card to chat????


                }
                else
                {
                    await Conversation.SendAsync(activity, () => new RootDialog());
                }


            }
            else
            {
                await HandleSystemMessageAsync(activity);
            }
            return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
        }
}

标签: c#azurebotframeworkadaptive-cards

解决方案


我想从一张自适应卡中捕获用户选择以生成另一张自适应卡,但我不知道如何将多个自适应卡链接在一起。

以下示例代码适用于我,您可以参考它来实现您的要求。

在 RootDialog 中:

[Serializable]
public class RootDialog : IDialog<object>
{
    public Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);

        return Task.CompletedTask;
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var activity = await result as Activity;

        if (activity.Value != null)
        {
            JToken valueToken = JObject.Parse(activity.Value.ToString());
            string actionValue = valueToken.SelectToken("property") != null ? valueToken.SelectToken("property").ToString() : string.Empty;

            var reply = context.MakeMessage();
            string json = "";

            switch (actionValue)
            {
                case "1":
                    json = await GetCardText("card1");
                    break;
                case "2":
                    json = await GetCardText("card2");
                    break;
                case "3":
                    json = await GetCardText("card3");
                    break;
                default:
                    break;
            }

            AdaptiveCardParseResult cardParseResult = AdaptiveCard.FromJson(json);

            reply.Attachments.Add(new Attachment
            {
                ContentType = AdaptiveCard.ContentType,
                Content = cardParseResult.Card
            });

            await context.PostAsync(reply);
        }
        else
        {
            if (activity.Text.ToLower().Contains("card"))
            {
                var replyMessage = context.MakeMessage();

                var json = await GetCardText("maincard");

                AdaptiveCardParseResult cardParseResult = AdaptiveCard.FromJson(json);

                replyMessage.Attachments.Add(new Attachment()
                {
                    Content = cardParseResult.Card,
                    ContentType = AdaptiveCard.ContentType,
                    Name = "Card"
                });

                await context.PostAsync(replyMessage);
            }
            else
            {
                await context.PostAsync($"You sent {activity.Text}");
            }

        }

        context.Wait(MessageReceivedAsync);
    }

    public async Task<string> GetCardText(string cardName)
    {
        var path = System.Web.Hosting.HostingEnvironment.MapPath($"/AdaptiveCards/{cardName}.json");
        if (!File.Exists(path))
            return string.Empty;

        using (var f = File.OpenText(path))
        {
            return await f.ReadToEndAsync();
        }
    }
}

maincard.json

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "size": "large",
      "weight": "bolder",
      "text": "This is Adaptive Card"
    },
    {
      "type": "Input.ChoiceSet",
      "id": "property",
      "value": "1",
      "style": "compact",
      "isMultiSelect": false,
      "choices": [
        {
          "title": "Option 1",
          "value": "1"
        },
        {
          "title": "Option 2",
          "value": "2"
        },
        {
          "title": "option 3",
          "value": "3"
        }
      ]
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "Submit"
    }
  ]
}

card2.json

{
  "type": "AdaptiveCard",
  "version": "1.0",
  "body": [
    {
      "type": "TextBlock",
      "size": "large",
      "weight": "bolder",
      "text": "This is Card2"
    },
    {
      "type": "Input.Text",
      "id": "property",
      "placeholder": "Please enter value",
      "value": "2"
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "Submit"
    }
  ]
}

测试结果:

在此处输入图像描述


推荐阅读