You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Task module提交触发时驱动Waterfall Dialog执行下一步

Teams 瀑布对话框接收Task Module提交并继续执行的实现方案

核心逻辑:task/submit属于Invoke类型活动,不会自动进入正在运行的瀑布对话框栈,需要手动将提交数据注入对话上下文,主动唤醒等待中的对话框流程。


前置依赖确认

  • Bot类中已注入持久化的ConversationState实例
  • 已基于对话状态创建DialogSet,所有业务对话框都注册在该DialogSet中
  • 对话框栈状态会在每轮活动处理完成后正确保存

分步实现

1. 调整弹出Task Module的瀑布步逻辑

在瀑布流第二步(弹出Task Module的步骤),不要在弹出卡片后直接调用NextAsync()让流程往下走,而是返回EndOfTurn让对话框保持在当前步骤等待后续事件。同时在步骤入口加判断,检测到Task Module提交数据时直接流转到下一步。

private async Task<DialogTurnResult> Step2_ShowTaskModuleAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    // 检测当前轮次是否携带Task Module提交数据
    if (stepContext.Context.TurnState.TryGetValue("TaskModulePayload", out var submitPayload))
    {
        // 携带提交数据,直接流转到下一个瀑布步
        return await stepContext.NextAsync(submitPayload, cancellationToken);
    }

    // 无提交数据,为首次进入步骤,构造Task Module弹出卡片
    var taskModuleInvoke = new TaskModuleAction("打开任务填写模块", new TaskModuleTaskInfo
    {
        Url = "你的任务模块前端页地址",
        Height = 550,
        Width = 650,
        Title = "信息填写"
    });
    var card = new HeroCard
    {
        Buttons = new List<CardAction> { taskModuleInvoke }
    }.ToAttachment();
    await stepContext.Context.SendActivityAsync(MessageFactory.Attachment(card), cancellationToken);

    // 关键:返回EndOfTurn,暂停瀑布流,保持当前步骤等待
    return Dialog.EndOfTurn;
}

2. 改造OnTeamsTaskModuleSubmitAsync事件处理

在接收到Task Module提交事件时,将提交数据存入当前轮次的TurnState,主动创建对话框上下文唤醒等待中的瀑布流,最后保存对话状态。

// 注意:_conversationState、_dialogSet为Bot构造函数中注入并全局保存的实例
protected override async Task<TaskModuleResponse> OnTeamsTaskModuleSubmitAsync(
   ITurnContext<IInvokeActivity> turnContext, 
   TaskModuleRequest taskModuleRequest, 
   CancellationToken cancellationToken
)
{
    // 将提交数据存入当前轮次状态,供瀑布步读取
    turnContext.TurnState.Add("TaskModulePayload", taskModuleRequest.Data);

    // 创建对话框上下文,关联当前对话的对话框栈
    var dialogContext = await _dialogSet.CreateContextAsync(turnContext, cancellationToken);
    
    // 触发对话框继续执行,唤醒等待中的瀑布步
    await dialogContext.ContinueDialogAsync(cancellationToken);
    
    // 必须保存对话状态,否则栈状态变更不会生效
    await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);

    // 可选:给用户发送提交成功提示
    await turnContext.SendActivityAsync(MessageFactory.Text("提交已接收,正在处理..."), cancellationToken);
       
    return TaskModuleResponseFactory.CreateResponse("提交成功");
}

3. 后续瀑布步接收提交数据

瀑布流第三步就可以直接通过stepContext.Result拿到Task Module的提交内容,执行后续业务逻辑:

private async Task<DialogTurnResult> Step3_ProcessSubmitAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    // 直接获取Task Module提交的结构化数据
    var formData = stepContext.Result;
    
    // 这里写后续业务逻辑:数据校验、存库、返回结果卡片等
    
    return await stepContext.NextAsync(cancellationToken);
}

常见问题排查

  • 瀑布流不继续:检查弹出Task Module的步骤是否错误返回了NextAsync(),导致流程提前跑完、对话框栈被清空;检查SaveChangesAsync是否正确调用
  • 拿不到提交数据:检查TurnState的Key是否一致,有没有在其他逻辑里覆盖了存入的载荷
  • 生产环境偶发失效:检查ConversationState是否用了持久化存储(如Cosmos DB、Blob Storage),内存存储仅适合本地调试,服务重启或多实例部署会丢状态

内容的提问来源于stack exchange,提问作者Snekithan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 16:37:00