如何仅使用自适应卡来创建对话流?

时间:2018-07-20 15:43:58

标签: c# azure botframework adaptive-cards

我正在尝试使用自适应卡引导用户输入,以便用户在聊天机器人最终引用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);
        }
}

1 个答案:

答案 0 :(得分:0)

  

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

以下示例代码对我有用,您可以参考它来满足您的要求。

在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"
    }
  ]
}

测试结果:

enter image description here