Search code examples
c#asp.net-corebotframeworkazure-qna-maker

How to have a button visible as soon as chatbot starts


I have a bot framework chatbot which uses QnA Maker. The bot is primarily for product support FAQ type questions. I have built a series of follow on prompts which allow the user to navigate to different questions/answers via the buttons which appear.

Currently, you have to type a question such as "I have an issue" before you see the prompts, but I would (somehow) like the particular prompt pair ("Search by Issue Type" / "Search by Product Category" shown in red in the diagram below), to automatically appear as soon as the conversation starts, so that the user doesn't have to type anything to see the prompts.

Image shows question in chatbot which then leads to follow on prompts

I found a real-life example of a similar type of behaviour, in a microsoft bot , which can be accessed by clicking this link, and then clicking the "Chat with Sales" button which appears in the bottom right of the page.

In this real life microsoft example, the bot automatically comes up with a message and then a button which says "Start", which then takes the user down a series of prompts. I would be happy to have a "Start" button on my bot if it could then take my user into the prompt pair "Search by Issue Type" / "Search by Product Category":

Microsoft bot showing a START button

My bot (as it happens) has a "Hello and Welcome!" message (highlighted in purple in the first screenshot), which was implemented via c# in the bot code. [I'm not at all skilled in C# as it happens].

Can I achieve my objective just within QnAMaker ? or do I have to do something in the c# code to bring up prompt(s). If I do have to go down the c# route, any pointers would be great.


Solution

  • Let's begin with your questions

    "Can I achieve my objective just within QnAMaker ? or do I have to do something in the c# code to bring up prompt(s)?"

    No you cannot do it only within QnAMaker. You have to write your custom C# bot code.

    "If I do have to go down the c# route, any pointers would be great"

    As you might know bot conversation started from OnMembersAddedAsync method. so if you want to prompt a button card at the very begining of your conversation you could try something like below:

    Starting Point:

    protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
            {
                
    
                foreach (var member in membersAdded)
                {
                    if (member.Id != turnContext.Activity.Recipient.Id)
                    {
                        var productProactivePromptCardEvening = ProductAndCategoryPromptCard();
                        await turnContext.SendActivityAsync(productProactivePromptCardEvening);
    
                    }
                }
            }
    

    ProductAndCategoryPromptCard:

    public IMessageActivity ProductAndCategoryPromptCard()
            {
                try
                {
                    //Break in Segment
                    var productCategoryInfoCard = Activity.CreateMessageActivity();
                    //Bind to Card
                    var heroCard = new HeroCard
                    {
                        Title = "Try to search using the type of issue, or type of device",
                       
                        Images = new List<CardImage> { new CardImage("") },
                        Buttons = new List<CardAction> {
                            new CardAction(ActionTypes.ImBack, "Search By Issue Type", value: "SearchByIssueType") ,
                            new CardAction(ActionTypes.ImBack, "Search By Product Category", value: "SearchByProductCategory")
                        },
                    };
    
                    // Create the attachment.
                    var attachment = heroCard.ToAttachment();
    
                    productCategoryInfoCard.Attachments.Add(attachment);
                    productCategoryInfoCard.AttachmentLayout = AttachmentLayoutTypes.Carousel;
                    return timeInfoCard;
                }
                catch (Exception ex)
                {
                    throw new NotImplementedException(ex.Message, ex.InnerException);
                }
    
            }
    

    Output:

    enter image description here

    Hope this is what exactly you are loking for. For details project example you could have a look here. You can modify the project with this code.

    Hopefully it would fulfil your requirement accordingly