1

I am developing a language selection function for my telegram bot written in telegraf.js, language variable changes for all users and this needs to be fixed

bot.start(async (ctx) => await ctx.reply("Выберете язык / Choose language: ",{
    reply_markup:{
        inline_keyboard:[
            [ { text: " Русский", callback_data: "ru" }, { text: " English", callback_data: "en" } ],
        ]
    }
}))
let lang;
bot.action('ru',() => lang = "ru");
bot.action('en',() => lang = "en");

i tried adding acync/await in various places but it did not help

1 Answers1

1

This is because you are modifying a global variable that is stored on the server-side. Note that the code you wrote will be only one instance running for all users, it doesn't spawn a new instance for each user, meaning that global variables are shared.

To store different data for each user, you should use the session middleware. Note that by default it only stores the data in-memory. To persist it, make sure to check the linked doc page.

Here's how to use it:

const { Telegraf, session } = require('telegraf');

const bot = new Telegraf(TELEGRAM_BOT_TOKEN);
bot.use(session());

bot.action('ru', (ctx) => {
  ctx.session.language = 'ru';
});
bot.action('en', (ctx) => {
  ctx.session.language = 'en';
});

// To test it
bot.command('test', (ctx) => {
  if (ctx.session.language === 'ru') {
    ctx.reply('Здравствуйте!');
  } else {
    ctx.reply('Hello!');
  }
});

Additionally, if you are using TypeScript, here is how you'd add static types:

import { Telegraf, session, type Context } from 'telegraf';
import type { Update } from 'telegraf/types';

type SupportedLanguage = 'ru' | 'en';

interface MyContext<U extends Update = Update> extends Context<U> {
    session: {
        language: SupportedLanguage;
    };
}

const bot = new Telegraf<MyContext>(TELEGRAM_BOT_TOKEN);
// I'm honestly not sure why the `as string` part is required, but my code doesn't work without it
bot.use(session({ defaultSession: () => ({ language: 'en' as string }) }));

and the rest of the code remains the same