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

Bot Framework恢复对话时抛出TypeError:无法对已撤销代理执行'set'

问题描述

我正在调试Microsoft Teams Bot Framework的bot-conversation示例,需求是通过WebSocket将用户消息发送至后端,收到后端响应后向聊天发送消息。

当前机器人核心实现代码:

class TeamsConversationBot extends TeamsActivityHandler {
    ws = null;

    constructor(adapter) {
        super();
        this.adapter = adapter;

        this.onMessage(async (context, next) => {
            // 用户消息发往后端,这部分正常工作
            TurnContext.removeRecipientMention(context.activity);
            await context.sendActivity({ type: 'typing' });
            const text = context.activity.text.trim();

            await this.handleUserPrompt(context, text);
            await next();
        });


        this.ws = new WebSocket('wss://.../dev');
        this.ws.on('message', async (data) => {
            // 后端消息发给用户
            console.log('\nKhydra->Teams: ', data.toString('utf8'));
            const messageData = JSON.parse(data);
            await this.handleKhydraFragment(messageData);
        });
    }

当收到后端包含textBlock的响应时,我尝试通过以下代码恢复对话并发送消息:

async handleKhydraFragment(messageData) {
        const fragment = messageData.fragment;
        if ('textBlock' in fragment) {
            const claimsIdentity = await this.adapter.createClaimsIdentity(process.env.MicrosoftAppId);
            await this.adapter.continueConversationAsync(claimsIdentity, messageData.conversationReference, async (context) => {
                context.sendActivity(fragment.textBlock);
            });
        } else {
            console.log(fragment);
        }
    }

奇怪的是,textBlock内容能成功发送到聊天,但随即抛出错误:

E:\Source\Microsoft-Teams-Samples\samples\bot-conversation\nodejs\node_modules\botbuilder-core\lib\turnContext.js:392
                    this.responded = true;
                                   ^

TypeError: Cannot perform 'set' on a proxy that has been revoked
    at Proxy.<anonymous> (E:\Robora\Source\Microsoft-Teams-Samples\samples\bot-conversation\nodejs\node_modules\botbuilder-core\lib\turnContext.js:392:36)
    at Generator.next (<anonymous>)
    at fulfilled (E:\Robora\Source\Microsoft-Teams-Samples\samples\bot-conversation\nodejs\node_modules\botbuilder-core\lib\turnContext.js:9:58)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

Node.js v18.15.0

请问我遗漏了什么?


解决方案

这个错误的核心原因是:context.sendActivity是异步操作,但你没有用await等待它执行完成,导致continueConversationAsync创建的上下文代理在异步操作结束前就被系统撤销,后续代理对象的属性赋值(比如this.responded = true)就会失败。

第一步:修复异步操作等待问题

修改handleKhydraFragment中的回调函数,给context.sendActivity添加await关键字,确保异步操作完成后再结束上下文:

async handleKhydraFragment(messageData) {
    const fragment = messageData.fragment;
    if ('textBlock' in fragment) {
        const claimsIdentity = await this.adapter.createClaimsIdentity(process.env.MicrosoftAppId);
        await this.adapter.continueConversationAsync(claimsIdentity, messageData.conversationReference, async (context) => {
            await context.sendActivity(fragment.textBlock); // 添加await等待发送完成
        });
    } else {
        console.log(fragment);
    }
}

第二步:优化对话引用与身份验证(可选但推荐)

你当前手动创建claimsIdentity的方式存在潜在风险,正确的做法是在用户首次发送消息时,把完整的对话引用(包含身份信息)发送给后端,后续直接使用后端返回的对话引用即可:

  1. 在处理用户消息的handleUserPrompt中,获取完整对话引用并发送给后端:
async handleUserPrompt(context, text) {
    const conversationRef = TurnContext.getConversationReference(context.activity);
    // 将conversationRef和text一起通过WebSocket发送给后端
    this.ws.send(JSON.stringify({ text, conversationReference: conversationRef }));
}
  1. 在handleKhydraFragment中,直接使用后端返回的对话引用,无需手动创建身份:
async handleKhydraFragment(messageData) {
    const fragment = messageData.fragment;
    if ('textBlock' in fragment) {
        // 使用微软应用ID和后端返回的对话引用恢复对话
        await this.adapter.continueConversationAsync(process.env.MicrosoftAppId, messageData.conversationReference, async (context) => {
            await context.sendActivity(fragment.textBlock);
        });
    } else {
        console.log(fragment);
    }
}

这样既解决了代理被撤销的错误,也保证了身份验证的正确性,避免了手动创建身份可能带来的权限问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:21:04