【问题标题】:BotBuilder type error :Cannot read property 'listen' of undefinedBotBuilder 类型错误:无法读取未定义的属性“侦听”
【发布时间】:2019-06-08 07:00:51
【问题描述】:

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

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 connector=builder.ConsoleConnector().listen();
类型错误: 无法读取未定义的“侦听”属性

【问题讨论】:

    标签: botframework


    【解决方案1】:

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

    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 Node SDK 开始开发。要开始使用,您可以参考文档 here 并查看示例代码 here

    简而言之,在 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 示例。我删除了一些内联评论。完整代码/文件及相关备注请参考项目。

    希望有帮助!

    【讨论】:

    • 感谢 Steven,它可以工作,能否请您给我一些视频链接,我可以在其中看到 v4 Node SDK。
    • @gopaltewari 不幸的是,没有视频详细说明如何使用 v4 SDK 进行构建。希望很快会有,但目前没有预计到达时间。
    • @gopaltewari 很高兴你成功了!如果您觉得我的回答足够,请“接受”它,以便我可以从我的支持跟踪器中清除这张票。这样做也将使其他有类似问题的人受益。如果没有,请告诉我我还能提供哪些帮助!
    猜你喜欢
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2021-11-22
    • 2017-08-12
    • 2022-12-08
    • 2022-12-01
    相关资源
    最近更新 更多