Edit: After reading/trying a lot, based on a few github issues. You can only change a user's scene when you have the context (ctx
) of that user.
The easiest way is to get the ctx
is to save it for later once you get an interaction with a user.
Please see my test code, explanation below:
const { Telegraf, Scenes, session } = require('telegraf');
const { BaseScene, Stage } = Scenes;
const botToken = '859163076:gfkjsdgkaslgflalsgflgsadhjg';
const user1id = 123456;
const user2id = 789456;
const ctxObj = { };
// Scene 1
const scene_1 = new BaseScene('scene_1');
scene_1.enter((ctx) => {
// Save ctx
ctxObj[ctx.message.from.id] = ctx;
console.log('State: ', ctxObj)
ctx.reply('You just enetered scene_1')
});
scene_1.on('text', async (ctx) => {
console.log('Got message in scene_1', ctx.message.text, ctx.message.from.id)
// When receiving form user-2, force user-1 scene
if (ctx.message.from.id === user2id) {
if (ctxObj[user1id]) {
ctxObj[user1id].scene.enter('scene_2');
}
}
});
// Scene 2
const scene_2 = new BaseScene('scene_2');
scene_2.enter((ctx) => ctx.reply('You just enetered scene_2'));
scene_2.on('text', (ctx) => {
console.log('Got message in scene_2', ctx.message.text);
ctx.scene.leave();
});
// Stage
const stage = new Stage([ scene_1, scene_2 ]);
// Bot
const bot = new Telegraf(botToken);
bot.use(session());
bot.use(stage.middleware());
bot.command('start', (ctx) => ctx.scene.enter('scene_1'));
bot.launch();
The 2 important parts are:
scene_1.enter((ctx) => {
// Save ctx
ctxObj[ctx.message.from.id] = ctx;
console.log('State: ', ctxObj)
ctx.reply('You just enetered scene_1')
});
Here we save the ctx
of every user when they enter scene_1
.
scene_1.on('text', async (ctx) => {
console.log('Got message in scene_1', ctx.message.text, ctx.message.from.id)
// When receiving form user-2, force user-1 scene
if (ctx.message.from.id === user2id) {
if (ctxObj[user1id]) {
ctxObj[user1id].scene.enter('scene_2');
}
}
});
Then, when we receive a message from a user that's in scene_2
, we check (this is pure for testing) if the message if from user_2
, if so, we use the ctx
of user_1
and call scene.enter
to force him into the new scene.
This works as expected, if needed I can place some screenshots of 2 Telegram accounts talking to that bot.
It seems like you can create the ctx
on the fly, but I'd recommend just saving it if you have the ability to.