IlyaSemenov / grammy-scenes

Nested named scenes for grammY
MIT License
27 stars 0 forks source link

Using Scenes with Storage Adapters #18

Closed naumoff1337 closed 9 months ago

naumoff1337 commented 9 months ago

Is there any possibility to use grammy-scenes together with some Storage Adapter, for example TypeORM storage adapter?

import { Bot, Context, session, SessionFlavor } from 'grammy'
import { ScenesSessionData, ScenesFlavor } from 'grammy-scenes'
import { TypeormAdapter } from '@grammyjs/storage-typeorm'

import { AppDataSource } from './db'
import { SessionEntity } from './session.entity'
import { scenes } from './scenes'

type MyContext = Context & SessionFlavor<ScenesSessionData> & ScenesFlavor

async function bootstrap() {
  const bot = new Bot<MyContext>(process.env.BOT_TOKEN)

  bot.use(
    session({
      initial: () => ({}),
      storage: new TypeormAdapter({
        repository: AppDataSource.getRepository(SessionEntity),
      }),
    }),
  )

  bot.use(scenes.manager())

  bot.command('start', async (ctx) => {
    ctx.scenes.enter('main')
  })

  bot.use(scenes)

  bot.start()
}

bootstrap()

The above code doesn't work because it doesn't save the scene state to the database.

naumoff1337 commented 9 months ago

Just need to use ctx.scenes.enter() with await.

Update this in the README.md file and in tests/lib/bot.ts

IlyaSemenov commented 9 months ago

Both the README and the test bot code are correct.

The README examples include explicit await:

https://github.com/IlyaSemenov/grammy-scenes/blob/1c576a4cd7914c70bcf3582ff1c9c2b02aa03758/README.md#L44-L47

The test bot directly returns a promise which is then awaited by the upstream:

https://github.com/IlyaSemenov/grammy-scenes/blob/1c576a4cd7914c70bcf3582ff1c9c2b02aa03758/tests/lib/bot.ts#L40

In your code above, you replaced the expression arrow function with the statement arrow function and created a dangling promise inside of it. That broke things indeed, as the middleware was finishing, unwinding the stack and saving the state too early (before the dangling promise had completed). Glad you've figured this out.