Creating sequential conversation flow in Telegram bot using Node.js

I’m building a Telegram bot with Node.js and need help implementing a multi-step conversation system. Right now I can handle basic commands like this:

telegramBot.on('message', function(message) {
  if (message.text === '/help') {
    telegramBot.sendMessage(message.chat.id, 'Welcome to our service bot');
  }
});

This works fine for simple responses when someone sends /help. But I want to build a conversation that has multiple steps. For example, when a user sends /order, the bot should ask what category they want. Then based on their answer, show subcategories, then ask for quantity, and so on.

What’s the best approach to track where each user is in the conversation flow? Should I store the current state somewhere? Do I need a database to remember what step each person is on, or is there a simpler way to handle this kind of sequential interaction?

You’ll need state management for multi-step conversations. I’ve done this before - a simple in-memory object works great for basic bots. Just use something like userStates[userId] = { step: 'awaiting_category', data: {} } to track where each user is. But there’s a catch - if your bot restarts, you lose everything. For production, go with Redis or even a JSON file that updates. Store the current step and collected data for each user ID. Here’s what really helped me: create a conversation handler that checks the user’s state before processing messages. You can route messages to the right handler based on where they are in the conversation instead of just looking for specific commands.

State machines are perfect for this. I built something similar where each conversation step is its own state with clear transitions. The trick is treating every user interaction as a state change instead of just tracking random step names. You can use something simple like conversationStates[chatId] = { currentState: 'CATEGORY_SELECTION', context: { orderId: 123 } } and create handlers for each state. What really made mine work was adding fallbacks - when users send random commands mid-conversation, you can either reset their state or handle the interruption smoothly. I started with a local JSON file for dev, then switched to MongoDB later. The state machine approach also makes adding new conversation branches way easier without breaking existing stuff.

Sessions are definitely the way to go. I built mine with middleware that catches all messages first - just check if message.from.id has an active session and route it to the session handler instead of the command parser. A simple Map() works great for storing the current step and answers you’ve collected. Perfect for smaller apps, though you’ll need Redis or something similar when you scale up.