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

BotFramework报错:Cannot perform 'get' on a proxy that has been revoked 求助

解决MS Teams机器人Cannot perform 'get' on a proxy that has been revoked错误

我正在开发一款可按模块向学生发送内容的MS Teams机器人,目前拆分了三个核心文件:

  • methods.js:封装发送文本、附件等所有消息发送方法
  • teamBot.js:捕获用户发送的特定关键词,触发对应业务逻辑
  • test.js:对接Airtable获取内容,调用发送方法推送

现在遇到Cannot perform 'get' on a proxy that has been revoked错误,推测是context的传递方式有问题。目前我是通过参数直接传递context,感觉这种方式不正确,想请教如何正确实现跨文件功能并保留context的有效性?


现有代码

teamsBot.js

const test = require("./test");
class TeamsBot extends TeamsActivityHandler {
  constructor() {
    super();

    // 记录点赞数
    this.likeCountObj = { likeCount: 0 };

    this.onMessage(async (context, next) => {
      console.log("Running with Message Activity.");
      let txt = context.activity.text;
      // const removedMentionText = TurnContext.removeRecipientMention(context.activity);
      // if (removedMentionText) {
      //   // 移除换行符
      //   txt = removedMentionText.toLowerCase().replace(/\n|\r/g, "").trim();
      // }

      // 根据IM文本触发命令
      switch (txt) {
        case "Begin": {
         await test.sendModuleContent(context)
        }
      }

      // 调用next()确保后续BotHandler执行
      await next();
    });

    // 监听MembersAdded事件
    this.onMembersAdded(async (context, next) => {
      const membersAdded = context.activity.membersAdded;
      for (let cnt = 0; cnt < membersAdded.length; cnt++) {
        if (membersAdded[cnt].id) {
          const card = cardTools.AdaptiveCards.declareWithoutData(rawWelcomeCard).render();
          await context.sendActivity({ attachments: [CardFactory.adaptiveCard(card)] });
          break;
        }
      }
      await next();
    });
  }
}

test.js

const ms = require('./methods')
async function sendModuleContent(context) {
 data = module_text // 从Airtable获取的内容
await ms.sendText(context, data)
}

methods.js

const {TeamsActivityHandler, ActivityHandler, MessageFactory } = require('botbuilder');

async function sendText(context, text){
    console.log("Sending text")
    await context.sendActivity(text);
}

问题原因与解决方案

错误原因

这个错误是因为Bot Framework中的context是一个代理对象,当前对话回合(turn)结束后,框架会自动回收这个代理、释放资源。如果在异步操作(比如从Airtable拉取数据)完成后再使用原context,代理已经被撤销,就会触发该错误。

正确实现方式

方案1:克隆Context保留有效引用

在传递context前,用TurnContext.clone创建副本,确保异步操作完成后仍能正常使用:

// teamsBot.js中引入TurnContext
const { TurnContext } = require('botbuilder');

// 修改Begin分支的调用逻辑
case "Begin": {
  const clonedContext = TurnContext.clone(context);
  await test.sendModuleContent(clonedContext)
}

方案2:提取核心信息,避免传递完整Context

不直接传递整个context,而是提取发送消息必需的对话引用和适配器,手动构建消息发送逻辑:

  1. 更新teamsBot.js的调用:
case "Begin": {
  const conversationReference = TurnContext.getConversationReference(context.activity);
  await test.sendModuleContent(conversationReference, this.adapter)
}
  1. 修改test.js:
const ms = require('./methods')
async function sendModuleContent(conversationReference, adapter) {
  const data = module_text; // 从Airtable获取内容
  await ms.sendText(conversationReference, adapter, data)
}
  1. 调整methods.js:
async function sendText(conversationReference, adapter, text){
  console.log("Sending text");
  await adapter.continueConversation(conversationReference, async (context) => {
    await context.sendActivity(text);
  });
}

方案3:确保异步操作在当前Turn内完成

检查Airtable数据获取逻辑是否存在不必要的延迟,确保所有异步操作在onMessage的next()调用前完成(你的代码已经用await等待sendModuleContent,但克隆Context仍是更稳妥的做法)。

额外优化建议

  • 尽量避免跨文件传递context,通过提取必要参数的方式解耦代码
  • 所有异步操作必须用await确保执行顺序
  • 在test.js中添加错误捕获,避免Airtable请求失败导致Bot流程中断

内容的提问来源于stack exchange,提问作者Dummy Cron

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 15:54:16