I had created a bot with v3 (C#) SDK and the welcome message used to work just fine without any sweat. And it still does for me in production. The code is handled in HandleS
Typically, the channel sends two conversation update events when the conversation is initialized - one for the bot and another for the user. The second one - the event for the user - is intended to trigger the welcome message. Unlike some other channels, Web Chat waits to send the second conversation update event until after the user messages the bot. Evidently, the welcome message won't be sent until after the first message. To workaround this issue, developers can send a back channel welcome event to the bot when the DirectLine connection is established and send a welcome message from the onEventAsync handler instead of onMembersAdded. For more details, take a look at the code snippets below.
Bot Chat Code
<!DOCTYPE html>
<html>
<head>
<link href="https://cdn.botframework.com/botframework-webchat/0.11.4/botchat.css" rel="stylesheet" />
<style>
#webchat {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div style="display: flex">
<div style="position: relative; height: 500px; width: 500px"><div id="bot" ></div></div>
</div>
<script src="https://cdn.botframework.com/botframework-webchat/0.11.4/botchat.js"></script>
<script>
(async function() {
const res = await fetch('/directline/token', { method: 'POST' });
const { token } = await res.json();
var userinfo = {
id: 'user-id',
name: 'user name',
locale: 'es'
};
var botConnection = new window.BotChat.DirectLine({ token });
botConnection.connectionStatus$
.subscribe(connectionStatus => {
switch(connectionStatus) {
case window.BotChat.ConnectionStatus.Online:
botConnection.postActivity({
from: { id: 'myUserId', name: 'myUserName' },
type: 'event',
name: 'webchat/join',
value: { locale: 'en-US' }
}).subscribe(
id => console.log("Posted welcome event, assigned ID ", id),
error => console.log("Error posting activity", error)
);
break;
}
});
BotChat.App({
botConnection: botConnection,
user: userinfo,
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
})().catch(err => console.log(err));
</script>
</body>
</html>
Bot Code - C#
protected override async Task OnEventActivityAsync(ITurnContext<IEventActivity> turnContext, CancellationToken cancellationToken)
{
if (turnContext.Activity.Name == "webchat/join") {
await turnContext.SendActivityAsync("Welcome Message!");
}
}
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
if (turnContext.Activity.ChannelId != "webchat" && turnContext.Activity.ChannelId != "directline") {
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync($"Hi there - {member.Name}. {WelcomeMessage}", cancellationToken: cancellationToken);
await turnContext.SendActivityAsync(InfoMessage, cancellationToken: cancellationToken);
await turnContext.SendActivityAsync(PatternMessage, cancellationToken: cancellationToken);
}
}
}
}
Screen Capture
Also note, Web Chat v0.11.4 is referred to as either Bot Chat or Web Chat v3. Sorry I got tripped up on that.
Hope this helps!
tdurnford's answer didn't work for me. I'm using a new v4 bot (no migration) and embedding iframe into Sharepoint. OnEventActivityAsync just doesn't trigger. I get a conversation update with my bot being a MembersAdded so I did this:
protected override async Task OnConversationUpdateActivityAsync(ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
await base.OnConversationUpdateActivityAsync(turnContext, cancellationToken);
if (turnContext.Activity.ChannelId == "webchat" && turnContext.Activity.MembersAdded?.FirstOrDefault(m => m?.Name == Configuration["BotName"]) != null)
{
await SendWelcomeMessageAsync(turnContext, cancellationToken);
}
}
BotName is "Bot" for local development and the app name for azure deployed apps. SendWelcomeMessage is my own method. Also as above, I added a check in OnMembersAddedAsync:
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
if (turnContext.Activity.ChannelId == "webchat" || turnContext.Activity.ChannelId == "directline")
return;
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)
{
await SendWelcomeMessageAsync(turnContext, cancellationToken);
}
}
}
In v4 of the Bot Framework SDK this functionality is handled by making your bot class inherit from the ActivityHandler class then overriding the OnMembersAddedAsync method.
How this looks in practice is:
...
public class MyBot : ActivityHandler
{
...
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.
if (member.Id != turnContext.Activity.Recipient.Id)
{
var welcomeMessage = "Hello and welcome!";
await turnContext.SendActivityAsync(welcomeMessage, cancellationToken);
}
}
}
...
}
There are examples of how to do this here, here, and here.
You may have to update the version of the Microsoft.Bot.Builder
package that you are using.