1
votes

I am currently working on a LUIS bot that creates projects in VSTS. Right now you just write the name to the bot like "Create Projekt abcd" and it creates the project for you. I wanted to make it look better by adding Adaptive Cards for the input, but when I press the submit button it just says to the Bot Code has an error. I did some research and the problem seems that the LUIS bot does not know how to handle the object that is returned as a message.

Adaptive Card: `

using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using AdaptiveCards;
using AdaptiveCards.Rendering;
using AdaptiveCards.Rendering.Html;
using Microsoft.Bot.Builder.FormFlow;

namespace LuisBot.Dialogs
{
public class ProjektInputCard
{


    public static Attachment GetCard(String pName)
    {
        String projektname = pName;
        if (projektname.Equals("(Name not found)"))
        {
            projektname = "";
        }

        AdaptiveCard Card = new AdaptiveCard() 
        {
            Body = new List<AdaptiveElement>()
            {
                new AdaptiveContainer()
                {
                    Items = new List<AdaptiveElement>()
                    {
                        new AdaptiveTextBlock()
                        {
                            Text = "Projekterstellung",
                            Weight = AdaptiveTextWeight.Bolder,
                            Size = AdaptiveTextSize.Large
                        },
                        new AdaptiveTextBlock()
                        {
                            Text = "Projektname:",
                            Weight = AdaptiveTextWeight.Bolder,
                            Size = AdaptiveTextSize.Default
                        },
                        new AdaptiveTextInput()
                        {
                            Type = "Input.Text",
                            Id = "ID_projekt",
                            Value = projektname
                        },
                        new AdaptiveTextBlock()
                        {
                            Text = "Beschreibung:",
                            Weight = AdaptiveTextWeight.Bolder,
                            Size = AdaptiveTextSize.Default
                        },

                        new AdaptiveTextInput()
                        {
                            Type = "Input.Text",
                            Id = "ID_description",
                            Value = "",
                            IsMultiline = true
                        }
                    }


                }



            }


        };

        Card.Actions = new List<AdaptiveAction>()
        {
            new AdaptiveSubmitAction()
            {
                Type = "Action.Submit",
                Title = "Erstellen"
            }
        };

        Attachment Attach = new Attachment() 
        {
            ContentType = AdaptiveCard.ContentType,
            Content = Card
        };

        return Attach;
    }
}
}`

Methode that calls the Card: `

private async Task Test(IDialogContext context)
     {

        var createprompt = context.MakeMessage();
    createprompt.Attachments.Add(ProjektInputCard.GetCard(GetProjectName()));
        await context.PostAsync(createprompt);

        context.Wait(MessageReceivedAsync);
    }`

The MessageReceived Methode:

public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        var message = await result;
        InputValues data;
        if (message.Value != null)
        {
            // Got an Action Submit
            dynamic value = message.Value;
            string submitType = value.Type.ToString();
            if (value != null)
            {
                data = Newtonsoft.Json.JsonConvert.DeserializeObject<InputValues>(submitType);
                _projectname = data.Name;
                _description = data.Description;
                await this.ShowLuisResult(context);

            }

        }
    }
1

1 Answers

1
votes

Ceepert, Instead of trying to do this all in the same class (I think that's what I'm seeing in your code), what you want to do is separate you adaptive card parts and luis parts into separate dialogs. Your initial dialog would be a regular IDialog<> implementation.

Collect the data from your input, create a new message with the data from the adaptive card as the Text property of the message and do call context.Forward to send the new message to your luis dialog. It's not clear from your code which input from the AdaptiveCard is going to be used by Luis to determine the user's intent so I've assumed '_projectname' for my example

If there is additional data beyond the Text, you can pass it in as parameters to the Luis dialog constructor.

public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
    var message = await result;

    if (message.Value != null)
    {
        //reroute the user back to your card with an additional message to 
        //put response in the provided fields.
        return;
    }

    InputValues data;
    if (message.Value != null)
    {
        // Got an Action Submit
        dynamic value = message.Value;
        string submitType = value.Type.ToString();
        if (value != null)
        {
            data = Newtonsoft.Json.JsonConvert.DeserializeObject<InputValues>(submitType);
            _projectname = data.Name;
            _description = data.Description;

            IMessageActivity msg = Activity.CreateMessageActivity();
            msg.TextFormat = "text";
            msg.Text = _projectname;

            await context.Forward(new MyLuisDialog(), ResumeAfterLuisDialog, msg, CancellationToken.None);

        }

    }
}