2

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);
    }
Basil
  • 41
  • 7

3 Answers3

2

@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

Chaitanya N G
  • 504
  • 12
  • 29
1

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)

BeschtPlaier
  • 133
  • 13
  • thanks @BeschtPlaier the solution worked for me. Now the bot is starting with welcome message as desired. – Basil Jan 28 '20 at 08:00
  • Updating the vote only because the IFrame way is the recommended way. Given the proper way below. I apologize if my comment as hurt anyone knowingly or unknowingly. – Chaitanya N G Jan 28 '20 at 17:38
  • Why did my answer receive a downvote? Could the one pls explain? Because this answer has nothing to do with IFrames or something, this isn't related to the HTML file – BeschtPlaier Jan 29 '20 at 06:07
1

@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.

billoverton
  • 2,705
  • 2
  • 9
  • 32
  • Sure that this will work? As far as I know "OnMembersAddedAsync" only gets triggered when a USER is added, and the problem about Webchat is, that the USER gets added AFTER the first message, so the inside of the function shouldn't really matter – BeschtPlaier Jan 29 '20 at 05:54
  • See https://learn.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.activityhandler.onmembersaddedasync?view=botbuilder-dotnet-stable --> "Override this in a derived class to provide logic for **when members other than the bot join the conversation**, such as your bot's welcome logic." – BeschtPlaier Jan 29 '20 at 06:00
  • i needed to show my welcome message then continue the chat. the above answer was correct for me – Basil Jan 29 '20 at 11:55
  • I did modify your C# code instead of providing my nodejs code, but yes, I use that exact condition in all of my bots and I correctly receive the welcome message both in emulator and Azure-deployed channels. – billoverton Jan 29 '20 at 15:47
  • the === is giving me an error CS1525 Invalid expression term '=' – hkhan Oct 14 '20 at 20:11
  • 1
    @hkhan I'm coding in nodejs and tried to convert it to C#, so that may not be proper in that language as I'm not familiar with it. You may be able to use '==' with the same result. – billoverton Oct 14 '20 at 21:12
  • @billoverton i just changed it the class to OnConversationUpdateActivityAsync and it works well. – hkhan Oct 14 '20 at 21:40