Issue with Telegram bot sending multiple messages using node-telegram-bot-api with concurrent accounts

I’m just starting my journey with JavaScript and Node.js, and I’m creating a Telegram bot to enhance my understanding of these technologies. However, I’ve encountered a problem with the bot’s event handling when several users are interacting at the same time.

Here’s how my registration process works: When a user sends the /start command, it triggers a registration flow:

bot.onText(/\/start/, async msg => {
  db.get("SELECT * FROM users WHERE user_id = ?", [msg.chat.id], async (err, res) => {
    res ? 
    console.log('user exists')
    : await bot.sendMessage(msg.chat.id, msg.chat.first_name + ', welcome! 🙈

' + 'You are not registered! Please select your gender for continuing the registration:', createKeyboard(genderButtons));
  });
});

The function I use to create keyboards is:

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

Here are the gender selection buttons:

const genderButtons = [
  [
    {
      text: '👨 I'm a man',
      callback_data: 'signup_male'
    },
    {
      text: '👩 I'm a woman', 
      callback_data: 'signup_female'
    }
  ]
];

And here’s the event handler for button clicks:

bot.on('callback_query', async query => {
  switch (query.data) {
    case 'signup_male':
      await bot.sendMessage(query.message.chat.id, 'Please enter your age between 16 and 90');
      bot.on('message', async msg => {
        if (msg.text >= 16 && msg.text <= 90) {
          return await bot.sendMessage(msg.chat.id, 'Your age has been accepted');
        } else {
          bot.sendMessage(msg.chat.id, 'Age must be between 16 and 90');
        }
      });
      break;
    case 'signup_female':
      bot.sendMessage(query.message.chat.id, 'Nice to have you here! Now, please provide your age in the chat as numbers.');
      break;
  }
});

Here’s where it gets tricky: when I run the bot from one account, everything works smoothly. However, when I use multiple accounts at once, each user gets multiple messages sent to their chat whenever they enter their age. This happens based on how many accounts are using the bot at the same time and triggering responses. I’m trying to figure out why this is occurring and how to resolve it. Any insights would be appreciated!

This is a classic event listener memory leak. Every time someone clicks the gender button, you’re stacking another message listener on top of the old ones. These listeners pile up and respond to messages from ANY user, not just the one who clicked. I hit this exact problem with my first bot - ended up with 50+ listeners after testing and couldn’t figure out why everyone was getting spammed. Quick fix is using bot.once() instead of bot.on() for the message handler, but that’s still messy architecture. Better solution is proper state management. Create a simple object to track user states like userStates[userId] = 'awaiting_age' when they pick gender. Then use one global message handler that checks the user’s state before doing anything. No more listener pollution and your bot stays clean as you add features.

your problem is nesting event listeners inside the callback. every time someone clicks the gender button, you’re stacking another ‘message’ listener that never gets cleaned up. click it 3 times? now you’ve got 3 listeners firing on every single message from anyone.

two fixes: use bot.once('message', ...) instead of bot.on('message', ...) - it’ll auto-remove after one use. or even better, ditch the nested approach entirely. track user states and handle everything through one main message handler.

You’re registering multiple event listeners for the same ‘message’ event inside your callback handler. Every time someone clicks the gender button, you add another message listener with bot.on('message', ...). These listeners pile up and never get removed. When multiple users interact with your bot, you end up with tons of message listeners that all fire for every single message - it doesn’t matter who sent it. That’s why users receive multiple responses based on how many people are using the bot at once. To fix this, remove the nested event listeners and implement a state management system. Store user states in your database or memory, then handle everything in one message handler that checks the user’s current state. After someone selects their gender, set their state to ‘awaiting_age’ in your database. Your main message handler can then check if they’re in that state before processing their age input. This way, each user receives exactly one response and prevents listener stacking.