首页 文章

带简历处理程序的延迟对话框

提问于
浏览 552
0

我有以下情况我认为我做错了 .

我有 RootDialog ,它叫 ResultDialog . ResultDialog 向用户显示结果列表(使用 HeroCard ) .

发布消息后,ResultDialog使用 context.Done(..) 自行关闭 .

在RootDialog- AfterResultDialog Resume处理程序中,我想询问用户是否找到了匹配结果,使用另一个对话框( NotificationDialog ),但我想在30秒后执行此操作 .

经过一些研究,这似乎必须使用主动消息来完成 . 这是example,我找到了一种主动发布 NotificationDialog 的方法 .

private async Task AfterResultDialog(IDialogContext context, IAwaitable<object> result)
{
    var message = await result as IMessageActivity;

    var conversationReference = context.Activity.ToConversationReference();
    ConversationStarter.conversationReference = JsonConvert.SerializeObject(conversationReference);

    t = new Timer(timerEvent);
    t.Change(30000, Timeout.Infinite);
    context.Wait<string>(NotificationDialogAfter);
}

public void timerEvent(object target)
{
    t.Dispose();
    ConversationStarter.Resume();
}

但我遇到的问题是我对这个 NotifcationDialog 的结果很感兴趣,知道用户下一步想做什么 . 但是我发现使用主动消息的所有示例都不会将主动消息的结果视为对话框:

public class ConversationStarter
{
    public static string conversationReference;

    public static async Task Resume()
    {
        var message = JsonConvert.DeserializeObject<ConversationReference>(conversationReference).GetPostToBotMessage();
        var client = new ConnectorClient(new Uri(message.ServiceUrl));
        using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
        {
            var botData = scope.Resolve<IBotData>();
            await botData.LoadAsync(CancellationToken.None);

            var task = scope.Resolve<IDialogTask>();

            // here it seems only to be possible to call a dialog using Void
            var dialog = new NotificationDialog();
            task.Call(dialog.Void<object, IMessageActivity>(), null);

            await task.PollAsync(CancellationToken.None);
            await botData.FlushAsync(CancellationToken.None);
        }
    }
}

NotificationDialogAfter 处理程序应根据用户输入决定下一个要调用的对话框:

private async Task NotificationDialogAfter(IDialogContext context, IAwaitable<string> result)
{
    var whereToContinue = await result;

    if (whereToContinue.Equals("Start over"))
    {
        context.ClearAllConversationDataKeys();
        context.Call(new TagDialog(), this.TagDialogAfter);
    }
    else if (whereToContinue == "Tell friends")
    {
        context.Call(new TellFriendsDialog(), TellFriendsDialogAfter);
    }
    else if (whereToContinue == "Feedback")
    {
        context.Call(new FeedbackDialog(), this.FeedbackDialogAfter);
    }
}

所以我基本上想要的是 NotificationDialog 的结果被转发到Root对话框正在等待的 NotificationDialogAfter 处理程序 . 这有可能吗?

1 回答

  • 0

    我通过定义静态继续处理程序(在 GlobalContinueHandler 中)来解决问题,我可以在调用其他对话框时在NotificationDialog中提供 .

    [Serializable]
    public class NotificationDialog : IDialog<string>
    {
        public Task StartAsync(IDialogContext context)
        {
            PromptDialog.Choice(context, Resume, new List<string> { "yes", "no" },
                "Found what you're looking for?");
            return Task.CompletedTask;
        }
    
        private async Task Resume(IDialogContext context, IAwaitable<string> result)
        {
            var message = await result;
            if (message == "yes")
            {
                context.Call(new SignupDialog(), GlobalContinueHandler.SignupDialogAfter);
            }
            else
            {
                context.Call(new FeedbackDialog(), GlobalContinueHandler.FeedbackDialogAfter);
            }
        }
    }
    

    我真的不喜欢这个解决方案,但现在它似乎工作 .

相关问题