BotBuilder 类型错误:无法读取未定义的属性'listen'



我正在遵循适用于 NodeJs 的 Microsoft Bot Builder(SDK v3) 的官方快速入门:使用 Bot Builder SDK for Node 创建一个机器人.js

1-我做了一个新项目

npm init

2-然后

npm install --save botbuilder@3.13.1

3-然后我创建了一个新文件"app.js">

var builder = require('botbuilder');
var connector = new builder.ConsoleConnector().listen();
var bot = new builder.UniversalBot(connector, function (session) {
session.send("You said: %s", session.message.text);
});

但是当我运行node app.js时,会抛出以下错误:

var 连接器 = builder。ConsoleConnector().listen();
类型错误: 无法读取未定义的属性"侦听">

尚未为机器人分配存储选项。最简单的选项(仅用于开发)是在内存存储中使用。你的代码应该看起来像这样:

var builder = require('botbuilder');
// Bot Storage: Here we register the state storage for your bot. 
// Default store: volatile in-memory store - Only for prototyping!
var inMemoryStorage = new builder.MemoryBotStorage();
var connector = new builder.ConsoleConnector().listen();
var bot = new builder.UniversalBot(connector, function(session) {
session.send("You said: %s", session.message.text);
}).set('storage', inMemoryStorage); // Register in memory storage

话虽如此,请注意,v3 SDK 将在不久的将来被弃用。建议改为使用 v4 节点 SDK 开始开发。要开始使用,您可以在此处引用文档并在此处查看示例代码。

简而言之,在 v4 中,您将使用三个文件:index.js、bot.js 和 consoleAdapter.js。

index.js文件本质上构建了服务器,api等。

const path = require('path');
const {
ConsoleAdapter
} = require('./consoleAdapter');
// load environment variables from .env file.
const ENV_FILE = path.join(__dirname, '.env');
require('dotenv').config({
path: ENV_FILE
});
// Create the bot adapter, which is responsible for sending and receiving messages.
// We are using the ConsoleAdapter, which enables a bot you can chat with from within your terminal window.
const adapter = new ConsoleAdapter();
// Import our bot class.
const {
EchoBot
} = require('./bot');
const bot = new EchoBot();
// A call to adapter.listen tells the adapter to start listening for incoming messages and events, known as "activities."
// Activities are received as TurnContext objects by the handler function.
adapter.listen(async(context) => {
bot.onTurn(context);
});
// Emit a startup message with some instructions.
console.log('> Console EchoBot is online. I will repeat any message you send me!');
console.log('> Say "quit" to end.');
console.log(''); // Leave a blank line after instructions.

通常,bot.js 文件处理机器人的 on[ActivityType] 操作(例如 onMessage())。在更复杂的机器人中,对话框被外推到它们自己的文件中。

class EchoBot {
async onTurn(context) {
// Check to see if this activity is an incoming message.
// (It could theoretically be another type of activity.)
if(context.activity.type === 'message' && context.activity.text) {
// Check to see if the user sent a simple "quit" message.
if(context.activity.text.toLowerCase() === 'quit') {
// Send a reply.
context.sendActivity(`Bye!`);
process.exit();
} else {
// Echo the message text back to the user.
return context.sendActivity(`I heard you say "${ context.activity.text }"`);
}
}
}
}
module.exports.EchoBot = EchoBot;

最后,consoleAdapter.js 文件的任务是捕获控制台活动并将其转换为机器人。

'use strict';
var __importStar = (this && this.__importStar) || function(mod) {
if(mod && mod.__esModule) return mod;
var result = {};
if(mod != null)
for(var k in mod)
if(Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result['default'] = mod;
return result;
};
Object.defineProperty(exports, '__esModule', {
value: true
});
const botbuilderCore = require('botbuilder-core');
const readline = __importStar(require('readline'));
const console = require('console');
/**
* Lets a user communicate with a bot from a console window.
*
*/
class ConsoleAdapter extends botbuilderCore.BotAdapter {
/**
* Creates a new ConsoleAdapter instance.
* @param reference (Optional) reference used to customize the address information of activities sent from the adapter.
*/
constructor(reference) {
super();
this.nextId = 0;
this.reference = Object.assign({
channelId: 'console',
user: {
id: 'user',
name: 'User1'
},
bot: {
id: 'bot',
name: 'Bot'
},
conversation: {
id: 'convo1',
name: '',
isGroup: false
},
serviceUrl: ''
}, reference);
}
/**
* Begins listening to console input. A function will be returned that can be used to stop the
* bot listening and therefore end the process.
*
* @param logic Function which will be called each time a message is input by the user.
*/
listen(logic) {
const rl = this.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});
rl.on('line', (line) => {
// Initialize activity
const activity = botbuilderCore.TurnContext.applyConversationReference({
type: botbuilderCore.ActivityTypes.Message,
id: (this.nextId++).toString(),
timestamp: new Date(),
text: line
}, this.reference, true);
// Create context and run middleware pipe
const context = new botbuilderCore.TurnContext(this, activity);
this.runMiddleware(context, logic)
.catch((err) => {
this.printError(err.toString());
});
});
return() => {
rl.close();
};
}
/**
* Lets a bot proactively message the user.
*
* @param reference A `ConversationReference` saved during a previous message from a user.  This can be calculated for any incoming activity using `TurnContext.getConversationReference(context.activity)`.
* @param logic A function handler that will be called to perform the bots logic after the the adapters middleware has been run.
*/
continueConversation(reference, logic) {
// Create context and run middleware pipe
const activity = botbuilderCore.TurnContext.applyConversationReference({}, reference, true);
const context = new botbuilderCore.TurnContext(this, activity);
return this.runMiddleware(context, logic)
.catch((err) => {
this.printError(err.toString());
});
}
/**
* Logs a set of activities to the console.
*
* @param context Context for the current turn of conversation with the user.
* @param activities List of activities to send.
*/
sendActivities(context, activities) {
const that = this;
// tslint:disable-next-line:promise-must-complete
return new Promise((resolve, reject) => {
const responses = [];
function next(i) {
if(i < activities.length) {
responses.push({});
const a = activities[i];
switch(a.type) {
case 'delay':
setTimeout(() => next(i + 1), a.value);
break;
case botbuilderCore.ActivityTypes.Message:
if(a.attachments && a.attachments.length > 0) {
const append = a.attachments.length === 1 ?
`(1 attachment)` : `(${ a.attachments.length } attachments)`;
that.print(`${ a.text } ${ append }`);
} else {
that.print(a.text || '');
}
next(i + 1);
break;
default:
that.print(`[${ a.type }]`);
next(i + 1);
break;
}
} else {
resolve(responses);
}
}
next(0);
});
}
/**
* Not supported for the ConsoleAdapter.  Calling this method or `TurnContext.updateActivity()`
* will result an error being returned.
*/
updateActivity(context, activity) {
return Promise.reject(new Error(`ConsoleAdapter.updateActivity(): not supported.`));
}
/**
* Not supported for the ConsoleAdapter.  Calling this method or `TurnContext.deleteActivity()`
* will result an error being returned.
*/
deleteActivity(context, reference) {
return Promise.reject(new Error(`ConsoleAdapter.deleteActivity(): not supported.`));
}
/**
* Allows for mocking of the console interface in unit tests.
* @param options Console interface options.
*/
createInterface(options) {
return readline.createInterface(options);
}
/**
* Logs text to the console.
* @param line Text to print.
*/
print(line) {
console.log(line);
}
/**
* Logs an error to the console.
* @param line Error text to print.
*/
printError(line) {
console.error(line);
}
}
exports.ConsoleAdapter = ConsoleAdapter;

上面的代码取自 Botbuilder-Samples 存储库的 01.console-echo 示例。我删除了一些内联评论。有关完整的代码/文件和相关备注,请参阅项目。

希望有帮助!

最新更新