使用Azure Custom Question Answering时遭遇HTTP Unauthorized错误
我正在开发一个基于Azure Custom Question Answering服务的机器人,已确认BotFrameworkAdapter和服务的所有凭证(appId、appPassword、projectName等)正确且未过期,部署到Firebase Functions也无警告/错误,但在Web Chat和Direct Line测试时收到以下错误:
There was an error sending this message to your bot: HTTP status code Unauthorized
相关代码片段:
const { onRequest } = require("firebase-functions/v2/https"); const logger = require("firebase-functions/logger"); const { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState } = require('botbuilder'); const axios = require('axios'); const functions = require('firebase-functions'); // Create adapter. const adapter = new BotFrameworkAdapter({ appId: '6c546f61-...', appPassword: 'EXK8Q~....' }); // Configuration for Custom Question Answering const projectName = 'mr-...'; const deploymentName = 'production'; const endpointKey = 'a27ee....'; const host = 'https://mr-...'; // Create storage. const memoryStorage = new MemoryStorage(); const conversationState = new ConversationState(memoryStorage); const userState = new UserState(memoryStorage); // Create bot logic. const botLogic = async (context) => { if (context.activity.type === 'message') { const question = context.activity.text; try { const response = await axios.post( `${host}/language/:query-knowledgebases?projectName=${projectName}&api-version=2021-10-01&deploymentName=${deploymentName}`, { top: 1, question: question }, { headers: { 'Ocp-Apim-Subscription-Key': endpointKey, 'Content-Type': 'application/json' } } ); const answers = response.data.answers; if (answers.length > 0) { await context.sendActivity(answers[0].answer); } else { await context.sendActivity('Sorry, I do not have an answer for that.'); } } catch (error) { console.error('Error querying the knowledge base:', error); await context.sendActivity('There was an error querying the knowledge base.'); } } }; const cors = require('cors')({ origin: true }); // Listen for incoming requests and send them to the bot. exports.bot = functions.https.onRequest((req, res) => { console.error('Just a test message'); adapter.processActivity(req, res, async (context) => { await botLogic(context); }); });
不确定是代码遗漏配置还是其他环节问题,求解决指导。
核对Bot服务凭证与通道配置
确认Azure Bot Service后台配置的Microsoft App ID和Microsoft App Password与代码中的值完全一致,无多余空格或格式错误。同时检查Direct Line通道是否已启用,测试时使用的是最新生成的有效Direct Line密钥。修复Firebase Functions的CORS处理逻辑
当前代码引入了cors模块但未实际调用,可能导致请求跨域或解析异常。修改请求处理函数,先通过cors处理跨域后再交给adapter:exports.bot = functions.https.onRequest((req, res) => { cors(req, res, async () => { console.error('Just a test message'); adapter.processActivity(req, res, async (context) => { await botLogic(context); }); }); });添加Bot Framework错误捕获日志
在adapter中添加全局错误处理,捕获身份验证相关的详细错误信息,便于定位问题:adapter.onTurnError = async (context, error) => { console.error('[onTurnError] 未处理错误:', error); await context.sendActivity('机器人遇到了错误,请稍后重试。'); };部署后查看Firebase Functions的日志,确认是否为JWT验证失败、凭证不匹配等具体原因。
单独验证Custom Question Answering API
用Postman或curl直接调用代码中的Custom Question Answering POST接口,确认返回200状态码,排除服务端接口本身的问题,避免因接口格式错误引发间接的授权异常。检查网络与区域限制
确认Azure Bot Service与Firebase Functions的区域无网络隔离限制,Bot Service能正常访问Firebase的接口地址。若Bot Service配置了虚拟网络或防火墙规则,需允许Firebase的IP范围访问。
内容的提问来源于stack exchange,提问作者Abbas Jafari

