Creating a concurrent Telegram bot in Ruby

I’m trying to build a Telegram bot that can handle multiple users at once. Each user should have their own session with a complex decision tree. Right now, I’m using the telegram-bot-ruby gem, but my current setup breaks when multiple people use the bot simultaneously.

Here’s a simple version of what I’ve got:

Telegram::Bot::Client.run(token) do |bot|
  bot.listen do |msg|
    case msg.text
    when '/begin'
      bot.api.send_message(chat_id: msg.chat.id, text: "Hi there! What's your name?")
      bot.listen do |name_msg|
        user_name = name_msg.text
        break
      end
      bot.api.send_message(chat_id: msg.chat.id, text: "Hey #{user_name}, how old are you?")
      bot.listen do |age_msg|
        user_age = age_msg.text
        break
      end
    when '/quit'
      bot.api.send_message(chat_id: msg.chat.id, text: "See you later!")
    else
      bot.api.send_message(chat_id: msg.chat.id, text: "Type /begin to start")
    end
  end
end

Do I need to make this async? Or is there a better way to handle multiple users? I’m not using Rails, just a standalone script. Any tips would be awesome!

Your approach is on the right track, but it’s not optimal for handling multiple users concurrently. I’d suggest implementing a state machine pattern using a database (SQLite or PostgreSQL) to store user states. This allows you to manage each user’s session independently.

Here’s a high-level overview of how you could restructure your code:

  1. Use a database to store user states and conversation progress.
  2. Implement a message handler that processes incoming messages based on the user’s current state.
  3. Update the user’s state in the database after each interaction.

This approach eliminates the need for nested ‘listen’ blocks and allows your bot to handle multiple users simultaneously without conflicts. It’s more scalable and easier to maintain in the long run.

Remember to use proper error handling and consider rate limiting to prevent abuse. Good luck with your project!

I’ve actually built a few Telegram bots in Ruby, and I ran into similar issues when scaling up to multiple users. The key is to move away from the nested listen blocks and implement a state machine for each user. Here’s what worked for me:

I used the ‘redis’ gem to store user states and the ‘concurrent-ruby’ gem for handling multiple users simultaneously. Each user gets their own ‘conversation’ object that manages their state.

The main loop just routes incoming messages to the appropriate conversation handler. This way, you can handle multiple users without blocking.

It took some refactoring, but the end result was much more robust and scalable. The bot could handle hundreds of concurrent users without breaking a sweat.

One gotcha to watch out for: make sure to implement proper error handling and logging. It’ll save you a lot of headaches when debugging issues in production.

Hope this helps point you in the right direction!

hey, try sidekiq for background jobs so the main thread doesn’t get blocked. also, using a db for user states can help pick up each convo where it left off. cheers and good luck with your bot!