能否通过Teams通知机器人回复已发送的自适应卡片?
可以通过Teams通知机器人实现卡片回复
你完全可以借助TeamsFx提供的ConversationBot(即你使用的通知机器人)实现对已发送自适应卡片的回复,无需直接调用Graph/REST API,同时还能避开用户MFA限制——因为机器人基于应用身份(Client Credentials)认证,不受终端用户MFA状态影响。
实现步骤
1. 保存已发送卡片的对话引用与活动ID
发送卡片时,需要将对话引用(ConversationReference)、原卡片的ActivityId与你的关联标识(如客户ID)绑定,存储到持久化介质(如Azure Blob存储、SQL数据库)中,这是后续回复的核心依据。
修改你现有的发送代码,添加存储逻辑:
string adaptiveCardFilePath = Path.Combine(context.FunctionAppDirectory, "Resources", "NotificationDefault.json"); string cardTemplate = await File.ReadAllTextAsync(adaptiveCardFilePath, req.HttpContext.RequestAborted); TeamsBotInstallation[] installations = await _conversation.Notification.GetInstallationsAsync(req.HttpContext.RequestAborted); // 示例用客户ID作为关联标识,替换为你的实际业务标识 string customerId = "target-customer-id"; foreach (var installation in installations) { var cardContent = new AdaptiveCardTemplate(cardTemplate).Expand ( new NotificationDefaultModel { Title = "This message is send via Teams Notification Bot", AppName = "Azure Function", Description = $"test", NotificationUrl = "https://www.example.com/", } ); // 发送卡片并获取返回结果 var result = await installation.SendAdaptiveCard(JsonConvert.DeserializeObject(cardContent), req.HttpContext.RequestAborted); // 获取对话引用 var conversationReference = installation.GetConversationReference(); // 构造元数据并存储(替换为你的持久化逻辑,如存入Azure Table Storage) var cardMetadata = new { CustomerId = customerId, ConversationReference = JsonConvert.SerializeObject(conversationReference), OriginalActivityId = result.ActivityId }; await SaveCardMetadataToStorage(cardMetadata); }
2. 根据关联标识回复卡片
当需要回复同一客户的卡片时,通过关联标识取出对应的对话引用和原ActivityId,构造回复卡片并发送。
示例回复代码:
// 根据客户ID获取存储的卡片元数据 var cardMetadata = await GetCardMetadataFromStorage("target-customer-id"); if (cardMetadata == null) return; // 反序列化对话引用 var conversationReference = JsonConvert.DeserializeObject<ConversationReference>(cardMetadata.ConversationReference); // 加载并渲染回复用的自适应卡片模板 string replyCardTemplate = await File.ReadAllTextAsync(Path.Combine(context.FunctionAppDirectory, "Resources", "NotificationReply.json"), req.HttpContext.RequestAborted); var replyCardContent = new AdaptiveCardTemplate(replyCardTemplate).Expand(new NotificationReplyModel { Title = "回复通知", Content = "这是对原卡片的跟进内容" }); // 创建对话上下文并发送回复 var turnContext = await _conversation.CreateTurnContextAsync(conversationReference, req.HttpContext.RequestAborted); var replyActivity = MessageFactory.Attachment(new Attachment { ContentType = AdaptiveCard.ContentType, Content = JsonConvert.DeserializeObject(replyCardContent) }); // 指定回复目标为原卡片 replyActivity.ReplyToId = cardMetadata.OriginalActivityId; await turnContext.SendActivityAsync(replyActivity, req.HttpContext.RequestAborted);
关键注意事项
- 机器人权限:确保Teams应用manifest中,机器人已配置
teamwork.bot权限,且已安装到目标Teams频道。 - 存储可靠性:对话引用和ActivityId是回复的核心依据,需保证存储的可靠性,避免丢失导致无法回复。
- 身份认证:机器人使用应用身份认证,无需用户参与MFA,只要Azure AD应用拥有对应权限即可正常操作。
内容的提问来源于stack exchange,提问作者Ali Hasan
相关产品推荐
相关产品推荐

