Reputation: 51
When testing with the emulator, the program does not wait for user input on the context.Wait nor when forwarding the dialog to another dialog.
My MessagesController fires a greet when a new user is connected:
if(activity.Type == ActivityTypes.ConversationUpdate)
{
if (activity.MembersAdded.Count == 1)
{
await Conversation.SendAsync(activity, () => new Dialogs.GreetDialog());
}
}
Then my Greet Dialog outputs "Hello" and forwards to GatherUserDialog:
public async Task StartAsync(IDialogContext context)
{
context.UserData.Clear();
context.Wait(GatherInfoAsync);
}
private async Task GatherInfoAsync(IDialogContext context, IAwaitable<object> args)
{
var activity = await args as Activity;
if (!(context.UserData.ContainsKey("askedname")))
{
await context.PostAsync("Hello!");
await context.Forward(new GatherUserDialog(), this.MessageReceivedAsync, activity);
}
}
My GatherUserDialog should prompt the user to enter a username and then connect to db and get user with said username:
Object person;
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("May I please have your username?");
context.UserData.SetValue("askedname", true);
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var activity = await result as Activity;
await result;
using (SoCoDirectoryModel model = new SoCoDirectoryModel())
{
var ents = model.Entities;
var text = activity.Text;
this.person = (from e in model.Entities
where e.EmployeeId == activity.Text
select e).SingleOrDefault();
}
if (this.person == null)
{
await context.PostAsync("Could not find that user. Please try again.");
context.Wait(MessageReceivedAsync);
}
else
{
this.person = person as Ent;
await context.PostAsync($"Hello {(this.person as Ent).FirstName}, what can I do for you?");
context.Wait(MessageReceivedAsync);
}
context.Wait(MessageReceivedAsync);
}
```
I am not sure what to put here, I didn't do anything special besides the code above and updating the NuGet packages to use the latest stable versions of packages.
Expected behavior should be a greeting followed by a prompt for a username, the username is then passed used to fetch the account info.
It seems that the emulator sends 2 posts on startup, state.getConversationData & state.getPrivateConversationData, both running simultaneously, and continuing through any waits that the bot should hold for input. Upon reaching the GatherUserDialog, the program fails to stop for user input and tries the linq code with an empty string. I believe this causes a timeout exception and "Sorry, my bot code is having an issue."
Apparently i cant post pictures, so here is a link to the picture of the chat: https://user-images.githubusercontent.com/18318261/42243397-0a373820-7ec6-11e8-99c4-5fefced6a06c.png
Upvotes: 2
Views: 317
Reputation: 8292
This is a known issue. ConversationUpdate is sent by the Direct Line connector when the bot connects to the conversation, and again when the user connects to the conversation. When the Direct Line connector sends ConversationUpdate, it does not send the correct User.Id, so the bot cannot construct the dialog stack. The emulator is behaving differently (It sends bot and user ConversationUpdate events immediately, and it DOES send the correct user.id.)
A workaround is to not use ConversationUpdate, and send an event from the client, then respond to that event with a dialog.
Client javascript:
var user = {
id: 'user-id',
name: 'user name'
};
var botConnection = new BotChat.DirectLine({
token: '[DirectLineSecretHere]',
user: user
});
BotChat.App({
user: user,
botConnection: botConnection,
bot: { id: 'bot-id', name: 'bot name' },
resize: 'detect'
}, document.getElementById("bot"));
botConnection
.postActivity({
from: user,
name: 'requestWelcomeDialog',
type: 'event',
value: ''
})
.subscribe(function (id) {
console.log('"trigger requestWelcomeDialog" sent');
});
Respond to the event:
if (activity.Type == ActivityTypes.Event)
{
var eventActivity = activity.AsEventActivity();
if (eventActivity.Name == "requestWelcomeDialog")
{
await Conversation.SendAsync(activity, () => new Dialogs.GreetDialog());
}
}
More information can be found here: https://github.com/Microsoft/BotBuilder/issues/4245#issuecomment-369311452
Update (blog post about this here): https://blog.botframework.com/2018/07/12/how-to-properly-send-a-greeting-message-and-common-issues-from-customers/
Upvotes: 2