Stage.enter 没有启动向导
Stage.enter doesn't start the wizard
我创建了一个向用户显示调查向导的应用程序。当用户启动 /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)
});
基本上,上面的代码创建了一个显示标签 Welcome 的菜单和一个开始调查的按钮。当用户点击按钮时,从 surveyController 中调用 AddProject 方法:
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 方法正确触发,但未显示向导,我做错了什么?
经过多次尝试,我终于实现了我的目标。我不是 TelegrafJS
的专家,我发现文档真的很难理解,特别是如果您是新手(缺少示例,缺少 WizardScene 等概念等)。
创建场景
所以基本上为了实现我的目标,我必须使用 Scene
和 TelegrafJS
提供不同类型的 Scene
s。
我的目标是等待用户输入并验证它。为此,我使用了 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
中注册,所以我们可以在Middleware
中使用这个Scene
。这样,我们就可以在单独的class或模块中访问Scene
:
const stage = new Stage([userWizard]);
stage.command('cancel', (ctx) => {
ctx.reply("Operation canceled");
return ctx.scene.leave();
});
bot.use(stage.middleware())
我还告诉 Stage
如果收到 /cancel
命令就离开 Scene
,所以如果用户想取消操作,输入 /cancel
是顺便。
开始场景
现在要进入向导,您可以执行以下操作:
await ctx.scene.enter('user-wizard');
所以基本上你已经在应用程序的 context
中注册了 Scene
中间件,你需要使用 Scene
的 ID 输入 .enter
就我而言 user-wizard
.
这将启动向导。
我希望文档能通过更多示例得到增强,因为我发现这真的很难实现和理解,特别是对我来说,我是 TelegrafJS
的新手。
亲切的问候。
我创建了一个向用户显示调查向导的应用程序。当用户启动 /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)
});
基本上,上面的代码创建了一个显示标签 Welcome 的菜单和一个开始调查的按钮。当用户点击按钮时,从 surveyController 中调用 AddProject 方法:
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 方法正确触发,但未显示向导,我做错了什么?
经过多次尝试,我终于实现了我的目标。我不是 TelegrafJS
的专家,我发现文档真的很难理解,特别是如果您是新手(缺少示例,缺少 WizardScene 等概念等)。
创建场景
所以基本上为了实现我的目标,我必须使用 Scene
和 TelegrafJS
提供不同类型的 Scene
s。
我的目标是等待用户输入并验证它。为此,我使用了 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
中注册,所以我们可以在Middleware
中使用这个Scene
。这样,我们就可以在单独的class或模块中访问Scene
:
const stage = new Stage([userWizard]);
stage.command('cancel', (ctx) => {
ctx.reply("Operation canceled");
return ctx.scene.leave();
});
bot.use(stage.middleware())
我还告诉 Stage
如果收到 /cancel
命令就离开 Scene
,所以如果用户想取消操作,输入 /cancel
是顺便。
开始场景
现在要进入向导,您可以执行以下操作:
await ctx.scene.enter('user-wizard');
所以基本上你已经在应用程序的 context
中注册了 Scene
中间件,你需要使用 Scene
的 ID 输入 .enter
就我而言 user-wizard
.
这将启动向导。
我希望文档能通过更多示例得到增强,因为我发现这真的很难实现和理解,特别是对我来说,我是 TelegrafJS
的新手。
亲切的问候。