@gramio/scenes
API может немного измениться, но мы уже активно используем его на боевых проектах.
Использование
ts
import { Bot } from "gramio";
import { scenes, Scene } from "@gramio/scenes";
const testScene = new Scene("test")
.params<{ test: boolean }>()
.step("message", async (context) => {
if (context.scene.step.firstTime || context.text !== "1")
return context.send("1");
if (context.scene.params.test === true) await context.send("ОТЛАДКА!");
return context.scene.step.next();
});
const bot = new Bot(process.env.TOKEN as string)
.extend(scenes([testScene]))
.command("start", async (context) => {
return context.scene.enter(testScene, {
test: true,
});
});
Общее состояние между шагами
ts
import { Scene } from "@gramio/scenes";
const testScene = new Scene("test")
.step("message", async (context) => {
if (context.scene.step.firstTime || context.text !== "1")
return context.send("1");
return context.scene.update({
messageId: context.id,
some: "привет!" as const,
});
})
.step("message", async (context) => {
if (context.scene.step.firstTime || context.text !== "2")
return context.send("2");
console.log(context.scene.state.messageId);
});
Использование хранилища
ts
import { redisStorage } from "@gramio/storage-redis";
const bot = new Bot(process.env.TOKEN as string)
.extend(
scenes([testScene], {
storage: redisStorage(),
})
)
.command("start", async (context) => {
return context.scene.enter(someScene, {
test: true,
});
});
scenesDerives
Иногда нужно управлять сценами до выполнения шагов сцены плагином, но после получения сцены из хранилища.
По умолчанию функция scenes()
передаёт необходимые данные последующим обработчикам, если пользователь не находится в сцене. С помощью scenesDerives()
вы можете получить эти данные раньше и управлять ими.
ts
import { scenes, scenesDerives, type AnyScene } from "@gramio/scenes";
import { Bot } from "gramio";
import { redisStorage } from "@gramio/storage-redis";
const storage = redisStorage();
const scenesList: AnyScene[] = [testScene];
const bot = new Bot(process.env.TOKEN as string)
.extend(
scenesDerives(scenesList, {
withCurrentScene: true,
storage,
})
)
.on("message", (context, next) => {
if (context.text === "/start" && context.scene.current) {
if (context.scene.current.is(testScene)) {
console.log(context.scene.current.state);
return context.scene.current.step.previous();
} else return context.scene.current.reenter();
}
return next();
})
.extend(
scenes(scenesList, {
storage,
})
)
.command("start", async (context) => {
return context.scene.enter(testScene, {
test: true,
});
});
IMPORTANT
Одно и то же хранилище и список сцен нужно использовать и в scenes()
, и в опциях scenesDerives()
.