首页 文章

使用MS BotFramework中的PromptDialog开始对话

提问于
浏览 443
2

机器人是否有正确的方法在直线通道中与 PromptDialog.Choice 开始对话?

我正在尝试一个丑陋的黑客攻击拳头 ConversationUpdate 活动并从用户创建一个假消息来初始化对话框,如下所示:

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());

message 是来自的 ConversationUpdate 消息 . 在RootDialog中,我以 PromptDialog.Choice 开头 .

它在模拟器中工作,但是在Direct Line通道bot中不记得对话框状态,当用户选择一个对话框选项并发送他的第一个真实消息时,root对话框会再次从 PromptDialog.Choice 开始,因此它会出现两次 .

Update

我找到了一个来自微软的相关博文:https://blog.botframework.com/2018/07/12/how-to-properly-send-a-greeting-message-and-common-issues-from-customers/

1 回答

  • 2

    在Direct Line通道bot中不记得对话框状态,当用户选择其中一个对话框选项并发送他的第一个真实消息时,root对话框将再次从PromptDialog.Choice启动,因此它会出现两次 .

    我可以在我身边重现同样的问题,并且我发现当机器人和用户都被添加到对话中时将执行 ConversationUpdate 处理程序 .

    要解决此问题,可以参考以下代码示例 .

    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

相关问题