Multiple message issue with Telegram bot using node-telegram-bot-api

I’m new to JavaScript and Node.js. Working on a Telegram bot as a learning project and running into a weird issue with message handlers.

I have a registration flow that starts with /start command showing gender selection buttons:

bot.onText(/\/register/, async message => {
  db.get("SELECT * FROM accounts WHERE account_id = ?", [message.chat.id], async (err, result) => {
    result ? 
    console.log('found')
    : await bot.sendMessage(message.chat.id, message.chat.first_name + ', ' + 'welcome! 🎉\n\n' + 
    'You are not registered yet! Please choose your gender to continue:', createKeyboard(genderOptions));
  });
});

Helper function for keyboard creation:

const createKeyboard = (options) => {
  return {
    reply_markup: JSON.stringify({
      inline_keyboard: options
    })
  }
};

Gender selection buttons:

const genderOptions = [
  [
    {
      text: '🚹 Male',
      callback_data: 'register_male'
    },
    {
      text: '🚺 Female', 
      callback_data: 'register_female'
    }
  ]
];

Callback handler:

bot.on('callback_query', async callback => {
  switch (callback.data) {
    case 'register_male':
      await bot.sendMessage(callback.message.chat.id, 'Please enter your age (18-80)');
      bot.on('message', async message => {
        if (message.text >= 18 && message.text <= 80) {
          return await bot.sendMessage(message.chat.id, 'age saved successfully');
        } else {
          bot.sendMessage(message.chat.id, 'Age must be between 18-80');
        }
      });
      break;
    case 'register_female':
      bot.sendMessage(callback.message.chat.id, 'Great choice! Now please enter your age as numbers');
      break;
  }
});

The problem happens when multiple users interact with the bot simultaneously. Each user gets duplicate messages equal to the number of active users. With one user everything works fine, but with multiple users the message handler seems to trigger for all of them.

What am I doing wrong here? How can I fix this behavior so each user only gets their own responses?

Yeah, that’s a classic Telegram bot mistake - you’re adding new listeners instead of handling state properly. I made the same error when I started lol. The bot.on(‘message’) inside your callback creates permanent listeners that never disappear, so they pile up and fire for everyone. Quick fix: use a flag system or store chat IDs in an array when waiting for age input, then check if the user’s in that array before processing messages.

You’re creating a new message handler every time someone clicks the gender button. Each click adds another bot.on('message') listener that responds to ALL messages from ANY user. These listeners pile up and never get cleaned up - that’s why users see multiple responses matching the number of active sessions.

Don’t nest event handlers. Use state management instead. Keep user states in memory or a database to track where each user is in the registration flow. Have one message handler that checks the user’s current state and responds based on that. For example: when they select gender, store userStates[chatId] = 'awaiting_age'. Then your main message handler checks this state and only processes age input for users in that specific state. This keeps each user’s handling isolated without messing with others.

You’re registering multiple event listeners inside your callback handler. Each time someone clicks the gender button, you add another bot.on('message') listener that sticks around and responds to messages from everyone, not just the person who clicked it.

I ran into this exact problem with my first Telegram bot. Here’s what worked: use one message handler with user session tracking. Make a global object like const userSessions = {} to store user states. When someone picks male, set userSessions[callback.message.chat.id] = { step: 'awaiting_age', gender: 'male' }. In your main message handler, check if the user has an active session and what step they’re on before processing their input. This stops listeners from piling up and keeps each user’s data separate. Don’t forget to clear the session when registration’s done.