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

能否通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:55:27