Bot Framework v4单点登录时如何添加输入指示器或加载提示
解决方案
你可以在触发OAuthPrompt的前置步骤里插入加载提示、输入指示器逻辑,同时新增登录状态标记避免重复点击报错,实现步骤和修改后的代码如下:
实现逻辑说明
- 输入指示器/加载提示:在调用OAuthPrompt之前,主动发送打字状态活动和加载提示文本,用户点击按钮后会立刻看到提示
- 防重复点击:在对话状态中新增登录进行中的标记,登录流程未完成时重复触发请求直接拦截,不会重复拉起认证流程
完整修改后的代码
// 首先在你的对话类里新增ConversationState的属性访问器,用来存储登录状态 public IStatePropertyAccessor<bool> IsLoggingInAccessor { get; } public AuthDialog(IBotServices services, IConfiguration configuration, IBotTelemetryClient telemetryClient, UserState userState, ConversationState conversationState) { // 初始化登录状态访问器 IsLoggingInAccessor = conversationState.CreateProperty<bool>("IsLoggingIn"); AddDialog(new WaterfallDialog(InitialDialog) .AddStep(Authenticate) .AddStep(ConfirmLogin)); AddDialog(new OAuthPrompt( nameof(OAuthPrompt), new OAuthPromptSettings { ConnectionName = configuration["ConnectionName"], Text = "Please sign in.", Title = "Get Started", Timeout = 300000, // User has 5 minutes to login })); _userState = userState; _conversationState = conversationState; // 记得把conversationState存为类变量 this.TelemetryClient = telemetryClient; InitialDialogId = InitialDialog; } private async Task<DialogTurnResult> Authenticate(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // 先判断是否已经在登录流程中,避免重复触发 var isLoggingIn = await IsLoggingInAccessor.GetAsync(stepContext.Context, () => false, cancellationToken); if (isLoggingIn) { await stepContext.Context.SendActivityAsync("正在处理登录请求,请稍候,请勿重复点击按钮", cancellationToken: cancellationToken); return EndOfTurn; } // 1. 发送输入指示器(打字状态) var typingActivity = Activity.CreateTypingActivity(); await stepContext.Context.SendActivityAsync(typingActivity, cancellationToken); // 2. 发送加载提示文本 await stepContext.Context.SendActivityAsync("正在准备登录验证,请稍候...", cancellationToken: cancellationToken); // 3. 标记登录状态为进行中 await IsLoggingInAccessor.SetAsync(stepContext.Context, true, cancellationToken); await _conversationState.SaveChangesAsync(stepContext.Context, false, cancellationToken); return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken); } // 别忘了在ConfirmLogin步骤里重置登录状态 private async Task<DialogTurnResult> ConfirmLogin(WaterfallStepContext stepContext, CancellationToken cancellationToken) { // 无论登录成功失败,都重置登录状态 await IsLoggingInAccessor.SetAsync(stepContext.Context, false, cancellationToken); await _conversationState.SaveChangesAsync(stepContext.Context, false, cancellationToken); // 你原来的ConfirmLogin逻辑保留在这里 // ....... }
额外优化点
如果需要全局生效打字指示器,可以在Startup里注册ShowTypingMiddleware中间件,会在机器人处理任何请求时自动先弹出打字状态,不需要每次手动发送。
内容的提问来源于stack exchange,提问作者jcmorara
相关产品推荐
相关产品推荐

