grammyjs / conversations

Conversational interfaces for grammY.
https://grammy.dev/plugins/conversations
MIT License
48 stars 17 forks source link

Can't understand how to use plugins inside conversation. #111

Closed semklim closed 2 months ago

semklim commented 2 months ago

Example from doc:

async function convo(conversation: MyConversation, ctx: MyContext) {
  // Install grammY plugins here
  await conversation.run(plugin());
  // Continue defining the conversation ...
}

What I do:

import process from 'node:process'
import path from 'node:path'
import { I18n } from '@grammyjs/i18n'
import type { Context } from '#root/bot/context.js'

export const i18n = new I18n<Context>({
  defaultLocale: 'en',
  directory: path.resolve(process.cwd(), 'locales'),
  useSession: true,
  fluentBundleOptions: {
    useIsolating: false,
  },
})

export const isMultipleLocales = i18n.locales.length > 1
import type {
  Context,
  SessionData,
} from '#root/bot/context.js'
import {
  createContextConstructor,
} from '#root/bot/context.js'
import {
  adminFeature,
  customLanguageFeature,
  languageFeature,
  unhandledFeature,
  welcomeFeature,
} from '#root/bot/features/index.js'
import { errorHandler } from '#root/bot/handlers/index.js'
import { i18n, isMultipleLocales } from '#root/bot/i18n.js'
import { updateLogger } from '#root/bot/middlewares/index.js'
import { config } from '#root/config.js'
import { logger } from '#root/logger.js'
import { autoChatAction } from '@grammyjs/auto-chat-action'
import { hydrate } from '@grammyjs/hydrate'
import { hydrateReply, parseMode } from '@grammyjs/parse-mode'
import type { BotConfig, StorageAdapter } from 'grammy'
import { Bot as TelegramBot, session } from 'grammy'

interface Options {
  sessionStorage?: StorageAdapter<SessionData>
  config?: Omit<BotConfig<Context>, 'ContextConstructor'>
}

export function createBot(token: string, options: Options = {}) {
  const { sessionStorage } = options
  const bot = new TelegramBot(token, {
    ...options.config,
    ContextConstructor: createContextConstructor({ logger }),
  })
  const protectedBot = bot.errorBoundary(errorHandler)

  // Middlewares

  if (config.isDev)
    protectedBot.use(updateLogger())

  protectedBot.use(autoChatAction(bot.api))
  protectedBot.use(
    session({
      initial: (): SessionData => {
        return {
          lang: 'en',
          isSecretGuest: false,
        };
      },
      storage: sessionStorage,
    }),
  )

  bot.api.config.use(parseMode('HTML'));
  protectedBot.use(hydrateReply);
  protectedBot.use(hydrate());
  protectedBot.use(i18n);
  protectedBot.use(conversations());
  protectedBot.use(createConversation(greeting));

  // Handlers
  protectedBot.use(welcomeFeature)
  protectedBot.use(adminFeature)

  if (isMultipleLocales)
    protectedBot.use(customLanguageFeature)
    protectedBot.use(languageFeature)

  // must be the last handler
  protectedBot.use(unhandledFeature)

  return bot
}

greeting.ts

import { Context, MyConversation } from "../context.js";
import { i18n } from "../i18n.js";

export async function greeting(conversation: MyConversation, ctx: Context) {
  await ctx.reply("Привіт! Як тебе звати?");
  const { message } = await conversation.wait();
  await conversation.run(i18n.middleware()); // or await conversation.run(i18n); **doesn't work**
  if (!message) {
    await ctx.reply("Привіт! Як тебе звати? " + ctx.t('welcome'));
  } else {
    return ctx.reply(`Ласкаво просимо до чату, ${message.text}!`);

  }
}

What I do wrong?

roziscoding commented 2 months ago

sticker

KnorpelSenf commented 2 months ago

What I do wrong?

What error do you see?

KnorpelSenf commented 2 months ago

Btw my guess is that you have to flip the order of the lines

  const { message } = await conversation.wait();
  await conversation.run(i18n.middleware()); // or await conversation.run(i18n); **doesn't work**

but this is a guess and more info would be very helpful.

semklim commented 2 months ago

Sorry, it was my mistake. I need to be more attentive. Thank you for help. While I was trying to figure out how to explain my problem, I found the error.

greeting.ts

Main mistake, i try to check if plugin is work in wrong place.

import { Context, MyConversation } from "../context.js";
import { i18n } from "../i18n.js";

export async function greeting(conversation: MyConversation, ctx: Context) {
  await ctx.reply("Привіт! Як тебе звати?");
  const { message } = await conversation.wait();
  // await conversation.run(i18n.middleware()); // or await conversation.run(i18n); **doesn't work**
  await conversation.run(i18n); // actually work
  if (!message) { 
    await ctx.reply("Привіт! Як тебе звати? " + ctx.t('welcome')); // <-- try to check if plugin is work in wrong place
  } else {
    return ctx.reply(`Ласкаво просимо до чату, ${message.text}!`);

  }
}