Search code examples
c#botframeworkadaptive-cards

Pass result of a Adaptive card combo box to another method


I am using Adaptive card combo box to show some categories of products. Once the user clicks on the category that category should pass to another method and display all the products of that category in another adaptive card Combo Box and let user select a product.

Here is the code to get all category to combo box.

    public async Task GetCategoryAdaptiveCard(IDialogContext context)
    {
        var replyToConversation = context.MakeMessage();
        replyToConversation.Attachments = new List<Attachment>();

        HttpResponseMessage response = new HttpResponseMessage();
        string query = string.Format(APIChatBot + "/AllCategory");

        using (var client = ClientHelper.GetClient())
        {
            response = await client.GetAsync(query);
        }
        var categoryList = await response.Content.ReadAsAsync<IEnumerable<CategoryDTO>>();
        AdaptiveCard adaptiveCard = new AdaptiveCard();
        adaptiveCard.Speak = "Please Select A Category from the list";

        adaptiveCard.Body.Add(new TextBlock()
        {
            Text = "Please Select A Category from the list",
            Size = TextSize.Normal,
            Weight = TextWeight.Normal
        });

        adaptiveCard.Body.Add(new TextBlock()
        {
            Text = "Category List",
            Size = TextSize.Normal,
            Weight = TextWeight.Normal
        });

        List<AdaptiveCards.Choice> list = new List<AdaptiveCards.Choice>();

        foreach (var item in categoryList)
        {
            AdaptiveCards.Choice choice = new AdaptiveCards.Choice()
            {
                Title = item.CategoryName,
                Value = item.Id.ToString()
            };

            list.Add(choice);
        }
        adaptiveCard.Body.Add(new ChoiceSet()
        {
            Id = "Category",
            Style = ChoiceInputStyle.Compact,
            Choices = list
        });

        Attachment attachment = new Attachment()
        {
            ContentType = AdaptiveCard.ContentType,
            Content = adaptiveCard
        };

        replyToConversation.Attachments.Add(attachment);
        await context.PostAsync(replyToConversation);
    }

Here is the method i used to get the Product for the selected category.

   public async Task GetProductForCategory(IDialogContext context, string category)
    {
        var replyToConversation = context.MakeMessage();
        replyToConversation.Attachments = new List<Attachment>();

        HttpResponseMessage response = new HttpResponseMessage();
        string query = string.Format(APIChatBot + "/ProductByCategory/" + category);

        using (var client = ClientHelper.GetClient())
        {
            response = await client.GetAsync(query);
        }

        var productList = await response.Content.ReadAsAsync<IEnumerable<ProductDTO>>();

        if(productList .Count() == 0)
        {
            string message = "Sorry There Are No products For this Category" + category;
           await context.PostAsync(message);
        }
        else
        {
            List<AdaptiveCards.Choice> list = new List<AdaptiveCards.Choice>();

            foreach (var item in productList )
            {
                AdaptiveCards.Choice choice = new AdaptiveCards.Choice()
                {
                    Title = item.ProductName,
                    Value = item.Id.ToString()
                };

                list.Add(choice);
            }

            AdaptiveCard adaptiveCard = new AdaptiveCard();
            adaptiveCard.Body.Add(new TextBlock()
            {
                Text = "List of Products for the Category " + category,
                Size = TextSize.Normal,
                Weight = TextWeight.Normal
            });

            adaptiveCard.Body.Add(new TextBlock()
            {
                Text = "Please Select A Product From The List",
                Size = TextSize.Normal,
                Weight = TextWeight.Normal
            });

            adaptiveCard.Body.Add(new ChoiceSet()
            {
                Id = "ProductForCategory",
                Style = ChoiceInputStyle.Compact,
                Choices = list
            });

            Attachment attachment = new Attachment()
            {
                ContentType = AdaptiveCard.ContentType,
                Content = adaptiveCard
            };

            replyToConversation.Attachments.Add(attachment);
            await context.PostAsync(replyToConversation);
        }
    }

How can i pass the category selected by the user to the method that selects the product based on category?


Solution

  • If you create an adaptive card something like this:

    var reply = context.MakeMessage();
    var card = new AdaptiveCard();
    
    var choices = new List<Choice>();
    choices.Add(new Choice()
    {
        Title = "Category 1",
        Value = "c1"
    });
    choices.Add(new Choice()
    {
        Title = "Category 2",
        Value = "c2"                       
    });
    var choiceSet = new ChoiceSet()
    {
        IsMultiSelect = false,
        Choices = choices,
        Style = ChoiceInputStyle.Compact,
        Id = "Category"
    };
    card.Body.Add(choiceSet);
    card.Actions.Add(new SubmitAction() { Title = "Select Category", Data = Newtonsoft.Json.Linq.JObject.FromObject(new { button = "select" }) });
    
    reply.Attachments.Add(new Attachment()
    {
        Content = card,
        ContentType = AdaptiveCard.ContentType, 
        Name = $"Card"
    });
    
    await context.PostAsync(reply);
    

    When the user selects one of the options, and clicks the button, the resulting activity's value will be a jobject you can deserialize and use to create a product specific adaptive card:

    class CategorySelection
    {
        public string Category { get; set; }
    }
    
    var activityValue = activity.Value as Newtonsoft.Json.Linq.JObject;
    if (activityValue != null)
    {
        var categorySelection = activityValue.ToObject<CategorySelection>();
        var category = categorySelection.Category;
        //query the database for products of this category type, 
        //create another adaptive card displaying the products and send to user
    
        await context.PostAsync(reply);
    }