Hubot: методы класса не переопределяются в Rocket.Chat / Meteor / JavaScript - PullRequest
1 голос
/ 18 марта 2019

Rocket.Chat устарел и удалил функциональность Internal Hubot, но в нашей компании у нас есть некоторый сценарий, который не может быть перенесен на внешний бот в данный момент, поэтому мы хотели сохранить функциональность Internal Hubot самостоятельно (так как мы уже пользовательский форк из-за изменений, связанных с LDAP).

Я смог заставить его работать почти. Внутренний Hubot был инициализирован, скрипты загружены. Но вызов некоторой команды вернул Meteor code must always run within a Fiber (...) error.

После некоторой отладки кажется, что основной проблемой здесь является наследование классов для робота Hubot, и адаптер не работает. Существуют пользовательские классы, расширяющие пакетные классы Hubot:

export class InternalHubotRobot extends Hubot.Robot {
    constructor(name, alias) {
        super(null, 'shell', false, name, alias);

        this.hear = bind(this.hear);
        this.respond = bind(this.respond);
        this.enter = bind(this.enter);
        this.leave = bind(this.leave);
        this.topic = bind(this.topic);
        this.error = bind(this.error);
        this.catchAll = bind(this.catchAll);
        this.user = Meteor.users.findOne({ username: this.name }, { fields: { username: 1 } });
        this.adapter = new RocketChatAdapter(this);

        new HubotScripts(this);

        console.log(`InternalHubotRobot initialized as '${ this.name }'`);
    }
    loadAdapter() { return false; }
    hear(regex, callback) { return super.hear(regex, Meteor.bindEnvironment(callback)); }
    respond(regex, callback) { return super.respond(regex, Meteor.bindEnvironment(callback)); }
    enter(callback) { return super.enter(Meteor.bindEnvironment(callback)); }
    leave(callback) { return super.leave(Meteor.bindEnvironment(callback)); }
    topic(callback) { return super.topic(Meteor.bindEnvironment(callback)); }
    error(callback) { return super.error(Meteor.bindEnvironment(callback)); }
    catchAll(callback) { return super.catchAll(Meteor.bindEnvironment(callback)); }
}

и

export class RocketChatAdapter extends Hubot.Adapter {
    constructor(robot) {
        super(robot);

        console.log('RocketChatAdapter initialized');
    }

    send(envelope, ...strings) {
        this.robot.logger.info('[ROBOT → adapter → send()]');
        // ...
    }

    // Many more overrides
}

Внутренний Hubot инициализируется с InternalHubot = new InternalHubotRobot(RocketChat.settings.get('InternalHubot_Username'), 'Custom Alias');, и я вижу в журналах:

I20190318-11:28:59.866(1)? RocketChatAdapter initialized
I20190318-11:29:00.209(1)? [Mon Mar 18 2019 11:29:00 GMT+0100 (CET)] WARNING A script has tried registering a HTTP route while the HTTP server is disabled with --disabled-httpd.
I20190318-11:29:00.211(1)? Loaded help.coffee
I20190318-11:29:00.211(1)? InternalHubotRobot initialized as 'Custom Alias'

Таким образом, оба конструктора вызываются правильно. Но все вызовы методов для методов робота и адаптера вызываются из базовых классов из пакета Hubot, а не из InternalHubotRobot / RocketChatAdapter.

И вот в чем проблема: , поскольку эти методы не переопределяются / не вызываются должным образом, возникает ошибка Fibre и ответы не отправляются, поскольку метод send() адаптера Hubot по умолчанию ничего не делает.

Что я сделал:

  • Мне удалось избавиться от ошибки Fiber, обернув, как robot.respond /(help)+(?:\s+(.*))?$/i, Meteor.bindEnvironment((incomingMessage) (это в основном то, что должен делать конструктор InternalHubotRobot, обернув методы с bind()
  • Мне удалось отправить ответ, переопределив send через прототип:
    Hubot.Robot.prototype.send = function(envelope, ...args) {
        return sendHelper(this, envelope, args, (string) =>
            RocketChat.sendMessage(InternalHubot.user, { msg: string }, { _id: envelope.room })
        );
    };
    

Однако: это грязно, и я хотел бы полагаться на наследование и переопределение метода в дочернем классе.

Я не эксперт по JavaScript / Meteor / Rocket.Chat, так что, может быть, я что-то упустил, небольшая деталь. Как мне получить рабочее наследство?

Информация о версиях:

  • Rocket.Chat 0.73.1 / 0.74.3 (оба с настроенным Internal Hubot, восстановлены в нашем пользовательском форке). На производстве у нас 0.72.3 и там Internal Hubot работает нормально
  • Hubot 3.3.1
  • Метеор 1.8.0.2
...