2

Is there a proper way for bot to start a conversation with PromptDialog.Choice in the Direct Line channel?

I am trying an ugly hack with catching the fist ConversationUpdate activity and creating a fake message from user to initialize the dialog like this:

IMessageActivity greetingMessage = Activity.CreateMessageActivity(); greetingMessage.From = message.Recipient;//from bot greetingMessage.Recipient = userAccount;//to user greetingMessage.Conversation = message.Conversation; greetingMessage.Text = "Hello, I am a bot"; greetingMessage.Locale = "en-us"; greetingMessage.Id = Guid.NewGuid().ToString(); await connector.Conversations.SendToConversationAsync((Activity)greetingMessage); IMessageActivity dialogEntryMessage = Activity.CreateMessageActivity(); dialogEntryMessage.Recipient = message.Recipient;//to bot dialogEntryMessage.From = message.From;//from user dialogEntryMessage.Conversation = message.Conversation; dialogEntryMessage.Text = "any text"; dialogEntryMessage.Locale = "en-us"; dialogEntryMessage.ChannelId = message.ChannelId; dialogEntryMessage.ServiceUrl = message.ServiceUrl; dialogEntryMessage.Id = Guid.NewGuid().ToString(); dialogEntryMessage.ReplyToId = greetingMessage.Id; await Conversation.SendAsync(dialogEntryMessage, () => new Dialogs.RootDialog()); 

Where message is a ConversationUpdate message from. In the RootDialog I start with a PromptDialog.Choice.

It works in the emulator, but in Direct Line channel bot doesn't remember the dialog state and when user choose one of dialog options and send his first real message, root dialog starts again from the PromptDialog.Choice, so it appears twice.

Update

I found a relevant blogpost from Microsoft: https://blog.botframework.com/2018/07/12/how-to-properly-send-a-greeting-message-and-common-issues-from-customers/

2
  • in Direct Line channel bot doesn't remember the dialog state and when user choose one of dialog options and send his first real message, root dialog starts again from the PromptDialog.Choice, so it appears twice. Do you enabled Direct Line channel and embed chat bot in your website? Or built a Direct Line client app? Commented Aug 6, 2018 at 5:31
  • It is embedded to a web page. I am using a fork of a BotFramework WebChat that has some UI customizations github.com/Microsoft/BotFramework-WebChat Commented Aug 6, 2018 at 7:14

1 Answer 1

2

in Direct Line channel bot doesn't remember the dialog state and when user choose one of dialog options and send his first real message, root dialog starts again from the PromptDialog.Choice, so it appears twice.

I can reproduce same issue on my side, and I find that ConversationUpdate handler will be executed when both bot and user is added to the conversation.

To solve the issue, you can refer to the following code sample.

In MessagesController:

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 if (update.MembersAdded != null && update.MembersAdded.Any()) { foreach (var newMember in update.MembersAdded) { if (newMember.Name == "{your_botid_here}") { IMessageActivity greetingMessage = Activity.CreateMessageActivity(); //... //your code logic //... IMessageActivity dialogEntryMessage = Activity.CreateMessageActivity(); dialogEntryMessage.Recipient = message.Recipient;//to bot dialogEntryMessage.From = message.From;//from user dialogEntryMessage.Conversation = message.Conversation; dialogEntryMessage.Text = "show choices"; dialogEntryMessage.Locale = "en-us"; dialogEntryMessage.ChannelId = message.ChannelId; dialogEntryMessage.ServiceUrl = message.ServiceUrl; dialogEntryMessage.Id = System.Guid.NewGuid().ToString(); dialogEntryMessage.ReplyToId = greetingMessage.Id; await Conversation.SendAsync(dialogEntryMessage, () => new Dialogs.RootDialog()); } } } } 

In RootDialog:

private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result) { var activity = await result as Activity; var mes = activity.Text.ToLower(); string[] choices = new string[] { "choice 1", "choice 2" }; if (Array.IndexOf(choices, mes) > -1) { await context.PostAsync($"You selected {mes}"); } else if(mes == "show choices") { PromptDialog.Choice(context, resumeAfterPrompt, choices, "please choose an option."); } else { await context.PostAsync($"You sent {activity.Text} which was {length} characters."); context.Wait(MessageReceivedAsync); } } private async Task resumeAfterPrompt(IDialogContext context, IAwaitable<string> result) { string choice = await result; await context.PostAsync($"You selected {choice}"); } 

Test result:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the reply. Checking the MembersAdded didn't help, but I used the idea of checking the message text in the RootDialog to determine the behavior. Now it works.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.