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

基于Node.js的Teams Bot:能否删除自适应卡片轮播中的单张卡片?

如何在Teams Bot的自适应卡片轮播中删除单个点击过的卡片?

当然可行!你遇到的问题是因为自适应卡片轮播本质是单个Activity里的多个附件集合,deleteActive会删除整个Activity(也就是整个轮播),而不是其中某一张卡片。要实现删除点击的单张卡片,我们需要通过更新原轮播Activity,移除目标卡片后重新渲染轮播。

解决方案思路

  1. 保存轮播的Activity ID和对应卡片的关联数据(比如LeadId),方便后续定位要删除的卡片
  2. 用户点击操作按钮时,根据传入的LeadId过滤掉对应卡片
  3. 使用context.updateActivity方法替换原轮播的附件列表,实现单张卡片的“删除”效果

修改后的代码示例

const { TurnContext, TeamsActivityHandler, CardFactory, AttachmentLayoutTypes, ActionTypes } = require('botbuilder');
class TeamsConversationBot extends TeamsActivityHandler {
 constructor() {
 super();
 // 存储每个会话的轮播活动信息:会话ID -> { activityId, 卡片列表(带LeadId) }
 this.carouselSessionData = {};

 this.onMessage(async (context:any, next:any) => {
 TurnContext.removeRecipientMention(context.activity);
 console.log("context activity at the begin is:" + JSON.stringify(context.activity))
 let msg = context.activity.text
 let action = context.activity.value
 if(msg.startsWith('lead')){
 msg = 'lead'
 }
 if(action !== undefined){
 console.log("user did some action on a card")
 msg = action.action
 }
 switch (msg) {
 case 'lead':
 await this.lead(context)
 break;
 case 'qualify_lead':
 await this.qualifyLead(context)
 break;
 }
 await next();
 });
 }

 async qualifyLead(context:any){
 console.log("in qualifyLead:" + JSON.stringify(context.activity))
 const leadId = context.activity.value.objectId
 const conversationId = context.activity.conversation.id;
 const carouselInfo = this.carouselSessionData[conversationId];

 if (carouselInfo) {
   // 过滤掉当前要删除的卡片
   const updatedCardList = carouselInfo.cards.filter(cardItem => cardItem.LeadId !== leadId)
                                             .map(cardItem => cardItem.card);
   // 更新原轮播活动,替换附件列表
   await context.updateActivity({
     id: carouselInfo.activityId,
     attachments: updatedCardList,
     attachmentLayout: AttachmentLayoutTypes.Carousel
   });
   // 可以清除已无卡片的会话数据(可选)
   if (updatedCardList.length === 0) {
     delete this.carouselSessionData[conversationId];
   }
 }

 console.log("Lead to qualify is:" + leadId)
 await context.sendActivity('Lead is qualified')
 }

 async lead(context:any){
 console.log("Start of lead with context:" + JSON.stringify(context))
 const items = [
 {"Name": 'x', "LeadId": "1"},
 {"Name": 'a', "LeadId": "2"},
 {"Name": 'b', "LeadId": "3"},
 {"Name": 'c', "LeadId": "4"},
 {"Name": 'd', "LeadId": "5"}
 ]
 // 生成卡片并保存每张卡片对应的LeadId
 const cardDataList = items.map(item => {
 const header = {
 "type": "TextBlock",
 "size": "Medium",
 "weight": "Bolder",
 "text": item.Name
 }
 const actions = [
 {
 "type": "Action.Submit",
 "title": "Qualify",
 "data": {
 "action" : "qualify_lead",
 "objectId" : item.LeadId
 }
 }
 ]
 const acard = CardFactory.adaptiveCard(
 {
 "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
 "type": "AdaptiveCard",
 "version": "1.0",
 "body": [ header ],
 "actions": actions
 }
 )
 return {
   LeadId: item.LeadId,
   card: acard
 };
 });
 const cardArr = cardDataList.map(item => item.card);

 const reply = {
 "attachments" : cardArr,
 "attachmentLayout" : AttachmentLayoutTypes.Carousel
 }
 // 发送轮播并保存活动ID和卡片数据
 const sentActivity = await context.sendActivity(reply);
 this.carouselSessionData[context.activity.conversation.id] = {
   activityId: sentActivity.id,
   cards: cardDataList
 };
 }
}
module.exports.TeamsConversationBot = TeamsConversationBot;

关键说明

  • carouselSessionData用来存储每个会话的轮播信息,确保不同用户/会话的操作互不干扰
  • updateActivity会替换原轮播的附件,用户看到的效果就是目标卡片被移除,其他卡片保持轮播状态
  • 如果所有卡片都被删除,可以选择删除会话数据或者发送一个“无卡片”提示

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:15:22