2
votes

I created my C# core chat bot in visual studio 2019 using SDK v4. The chat bot displays a hero card inorder to start the chat. It works fine in Bot emulator and azure portal but when implementing it into Web Chat using Iframe it doesn't show up the hero card.After passing a message it shows the hero card twice or if we pass the hero card button values then it goes with the flow. I don't know why this happens and i am a beginner in this domain and this is my first chat bot. Can anyone please help me to figure out the problem. Thanks in advance

code In DialogAndWelcome Bot.cs

namespace Welcome.Bots

public class DialogAndWelcomeBot<T> : DialogBot<T>
    where T : Dialog
{
    public DialogAndWelcomeBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger)
        : base(conversationState, userState, dialog, logger)
    {
    }

    protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
    {
        foreach (var member in membersAdded)
        {
            // Greet anyone that was not the target (recipient) of this message.
            // To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
            if (member.Id != turnContext.Activity.Recipient.Id)
            {
                var response = MessageFactory.Text("Hi , I’m Alexa. How could I help you");
                await turnContext.SendActivityAsync(response, cancellationToken);
                await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
            }
            await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
        }
    }
}

Code in DialogBot.cs

public DialogBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger)
        {
            ConversationState = conversationState;
            UserState = userState;
            Dialog = dialog;
            Logger = logger;
        }

    public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
    {
        await base.OnTurnAsync(turnContext, cancellationToken);

        // Save any state changes that might have occured during the turn.
        await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
        await UserState.SaveChangesAsync(turnContext, false, cancellationToken);
    }
3
Can you please post the relevant portions of your code? It will be a lot easier for someone to come up with suggestions if we can see what you have done.billoverton
Edited the question and reposted it.Basil

3 Answers

2
votes

@Basil: I understand from your query you are using Webchannel for your BOT and you are using IFrame. In other words if i am not wrong you have a html file where you have copy pasted the embedded code provided in azure portal inside the BOT app and replaced the placeholder in the embedded code with your BOT secret KEY. I.e something like below: https://webchat.botframework.com/embed/TestBotForOauthPrompt?s=<>' style='min-width: 400px; width: 100%; min-height: 500px;'>

Assuming my understanding is right here, i think the Iframe is a wrong way to do it, solely because it is not the Microsoft recommended way to do it for web channel rather you have to use the answer provided in below StackOverflow POSTS:

  1. [BotFramework]: Is there a way to Display Oauth prompt in hero card or Adaptive card in a BOT Developed using SDK V4 in C#?

I know the query in post does not talk about welcome message but it has a sentence in the answer --- Fix: Remove the iframe and just use the WebChat code. This isn't really documented anywhere, but the iFrame uses botchat, which is an older version of WebChat.

Since you are using SDK V4 IFrame should not be used rather the HTML provided in the answers for above post should be used.

Regarding your welcome message i guess you have to use a backchannel support for it to work for web channel which is already provided in the above post.

And Finally , if you want your webchannel Bot to work in all browsers then you have to take look into the below POST which answers the same:

  1. How to fix issue of HTML page for Web Chat Bot developed in C# using SDK V4 template is not opening in IE 11 browser?

Hope this helps and my above given understanding is correct.

All these answers were verified and working and provided by Support Engineers at Microsoft

Regards -ChaitanyaNG

1
votes

@BeschtPlaier's solution will work fine but I also wanted to provide a simpler alternative. You can just change the condition from member.id != turnContext.activity.recipient.id to member.id === turnContext.activity.recipient.id. So your onMembersAdded function would look like this:

    protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
    {
        foreach (var member in membersAdded)
        {
            // Greet anyone that was not the target (recipient) of this message.
            // To learn more about Adaptive Cards, see https://aka.ms/msbot-adaptivecards for more details.
            if (member.Id === turnContext.Activity.Recipient.Id)
            {
                var response = MessageFactory.Text("Hi , I’m Alexa. How could I help you");
                await turnContext.SendActivityAsync(response, cancellationToken);
                await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
            }
            await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
        }
    }

I use this method for all my bots and works fine, both in emulator and deployed to Azure. Personally I prefer this method since you don't have to worry about keeping track of the bot name.

1
votes

This is because of how "onMembersAdded" works. This event triggers as soon as a User is added to the Chat (Not when a Bot gets added). In Webchat / DirectLine a User gets added when the first Message is sent, so the Welcome Message gets shown AFTER the first message, and thats not how I suppose welcome messages to work.

You will need some workaround to get the welcome message get sent properly.

Not sure about the recommended way, but this is how I did it. (it works perfectly for me) Replace the onMembersAddedAsync with this:

protected override async Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken){

    if(turnContext.Activity.MembersAdded[0].Name == turnContext.Activity.Recipient.Name){       
var response = MessageFactory.Text("Hi , I’m Alexa. How could I help you");
                await turnContext.SendActivityAsync(response, cancellationToken);
                await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
        }
    }  

This will send the welcome Message everytime a ConversationUpdate pops up. (When a Bot gets added and when a User gets added) We want to send the Message when the Chat starts --> When the Bot is added. (User gets added AFTER the first message is send. (In Webchat/DirectLine).

Edit because of other Answers

To get only one message we need to check for the recipient,(always the bot) otherwise we will recive two welcome messages (one for the bot, one for the user)