Skip to content

@gramio/scenes

npmJSRJSR Score

The API can be changed a little, but we already use it in production environment.

Usage

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
("DEBUG!");
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,
}); });

Share state between steps

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
: "hii!" as
const
,
}); }) .
step
("message", async (
context
) => {
if (
context
.
scene
.
step
.
firstTime
||
context
.
text
!== "2")
return
context
.
send
("2");
console
.
log
(
context
.
scene
.
state
.
messageId
);
});

Storage usage

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,
        });
    });

Read more about storages

Scenes derives

Sometimes you wants to control scenes before plugin execute scene steps but after scene fetching from storage.

By default scenes() function derives what needed to next middlewares if user not in scene. With scenesDerives() you can get it earlier and manage scene data.

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

The same storage and list of scenes should be shared across scenes() and scenesDerives() options.

state: {
    messageId: number;
    some: "hii!";
}
InActiveSceneHandlerReturn<never, { simple: string; example: number[]; }>.state: {
    simple: string;
    example: number[];
}