Recently I've worked on some projects related to Bot Framework and enjoyed the functionalities which permit to automate actions in response to user interactions.
It is important to provide the user with a great experience: one "nice touch" can be achieved by providing a welcome message at the beginning of a new conversation.
The first solution I tried was triggering the welcome message in the ConversationUpdate activity:
private Activity HandleSystemMessage(Activity message) { if (message.Type == ActivityTypes.DeleteUserData) { // Implement user deletion here // If we handle user deletion, return a real message } else if (message.Type == ActivityTypes.ConversationUpdate) { // Handle conversation state changes, like members being added and removed // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info // Not available in all channels // Note: Add introduction here: ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl)); Activity reply = message.CreateReply("Hello from my simple Bot!"); connector.Conversations.ReplyToActivityAsync(reply); } else if (message.Type == ActivityTypes.ContactRelationUpdate) { // Handle add/remove from contact lists // Activity.From + Activity.Action represent what happened } else if (message.Type == ActivityTypes.Typing) { // Handle knowing tha the user is typing } else if (message.Type == ActivityTypes.Ping) { } return null; }
When I ran this, the message was presented twice in the Bot Framework Emulator:
After some investigation, I discovered that the ConversationUpdate activity is triggered both when the connection to the Bot is established and when a new user joins the conversation.
As explained on GitHub, the correct way to handle this case is by showing the welcome message only when a new user is added:
private Activity HandleSystemMessage(Activity message) { if (message.Type == ActivityTypes.DeleteUserData) { // Implement user deletion here // If we handle user deletion, return a real message } else if (message.Type == ActivityTypes.ConversationUpdate) { // Handle conversation state changes, like members being added and removed // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info // Not available in all channels // Note: Add introduction here: IConversationUpdateActivity update = message; var client = new ConnectorClient(new Uri(message.ServiceUrl), new MicrosoftAppCredentials()); if (update.MembersAdded != null && update.MembersAdded.Any()) { foreach (var newMember in update.MembersAdded) { if (newMember.Id != message.Recipient.Id) { var reply = message.CreateReply(); reply.Text = $"Welcome {newMember.Name}!"; client.Conversations.ReplyToActivityAsync(reply); } } } } else if (message.Type == ActivityTypes.ContactRelationUpdate) { // Handle add/remove from contact lists // Activity.From + Activity.Action represent what happened } else if (message.Type == ActivityTypes.Typing) { // Handle knowing tha the user is typing } else if (message.Type == ActivityTypes.Ping) { } return null; }
Using this approach the welcome message is displayed properly:
Happy coding!