botframework - 无法在 Bot Framework Emulator 中建立隧道套接字
问题描述
我发现在将 botbuilder 软件包升级到高于 4.7 的版本后,我不再能够在本地使用 Bot Framework Emulator(不使用 ngrok,我的公司不允许)(编辑:我现在已经检查过了,错误似乎是中引入4.10
。它在版本上运行良好,4.9
只保留botbuilder-testing
包在4.9
没有帮助)。谁能告诉我发生了什么变化导致这不起作用,以及是否有办法继续在本地进行测试?这在我使用的任何时候都会失败await context.sendActivity
(我确信其他东西也不能正常工作,但这是我能得到的)。这是我设置机器人适配器的方法。AppId 和 Password 为NULL,因为我在本地运行它而不使用 ngrok。
const adapter = new BotFrameworkAdapter({
appId: process.env.MicrosoftAppId, // this variable is null for local/emulator
appPassword: process.env.MicrosoftAppPassword // this variable is null for local/emulator
});
这是完整的错误信息。是的,我知道我没有发现错误,但我不会为每个 sendActivity 语句放置一个 try catch 块。错误细节没有什么不同。
(node:19488) UnhandledPromiseRejectionWarning: Error: BotFrameworkAdapter.processActivity(): 500 ERROR
Error: tunneling socket could not be established, statusCode=403
at new RestError (C:\Users\e0077301\Documents\DevOps Projects\TRaCy nanorep\node_modules\@azure\ms-rest-js\dist\msRest.node.js:1403:28)
at AxiosHttpClient.<anonymous> (C:\Users\e0077301\Documents\DevOps Projects\TRaCy nanorep\node_modules\@azure\ms-rest-js\dist\msRest.node.js:2194:35)
at step (C:\Users\e0077301\Documents\DevOps Projects\TRaCy nanorep\node_modules\tslib\tslib.js:133:27)
at Object.throw (C:\Users\e0077301\Documents\DevOps Projects\TRaCy nanorep\node_modules\tslib\tslib.js:114:57)
at rejected (C:\Users\e0077301\Documents\DevOps Projects\TRaCy nanorep\node_modules\tslib\tslib.js:105:69)
at process._tickCallback (internal/process/next_tick.js:68:7)
at BotFrameworkAdapter.<anonymous> (C:\Users\e0077301\Documents\DevOps Projects\TRaCy nanorep\node_modules\botbuilder\lib\botFrameworkAdapter.js:736:27)
at Generator.throw (<anonymous>)
at rejected (C:\Users\e0077301\Documents\DevOps Projects\TRaCy nanorep\node_modules\botbuilder\lib\botFrameworkAdapter.js:13:65)
at process._tickCallback (internal/process/next_tick.js:68:7)
以下是完整的 index.js 和 package.json 文件:
index.js
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
const path = require('path');
const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({ path: ENV_FILE });
const request = require('request-promise-native');
// Import and start application insights
const appInsights = require('applicationinsights');
appInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY).start();
const appInsightsClient = appInsights.defaultClient;
// Import required packages
const restify = require('restify');
const { CustomLogger } = require('./helpers/CustomLogger');
// Import required bot services. See https://aka.ms/bot-services to learn more about the different parts of a bot.
const { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState, TranscriptLoggerMiddleware } = require('botbuilder');
const { BlobStorage } = require('botbuilder-azure');
// This bot's main dialog.
const { DispatchBot } = require('./bots/dispatchBot');
// Create adapter.
// See https://aka.ms/about-bot-adapter to learn more about adapters.
const adapter = new BotFrameworkAdapter({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword
});
// Catch-all for errors.
adapter.onTurnError = async (context, error) => {
console.error(`\n [onTurnError]: ${ error }`);
// Log to Application Insights
appInsightsClient.trackTrace({
message: `${error.name} - ${path.basename(__filename)}`,
severity: 4,
properties: {'error':error.message,'callStack':error.stack,'botName': process.env.BOTNAME}
});
// Send a message to the user
await context.sendActivity(`Sorry, I've encountered an unexpected error and I had to cancel our last activity. If you continue to receive this error, please contact your support team.`);
// Clear out state
await conversationState.delete(context);
};
if (process.env.BOTNAME == 'Bot_Local') {
// Memory storage - for development only
console.log(`\nUsing MemoryStorage for state storage`);
const memoryStorage = new MemoryStorage();
var conversationState = new ConversationState(memoryStorage);
var userState = new UserState(memoryStorage);
} else {
// Blob storage - for production
console.log(`\nUsing BlobStorage for state storage`);
const blobStorage = new BlobStorage({
containerName: 'bot-storage',
storageAccountOrConnectionString: process.env.blobStorageServiceName,
storageAccessKey: process.env.blobStorageAccessKey
});
var conversationState = new ConversationState(blobStorage);
var userState = new UserState(blobStorage);
}
// Set up transcript logger
const transcriptLogger = new TranscriptLoggerMiddleware(new CustomLogger(appInsightsClient));
adapter.use(transcriptLogger);
// Pass in a logger to the bot.
//const logger = console;
const logger = appInsightsClient;
// Create the main dialog
let bot = new DispatchBot(conversationState, userState, logger);
// Create HTTP server
let server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function() {
console.log(`\n${ server.name } listening to ${ server.url }`);
console.log(`\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator`);
console.log(`\nSee https://aka.ms/connect-to-bot for more information`);
});
const restifyBodyParser = require('restify').plugins.bodyParser;
server.use(restifyBodyParser());
// Listen for incoming activities and route them to your bot main dialog.
server.post('/api/messages', (req, res) => {
// Route received a request to adapter for processing
adapter.processActivity(req, res, async (turnContext) => {
// route to bot activity handler.
await bot.run(turnContext);
});
});
// Respond to pings
server.get('/api/ping', (req, res) => {
res.send('Ping acknowledged');
});
// Listen for incoming notifications and send proactive messages to users.
server.post('/api/notify', async (req, res) => {
console.log(req.body);
try {
const conversationReference = req.body.conversationReference;
await adapter.continueConversation(conversationReference, async turnContext => {
// If you encounter permission-related errors when sending this message, see
// https://aka.ms/BotTrustServiceUrl
await turnContext.sendActivity(req.body.message);
});
res.setHeader('Content-Type', 'text/html');
res.writeHead(200);
res.write('<html><body><h1>Proactive messages have been sent.</h1></body></html>');
res.end();
} catch (error) {
console.log('Bad request');
appInsightsClient.trackTrace({
message: `${error.name} - ${path.basename(__filename)} /api/notify`,
severity: 4,
properties: {'error':error.message,'callStack':error.stack,'botName': process.env.BOTNAME}
});
res.setHeader('Content-Type', 'text/html');
res.writeHead(400);
res.write('<html><body><h1>Bad Request. Please ensure your message contains the conversation reference and message text.</h1></body></html>');
res.end();
}
});
server.post('/directline/token', async (req, res) => {
try {
var body = {User:{Id:req.body.userId}};
const response = await request({
url: 'https://directline.botframework.com/v3/directline/tokens/generate',
method: 'POST',
headers: { Authorization: `Bearer ${process.env.DIRECTLINE_SECRET}`},
json: body,
rejectUnauthorized: false
});
const token = response.token;
res.setHeader('Content-Type', 'text/plain');
res.writeHead(200);
res.write(token);
res.end();
} catch(err) {
console.log(err);
res.setHeader('Content-Type', 'text/plain');
res.writeHead(500);
res.write('Call to retrieve token from Direct Line failed');
res.end();
}
})
package.json (将 botbuilder 包更新到最新版本。如果我将它们全部降级到 4.7.0 就可以了)
{
"name": "core-bot",
"version": "1.0.0",
"description": "A bot that demonstrates core AI capabilities",
"author": "Microsoft",
"license": "MIT",
"main": "index.js",
"nyc": {
"exclude": [
"test",
"helpers/cardHelper.js"
]
},
"scripts": {
"start": "node ./index.js",
"watch": "nodemon ./index.js",
"lint": "eslint .",
"test:dev": "mocha test/**/*test.js",
"test": "nyc --reporter=text --reporter=cobertura mocha test/**/*test.js --timeout 10000 --reporter mocha-multi-reporters --reporter-options configFile=./mocha-reporter-config.json",
"test:inspect": "mocha test/**/*test.js --inspect-brk",
"testList": "node ./node_modules/mocha-list-tests/mocha-list-tests.js test/"
},
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/BotBuilder-Samples.git"
},
"dependencies": {
"@microsoft/recognizers-text-data-types-timex-expression": "^1.1.4",
"@sendgrid/mail": "^6.4.0",
"applicationinsights": "^1.6.0",
"azure-storage": "^2.10.3",
"botbuilder": "^4.12.0",
"botbuilder-ai": "^4.12.0",
"botbuilder-azure": "^4.12.0",
"botbuilder-dialogs": "^4.12.0",
"botbuilder-testing": "^4.12.0",
"crypto": "^1.0.1",
"dotenv": "^6.1.0",
"mocha": "^6.2.2",
"mocha-list-tests": "^1.0.2",
"nock": "^11.7.0",
"remove-markdown": "^0.3.0",
"restify": "^7.2.3",
"turndown": "^5.0.3",
"xml2js": "^0.4.22"
},
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-node": "^8.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"https-proxy-agent": "^5.0.0",
"mocha-junit-reporter": "^1.23.1",
"mocha-multi-reporters": "^1.1.7",
"nodemon": "^1.19.4",
"nyc": "^14.1.1",
"source-map-support": "^0.5.16"
}
}
解决方案
如果您在 Windows 机器上,请尝试设置此系统环境变量 -NODE_TLS_REJECT_UNAUTHORIZED=0
而不是HTTPS_PROXY
. 这解决了在 http 协议上运行的模拟器 localhost 问题,以开始与 https 上的服务进行通信。代理设置不再适用于 botbuilder 包 4.10 及更高版本。
推荐阅读
- php - 更新数据库,留下5,不受影响
- android - React Native - IOS设备屏幕在标准模式下放大问题
- java - 使用 OpenCv 的 Java 对象识别图像
- android - 是否可以从命令行使用 Android Studio 的反编译器?
- python-3.x - 按列分组,并有一列带有 value_counts 字典
- javascript - 如何检查电子邮件地址是否已在 firebase auth 上注册,就像 firebaseui 一样?
- amazon-web-services - Amazon EC2 服务器偶尔冻结
- firebase - 无法使用 cli 命令登录 Firebase
- php - 使用 htaccess 在 Wordpress 中重写 URL
- python - 重写列表列表中的值