如何在Azure Bot Framework中添加类似Teams即将停用的M365 Copilot的中断按钮?
在Azure Bot Framework中实现Teams风格的中断按钮
要实现和Teams旧版M365 Copilot一致的中断按钮效果,核心是通过Adaptive Card提供交互入口,并在Bot端处理中断请求、终止当前任务,以下是具体实现步骤:
1. 发送带中断按钮的处理中卡片
使用Adaptive Card创建包含红色中断按钮的消息卡片,按钮通过Action.Submit触发中断指令,样式设置为destructive以匹配Teams原生中断按钮的视觉效果。
示例Adaptive Card JSON:
{ "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.4", "body": [ { "type": "TextBlock", "text": "正在处理你的请求...", "size": "Medium" } ], "actions": [ { "type": "Action.Submit", "title": "中断", "style": "destructive", "data": { "action": "interrupt" } } ] }
2. Bot端处理中断请求
在Bot的消息处理逻辑中,监听Adaptive Card的提交事件,识别中断指令后终止当前正在执行的异步任务,并更新消息状态。
C# 代码示例
private CancellationTokenSource _currentCts; protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken) { var activity = turnContext.Activity; // 处理Adaptive Card的中断提交请求 if (activity.Value != null) { dynamic payload = activity.Value; if (payload.action?.ToString() == "interrupt") { // 终止当前任务 _currentCts?.Cancel(); _currentCts?.Dispose(); _currentCts = null; // 回复中断确认 await turnContext.SendActivityAsync(MessageFactory.Text("请求已中断"), cancellationToken); // 更新原消息,移除中断按钮 var updatedCard = GetStatusCard("请求已中断"); await turnContext.UpdateActivityAsync(MessageFactory.Attachment(new Attachment { ContentType = AdaptiveCard.ContentType, Content = updatedCard }, null, null, activity.ReplyToId), cancellationToken); return; } } // 正常处理用户请求,创建取消令牌跟踪任务 _currentCts = new CancellationTokenSource(); try { // 发送带中断按钮的处理中卡片 var processingCard = GetProcessingCard(); var processingReply = await turnContext.SendActivityAsync(MessageFactory.Attachment(new Attachment { ContentType = AdaptiveCard.ContentType, Content = processingCard }), cancellationToken); // 模拟长时间任务(如LLM调用、复杂业务逻辑) await LongRunningTask(_currentCts.Token); // 任务完成后更新卡片状态 var completedCard = GetStatusCard("请求处理完成"); await turnContext.UpdateActivityAsync(MessageFactory.Attachment(new Attachment { ContentType = AdaptiveCard.ContentType, Content = completedCard }, null, null, processingReply.Id), cancellationToken); } catch (OperationCanceledException) { // 捕获任务取消异常,无需额外处理 } finally { _currentCts?.Dispose(); _currentCts = null; } } // 生成处理中卡片 private object GetProcessingCard() { return new { type = "AdaptiveCard", schema = "http://adaptivecards.io/schemas/adaptive-card.json", version = "1.4", body = new[] { new { type = "TextBlock", text = "正在处理你的请求...", size = "Medium" } }, actions = new[] { new { type = "Action.Submit", title = "中断", style = "destructive", data = new { action = "interrupt" } } } }; } // 生成状态提示卡片(无按钮) private object GetStatusCard(string statusText) { return new { type = "AdaptiveCard", schema = "http://adaptivecards.io/schemas/adaptive-card.json", version = "1.4", body = new[] { new { type = "TextBlock", text = statusText, size = "Medium" } } }; } // 模拟耗时任务 private async Task LongRunningTask(CancellationToken token) { for (int i = 0; i < 10; i++) { token.ThrowIfCancellationRequested(); await Task.Delay(1000, token); } }
关键注意事项
- 任务跟踪:通过
CancellationTokenSource维护当前执行任务的取消令牌,确保中断指令能及时终止耗时操作。 - 视觉匹配:使用
style="destructive"让按钮显示为红色,和Teams原生中断按钮样式一致。 - 消息更新:中断或任务完成后,更新原消息卡片移除按钮,避免重复触发操作。
内容的提问来源于stack exchange,提问作者draco951
相关产品推荐
相关产品推荐

