I created an application which display a survey wizard to the user. When the user launch the /start command, I call the 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)
});
essentially the code above create a menu that display the label Welcome and a button to start the survey. When the user click on the button, the method AddProject is called from the 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');
},
};
the method AddProject is firing correctly, but the wizard is not displayed, what I did wrong?
After a lot of attempts I finally achieved my goal. I'm not an expert of TelegrafJS
and I found the documentation really hard to understand, specially if you are a newbie (missing examples, some concept like WizardScene missing etc...).
Create a Scene
So basically to achieve my target I have to use a Scene
and TelegrafJS
makes available different types of Scene
s.
My goal was to wait for user input, and validate it. For this, I have used the WizardScene
, this is my implementation:
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
}
);
Register a Scene
the WizardScene
above need to be registered in a Stage
, so we can use this Scene
in a Middleware
. In this way, we can access to the Scene
in a separate class or module:
const stage = new Stage([userWizard]);
stage.command('cancel', (ctx) => {
ctx.reply("Operation canceled");
return ctx.scene.leave();
});
bot.use(stage.middleware())
I also told to the Stage
to leave the Scene
if the /cancel
command is reiceved, so if the user want cancel the operation, typing /cancel
is the way.
Start a Scene
Now for enter in the wizard you can do the following:
await ctx.scene.enter('user-wizard');
so basically you have the Scene
middleware registered in the context
of your application, and you need to type .enter
with the id of your Scene
which is in my case user-wizard
.
This will start the wizard.
I hope the documentation will be enhanced with more example, because I found this really hard to implement and understand, specially for me that I'm a newbie on TelegrafJS
.
Kind regards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With