自定义适配器接收错误:[onTurnError]未处理的错误:TypeError: bot.回复不是一个功能



我们已经创建了一个名为Botbuilder - Adapter - Vonage -js的自定义Botbuilder适配器来连接Vonage API。为了测试适配器的基本功能,使用基本的bot回复,我们向Vonage号码发送一条SMS,并应该收到一条SMS回复"Hello back",但收到的却是下面的错误:

[onTurnError] unhandled error: TypeError: bot.reply is not a function

不确定如何实际调试自定义适配器以找到它被破坏的地方。

如果能找到熟悉Botkit核心库和Botkit平台适配器的人就太好了。我在下面附上了Express Server (webhook-server.js)。

// webhook-server.js
require('dotenv').config();
const express = require('express');
const app = express();
const port = 3000;
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
const SendMessagesAPI = require('./Vonage-SEND-messages-api');
const VonageAdapter = require('botbuilder-adapter-vonage-js');
const Botkit = require('botkit');
const {
BotFrameworkAdapter,
InspectionMiddleware,
MemoryStorage,
InspectionState,
UserState,
ConversationState,
} = require('botbuilder');
const { MicrosoftAppCredentials } = require('botframework-connector');
// This bot's main dialog.
const { IntersectionBot } = require('./bot');
const { Message } = require('@vonage/server-sdk');
const creds = {
apiKey: process.env.VONAGE_API_KEY,
apiSecret: process.env.VONAGE_API_SECRET,
applicationId: process.env.VONAGE_APPLICATION_ID,
privateKey: process.env.VONAGE_APPLICATION_PRIVATE_KEY_PATH,
};
const config = {
to_number: process.env.TO_NUMBER,
from_number: process.env.FROM_NUMBER,
// enable_incomplete: true
};
// Create Adapter
const adapter = new VonageAdapter(creds, config);
// Create the Storage provider and the various types of BotState.
const memoryStorage = new MemoryStorage();
const inspectionState = new InspectionState(memoryStorage);
const userState = new UserState(memoryStorage);
const conversationState = new ConversationState(memoryStorage);
// Create and add the InspectionMiddleware to the adapter.
adapter.use(
new InspectionMiddleware(
inspectionState,
userState,
conversationState,
new MicrosoftAppCredentials(
process.env.MicrosoftAppId,
process.env.MicrosoftAppPassword
)
)
);
app.post('/webhooks/dlr', (req, res) => {
res.status(200).end();
});
// Catch-all for errors.
adapter.onTurnError = async (, error) => {
// This check writes out errors to console log .vs. app insights.
// NOTE: In production environment, you should consider logging this to Azure
//       application insights. See https://aka.ms/bottelemetry for telemetry
//       configuration instructions.
console.error(`n [onTurnError] unhandled error: ${error}`);
// Send a trace activity, which will be displayed in Bot Framework Emulator
await .sendTraceActivity(
'OnTurnError Trace',
`${error}`,
'https://www.botframework.com/schemas/error',
'TurnError'
);
// Send a message to the user
await .sendActivity('The bot encountered an error or bug.');
await .sendActivity(
'To continue to run this bot, please fix the bot source code.'
);
// Clear out state
await conversationState.clear();
};
// Create the main dialog.
const bot = new IntersectionBot(conversationState, userState);
// Listen for incoming requests.
app.post('/webhooks/inbound', (req, res) => {
console.log('/webhooks/inbound req.body', req.body);
adapter.processActivity(req, res, async () => {

console.log(context);
// [onTurnError] unhandled error: TypeError: Cannot read property 'from' of undefined
// await bot.run();
//  [onTurnError] unhandled error: TypeError: .reply is not a function
// await .reply('I heard a message!');
// [onTurnError] unhandled error: TypeError: bot.reply is not a function
await bot.reply('Hello Back!');
});
res.status(200).end();
});
app.post('/webhooks/status', (req, res) => {
res.status(200).end();
});
app.listen(port, () => {
console.log(`🌏 Server running at http://localhost:${port}`);
});

反应
🌏 Server running at http://localhost:3000
/webhooks/inbound req.body {
message_uuid: 'e93a3007-f7a5-436a-8ba7-c46d64343d80',
to: { type: 'sms', number: '12018994297' },
from: { type: 'sms', number: '15754947000' },
timestamp: '2021-08-27T21:14:51.228Z',
usage: { price: '0.0057', currency: 'EUR' },
message: {
content: { type: 'text', text: 'Hello' },
sms: { num_messages: '1' }
},
direction: 'inbound'
}
TurnContext {
_respondedRef: { responded: false },
_turnState: TurnContextStateCollection(2) [Map] {
'httpStatus' => 200,
Symbol(state) => { state: [Object], hash: '{}' }
},
_onSendActivities: [],
_onUpdateActivity: [],
_onDeleteActivity: [],
_turn: 'turn',
_locale: 'locale',
bufferedReplyActivities: [],
_adapter: VonageAdapter {
middleware: MiddlewareSet { middleware: [Array] },
BotIdentityKey: Symbol(BotIdentity),
OAuthScopeKey: Symbol(OAuthScope),
name: 'Vonage Adapter',
middlewares: null,
botkit_worker: [class VonageBotWorker extends BotWorker],
credentials: {
apiKey: '4f2ff535',
apiSecret: 'jtYzPbh3MXr8M1Hr',
applicationId: '978500cf-7ea8-4d7b-ac54-2b42f67b28a2',
privateKey: './private.key'
},
options: {},
to_number: '15754947000',
from_number: '12018994297',
enable_incomplete: undefined,
turnError: [AsyncFunction (anonymous)]
},
_activity: {
id: 'e93a3007-f7a5-436a-8ba7-c46d64343d80',
timestamp: 2021-08-27T21:14:39.573Z,
channelId: 'vonage-sms',
conversation: { id: '15754947000' },
from: { id: '15754947000' },
recipient: { id: '12018994297' },
text: 'Hello',
channelData: {
message_uuid: 'e93a3007-f7a5-436a-8ba7-c46d64343d80',
to: [Object],
from: [Object],
timestamp: '2021-08-27T21:14:51.228Z',
usage: [Object],
message: [Object],
direction: 'inbound'
},
type: 'message'
}
}
[onTurnError] unhandled error: TypeError: bot.reply is not a function
  • Botkit版本:
  • 短信平台:Vonage
  • 节点版本:v14.16.1
  • Os: MAC

看起来您的自定义适配器是使用Botkit和BotFramework构建的,类似于其他Botkit适配器。然而,你的bot的实现更符合仅为BotFramework构建的bot,但你正在尝试调用属于Botkit bot的reply()方法。

例如,在Botkit的'botbuilder-adapter-twilio-sms'适配器中,提供了两种使用适配器的方法。首先,在Botkit Basics下创建适配器,然后由Botkit使用该适配器以形成控制器。这允许您访问可从Botkit bot调用的reply()方法。

在第二步中,在BotBuilder Basics下创建适配器,然后在Express服务器的/api/messages端点中使用该适配器。入站消息被传递到适配器的processActivity()方法,然后bot使用sendActivity()方法进行响应,该方法可从BotFramework适配器的上下文中调用。

缩小您打算使用的实现范围,我相信这将减轻您收到的错误。

最新更新