Stage.enter не запускает мастера - PullRequest
5 голосов
/ 18 апреля 2019

Я создал приложение, которое отображает мастер опроса для пользователя. Когда пользователь запускает команду / start, я вызываю AddProject:

const Telegraf = require('telegraf');
const bot = new Telegraf(process.env.BOT_TOKEN);
const session = require('telegraf/session');
bot.use(session());

const main = new TelegrafInlineMenu("Welcome.");
main.setCommand('start');
main.simpleButton('Start Survey', 'START_SURVEY', {
  doFunc: async ctx => surveyController.AddProject(ctx, bot)
});

По сути, приведенный выше код создает меню, в котором отображается надпись «Добро пожаловать» и кнопка для начала опроса. Когда пользователь нажимает кнопку, вызывается метод AddProject из surveyController:

const Composer = require('telegraf/composer');
const stepHandler = new Composer();
const Stage = require('telegraf/stage');
const WizardScene = require('telegraf/scenes/wizard');
const userController = require('../controllers/user.controller');

module.exports = {

  AddProject: async function (ctx, bot) {

    const superWizard = new WizardScene('super-wizard',
      (ctx) => {
        ctx.reply('Step 1', Markup.inlineKeyboard([
          Markup.urlButton('❤️', 'http://telegraf.js.org'),
          Markup.callbackButton('➡️ Next', 'next'),
        ]).extra());
        return ctx.wizard.next();
      },
      (ctx) => {
        ctx.reply('Step 2');
        return ctx.wizard.next();
      },
      (ctx) => {
        ctx.reply('Done');
        return ctx.wizard.leave();
      },
    );

    const stage = new Stage([superWizard]);
    bot.use(stage.middleware());
    Stage.enter('super-wizard');
  },
};

метод AddProject срабатывает корректно, но мастер не отображается, что я сделал не так?

1 Ответ

3 голосов
/ 23 апреля 2019

После многих попыток я наконец достиг своей цели. Я не эксперт по TelegrafJS, и мне было трудно понять документацию, особенно если вы новичок (отсутствуют примеры, отсутствует какая-то концепция, например, WizardScene и т. Д.).

Создать сцену

Таким образом, чтобы достичь цели, я должен использовать Scene, а TelegrafJS делает доступными различные типы Scene с.

Моя цель состояла в том, чтобы дождаться ввода пользователя и проверить его. Для этого я использовал WizardScene, это моя реализация:

const userWizard = new WizardScene('user-wizard',
    (ctx) => {
        ctx.reply("What is your name?");

        //Necessary for store the input
        ctx.scene.session.user = {};

        //Store the telegram user id
        ctx.scene.session.user.userId = ctx.update.callback_query.from.id;
        return ctx.wizard.next();
    },
    (ctx) => {

        //Validate the name
        if (ctx.message.text.length < 1 || ctx.message.text.length > 12) {
            return ctx.reply("Name entered has an invalid length!");
        }

        //Store the entered name
        ctx.scene.session.user.name = ctx.message.text;
        ctx.reply("What is your last name?");
        return ctx.wizard.next();
    },
    async (ctx) => {

        //Validate last name
        if (ctx.message.text.length > 30) {
            return ctx.reply("Last name has an invalid length");
        }

        ctx.scene.session.user.lastName = ctx.message.text;

        //Store the user in a separate controller
        await userController.StoreUser(ctx.scene.session.user);
        return ctx.scene.leave(); //<- Leaving a scene will clear the session automatically
    }
);

Зарегистрировать сцену

WizardScene выше необходимо зарегистрировать в Stage, поэтому мы можем использовать это Scene в Middleware. Таким образом, мы можем получить доступ к Scene в отдельном классе или модуле:

const stage = new Stage([userWizard]);
stage.command('cancel', (ctx) => {
    ctx.reply("Operation canceled");
    return ctx.scene.leave();
});
bot.use(stage.middleware())

Я также сказал Stage оставить Scene, если команда /cancel получена повторно, поэтому, если пользователь хочет отменить операцию, введите /cancel.

Начать сцену

Теперь для входа в мастер вы можете сделать следующее:

await ctx.scene.enter('user-wizard');

так что в основном у вас есть Scene промежуточное программное обеспечение, зарегистрированное в context вашего приложения, и вам нужно набрать .enter с идентификатором вашего Scene, который в моем случае user-wizard.

Это запустит мастера.

Я надеюсь, что документация будет улучшена с помощью большего количества примеров, потому что я обнаружил, что это действительно сложно реализовать и понять, особенно для меня, что я новичок в TelegrafJS.

С уважением.

...