### Webhook Setup with Sinatra Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Configure a webhook for production by setting the webhook URL and handling incoming POST requests. This example uses Sinatra to parse updates and respond. ```ruby require 'telegram/bot' require 'sinatra' TOKEN = ENV['TELEGRAM_BOT_TOKEN'] WEBHOOK_URL = "https://yourdomain.com/webhook/#{TOKEN}" # Register the webhook once at startup api = Telegram::Bot::Api.new(TOKEN) api.set_webhook(url: WEBHOOK_URL) post "/webhook/#{TOKEN}" do request.body.rewind data = JSON.parse(request.body.read) update = Telegram::Bot::Types::Update.new(data.transform_keys(&:to_sym)) msg = update.current_message if msg.is_a?(Telegram::Bot::Types::Message) api.send_message(chat_id: msg.chat.id, text: "You said: #{msg.text}") end status 200 end # Delete webhook to switch back to long polling: # api.delete_webhook ``` -------------------------------- ### Configure Faraday Adapter with Options Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This example configures the `telegram-bot` gem to use the `:httpx` adapter and passes additional options to it. Ensure the `httpx` gem is installed. ```ruby Telegram::Bot.configure do |config| config.adapter = :httpx config.adapter_options = { persistent: false } end ``` -------------------------------- ### Install Gem Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Execute this command after adding the gem to your Gemfile or to install it system-wide. ```shell bundle ``` ```shell gem install telegram-bot-ruby ``` -------------------------------- ### Handle Inline Queries and Send Messages Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This example shows how to handle inline queries and respond with a list of articles. It also includes a basic message handler for regular messages. Ensure the `telegram-bot` gem is installed. ```ruby bot.listen do |message| case message when Telegram::Bot::Types::InlineQuery results = [ ['1', 'First article', 'Very interesting text goes here.'], ['2', 'Second article', 'Another interesting text here.'] ].map do |arr| Telegram::Bot::Types::InlineQueryResultArticle.new( id: arr[0], title: arr[1], input_message_content: Telegram::Bot::Types::InputTextMessageContent.new(message_text: arr[2]) ) end bot.api.answer_inline_query(inline_query_id: message.id, results: results) when Telegram::Bot::Types::Message bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}!") end end ``` -------------------------------- ### Development Mode Bot Initialization Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Start a bot in development mode by passing `environment: :test` during client initialization. ```ruby Telegram::Bot::Client.run(token, environment: :test) do |bot| # ... end ``` -------------------------------- ### Install telegram-bot-ruby Gem Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Add the gem to your project's Gemfile and run bundle install, or install it globally. ```ruby # Gemfile gem 'telegram-bot-ruby', '~> 2.7' ``` ```shell bundle install # or install globally: gem install telegram-bot-ruby ``` -------------------------------- ### Basic Bot Initialization and Listening Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Initialize your Telegram bot with your API token and start listening for messages. Handles '/start' and '/stop' commands by sending greetings. ```ruby require 'telegram/bot' token = 'YOUR_TELEGRAM_BOT_API_TOKEN' Telegram::Bot::Client.run(token) do |bot| bot.listen do |message| case message.text when '/start' bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}") when '/stop' bot.api.send_message(chat_id: message.chat.id, text: "Bye, #{message.from.first_name}") end end end ``` -------------------------------- ### Start a Long-Polling Bot with Client.run Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Use Client.run to initialize the API connection and start an infinite long-polling loop. The bot object is yielded to the block for processing updates via bot.listen. ```ruby require 'telegram/bot' TOKEN = ENV['TELEGRAM_BOT_TOKEN'] Telegram::Bot::Client.run(TOKEN) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::Message case message.text when '/start' bot.api.send_message( chat_id: message.chat.id, text: "Hello, #{message.from.first_name}! I'm online." ) when '/stop' bot.api.send_message(chat_id: message.chat.id, text: 'Goodbye!') else bot.api.send_message(chat_id: message.chat.id, text: "You said: #{message.text}") end end end end ``` -------------------------------- ### Configure Bot Logging Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This example shows how to configure the bot to use a custom logger, in this case, logging to standard error. The `Logger.new($stderr)` part initializes the logger. ```ruby Telegram::Bot::Client.run(token, logger: Logger.new($stderr)) do |bot| bot.logger.info('Bot has been started') bot.listen do |message| # ... end end ``` -------------------------------- ### Register and Query Bot Commands Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Use `set_my_commands` to register commands visible in the Telegram UI and `get_my_commands` to verify them. This example also includes basic message handling for registered commands. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| # Register commands shown in the "/" menu bot.api.set_my_commands( commands: [ Telegram::Bot::Types::BotCommand.new(command: 'start', description: 'Start the bot'), Telegram::Bot::Types::BotCommand.new(command: 'help', description: 'Show help'), Telegram::Bot::Types::BotCommand.new(command: 'stop', description: 'Stop the bot') ] ) # Verify they were registered commands = bot.api.get_my_commands commands.each { |cmd| puts "/#{cmd.command} — #{cmd.description}" } # => /start — Start the bot # => /help — Show help # => /stop — Stop the bot bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) case message.text when '/start' then bot.api.send_message(chat_id: message.chat.id, text: 'Welcome!') when '/help' then bot.api.send_message(chat_id: message.chat.id, text: 'Use /start to begin.') when '/stop' then bot.api.send_message(chat_id: message.chat.id, text: 'Bye!') end end end ``` -------------------------------- ### Global Bot Configuration Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Configure global settings for the Telegram bot client, such as HTTP adapter, connection timeouts, and custom API URLs. This setup is done before running the bot. ```ruby require 'telegram/bot' require 'net/http/persistent' # Global adapter + timeout configuration Telegram::Bot.configure do |config| config.adapter = :net_http_persistent # persistent connections config.connection_timeout = 30 # seconds, default: 20 config.connection_open_timeout = 10 # seconds, default: 20 end ``` ```ruby # SOCKS5 proxy example (requires excon adapter) Telegram::Bot.configure do |config| config.adapter = :excon config.adapter_options = { socks5_proxy: 'socks5://127.0.0.1:1080' } end ``` ```ruby # Custom API URL proxy Telegram::Bot::Client.run( ENV['TELEGRAM_BOT_TOKEN'], url: 'https://my-telegram-proxy.example.com', logger: Logger.new($stdout) ) do |bot| bot.listen { |msg| bot.api.send_message(chat_id: msg.chat.id, text: 'Via proxy!') if msg.is_a?(Telegram::Bot::Types::Message) } end ``` -------------------------------- ### Configure Faraday Connection Adapter Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This snippet configures the `telegram-bot` gem to use the `:net_http_persistent` Faraday adapter. Ensure the `net-http-persistent` gem is installed. ```ruby require 'net/http/persistent' Telegram::Bot.configure do |config| config.adapter = :net_http_persistent end ``` -------------------------------- ### Telegram::Bot::Client.run — Start a long-polling bot Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt The primary entry point for starting a bot using long polling. It initializes the API connection and starts an infinite loop to process updates. ```APIDOC ## Telegram::Bot::Client.run — Start a long-polling bot `Client.run` is the primary entry point. It initialises the API connection and starts an infinite long-polling loop, yielding the `bot` object to the block so you can call `bot.listen` to process updates. ```ruby require 'telegram/bot' TOKEN = ENV['TELEGRAM_BOT_TOKEN'] Telegram::Bot::Client.run(TOKEN) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::Message case message.text when '/start' bot.api.send_message( chat_id: message.chat.id, text: "Hello, #{message.from.first_name}! I'm online." ) when '/stop' bot.api.send_message(chat_id: message.chat.id, text: 'Goodbye!') else bot.api.send_message(chat_id: message.chat.id, text: "You said: #{message.text}") end end end end ``` ``` -------------------------------- ### Manual Bot Lifecycle Control with Client.new Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Instantiate the client manually to wire up signal handlers for graceful shutdown. Use bot.stop to end the polling loop. ```ruby require 'telegram/bot' bot = Telegram::Bot::Client.new(ENV['TELEGRAM_BOT_TOKEN']) Signal.trap('INT') do puts "\nStopping bot…" bot.stop # sets @running = false; the current fetch_updates request finishes before exiting end bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) bot.api.send_message(chat_id: message.chat.id, text: "Echo: #{message.text}") end ``` -------------------------------- ### Build Custom Reply Keyboards with ReplyKeyboardMarkup Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Use ReplyKeyboardMarkup and KeyboardButton to create custom reply keyboards, including buttons for sharing contact or location. Set one_time_keyboard and resize_keyboard options as needed. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) case message.text when '/quiz' keyboard = Telegram::Bot::Types::ReplyKeyboardMarkup.new( keyboard: [ [{ text: 'Paris' }, { text: 'London' }], [{ text: 'Berlin' }, { text: 'Madrid' }] ], one_time_keyboard: true, resize_keyboard: true ) bot.api.send_message( chat_id: message.chat.id, text: 'What is the capital of France?', reply_markup: keyboard ) when '/contact' kb = [[ Telegram::Bot::Types::KeyboardButton.new(text: 'Share phone', request_contact: true), Telegram::Bot::Types::KeyboardButton.new(text: 'Share location', request_location: true) ]] markup = Telegram::Bot::Types::ReplyKeyboardMarkup.new(keyboard: kb, resize_keyboard: true) bot.api.send_message(chat_id: message.chat.id, text: 'Please share:', reply_markup: markup) when '/hide' remove_kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true) bot.api.send_message(chat_id: message.chat.id, text: 'Keyboard removed.', reply_markup: remove_kb) end end end ``` -------------------------------- ### Create Inline Keyboards with InlineKeyboardMarkup Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Generate inline buttons with URLs or callback data using InlineKeyboardMarkup and InlineKeyboardButton. Handle CallbackQuery updates to respond to button presses. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::CallbackQuery case message.data when 'yes' bot.api.answer_callback_query(callback_query_id: message.id, text: 'You chose Yes!') bot.api.send_message(chat_id: message.from.id, text: 'Great choice!') when 'no' bot.api.answer_callback_query(callback_query_id: message.id, text: 'You chose No.') bot.api.send_message(chat_id: message.from.id, text: 'Maybe next time.') end when Telegram::Bot::Types::Message buttons = [[ Telegram::Bot::Types::InlineKeyboardButton.new(text: '✅ Yes', callback_data: 'yes'), Telegram::Bot::Types::InlineKeyboardButton.new(text: '❌ No', callback_data: 'no'), Telegram::Bot::Types::InlineKeyboardButton.new(text: '🌐 Docs', url: 'https://core.telegram.org/bots/api') ]] markup = Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: buttons) bot.api.send_message( chat_id: message.chat.id, text: 'Do you like this bot?', reply_markup: markup ) end end end ``` -------------------------------- ### SOCKS5 Proxy Configuration with Excon Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Configure the gem to use a SOCKS5 proxy with the Excon adapter for network requests. ```ruby Telegram::Bot.configure do |config| config.adapter = :excon config.adapter_options = { socks5_proxy: 'socks5://socks.proxy:1080' } end ``` -------------------------------- ### File Uploads with send_photo, send_document, send_audio Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Upload files using Faraday::Multipart::FilePart for local files. Any send_* media method follows the same pattern. ```ruby require 'telegram/bot' require 'faraday/multipart' Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) case message.text when '/photo' bot.api.send_photo( chat_id: message.chat.id, photo: Faraday::Multipart::FilePart.new('/tmp/photo.jpg', 'image/jpeg'), caption: 'Here is your photo!' ) when '/doc' bot.api.send_document( chat_id: message.chat.id, document: Faraday::Multipart::FilePart.new('/tmp/report.pdf', 'application/pdf'), caption: 'Your report' ) when '/audio' bot.api.send_audio( chat_id: message.chat.id, audio: Faraday::Multipart::FilePart.new('/tmp/track.mp3', 'audio/mpeg') ) end end end ``` -------------------------------- ### Telegram::Bot::Client — Test / development environment Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Use the `:test` environment to route API calls to Telegram's test datacenter. This prevents development activities from affecting the production environment. ```APIDOC ## Telegram::Bot::Client — Test / development environment Pass `environment: :test` to route API calls to Telegram's test datacenter, keeping development activity off production. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN'], environment: :test) do |bot| # All requests go to /bot/test/ instead of /bot/ bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) bot.api.send_message(chat_id: message.chat.id, text: '[TEST] Hello!') end end ``` ``` -------------------------------- ### Handle Callback Queries and Send Messages with Inline Keyboards Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This snippet demonstrates how to handle callback queries from inline buttons and send messages with custom inline keyboards. It requires the `telegram-bot` gem. ```ruby bot.listen do |message| case message when Telegram::Bot::Types::CallbackQuery # Here you can handle your callbacks from inline buttons if message.data == 'touch' bot.api.send_message(chat_id: message.from.id, text: "Don't touch me!") end when Telegram::Bot::Types::Message kb = [[ Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Go to Google', url: 'https://google.com'), Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Touch me', callback_data: 'touch'), Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Switch to inline', switch_inline_query: 'some text') ]] markup = Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: kb) bot.api.send_message(chat_id: message.chat.id, text: 'Make a choice', reply_markup: markup) end end ``` -------------------------------- ### Test/Development Environment Routing Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Use the `:test` environment option to route API calls to Telegram's test datacenter. This prevents development activity from affecting the production environment. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN'], environment: :test) do |bot| # All requests go to /bot/test/ instead of /bot/ bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) bot.api.send_message(chat_id: message.chat.id, text: '[TEST] Hello!') end end ``` -------------------------------- ### Webhook Mode Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Configure the bot to use webhooks for receiving updates, which is recommended for production deployments. This involves setting a webhook URL and handling incoming POST requests. ```APIDOC ## Webhook mode For production deployments, use webhooks instead of long polling by calling `set_webhook` and handling incoming POST requests in your own web framework. ```ruby require 'telegram/bot' require 'sinatra' TOKEN = ENV['TELEGRAM_BOT_TOKEN'] WEBHOOK_URL = "https://yourdomain.com/webhook/#{TOKEN}" # Register the webhook once at startup api = Telegram::Bot::Api.new(TOKEN) api.set_webhook(url: WEBHOOK_URL) post "/webhook/#{TOKEN}" do request.body.rewind data = JSON.parse(request.body.read) update = Telegram::Bot::Types::Update.new(data.transform_keys(&:to_sym)) msg = update.current_message if msg.is_a?(Telegram::Bot::Types::Message) api.send_message(chat_id: msg.chat.id, text: "You said: #{msg.text}") end status 200 end # Delete webhook to switch back to long polling: # api.delete_webhook ``` ``` -------------------------------- ### Custom Keyboard for Contact and Location Sharing Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Create a custom keyboard that prompts the user to share their phone number or location. ```ruby bot.listen do |message| kb = [[ Telegram::Bot::Types::KeyboardButton.new(text: 'Give me your phone number', request_contact: true), Telegram::Bot::Types::KeyboardButton.new(text: 'Show me your location', request_location: true) ]] markup = Telegram::Bot::Types::ReplyKeyboardMarkup.new(keyboard: kb) bot.api.send_message(chat_id: message.chat.id, text: 'Hey!', reply_markup: markup) end ``` -------------------------------- ### Graceful Bot Shutdown Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Set up a trap for the 'INT' signal (Ctrl-C) to gracefully stop the bot using `bot.stop`. ```ruby bot = Telegram::Bot::Client.new(token) Signal.trap('INT') do bot.stop end bot.listen do |message| # it will be in an infinity loop until `bot.stop` command # (with a small delay for the current `fetch_updates` request) end ``` -------------------------------- ### Telegram::Bot::Client.new + bot.stop — Manual lifecycle control Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Instantiate the client manually for more control over the bot's lifecycle, including graceful shutdown using signal handlers. ```APIDOC ## Telegram::Bot::Client.new + bot.stop — Manual lifecycle control Instantiate the client manually to wire up signal handlers for graceful shutdown. ```ruby require 'telegram/bot' bot = Telegram::Bot::Client.new(ENV['TELEGRAM_BOT_TOKEN']) Signal.trap('INT') do puts "\nStopping bot…" bot.stop # sets @running = false; the current fetch_updates request finishes before exiting end bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) bot.api.send_message(chat_id: message.chat.id, text: "Echo: #{message.text}") end ``` ``` -------------------------------- ### Parse Telegram Bot API Methods Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This command-line instruction uses Rake to parse the official Telegram Bot API documentation and generate method definitions into `data/methods.json`. ```shell rake parse:methods # Parses methods to data/methods.json ``` -------------------------------- ### Telegram::Bot.configure Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Globally configure the Telegram Bot client. This includes setting the HTTP adapter, connection timeouts, and a custom API URL for proxies. ```APIDOC ## Telegram::Bot.configure — Global configuration Set the Faraday HTTP adapter, connection timeouts, and a custom API URL (for proxies) globally before running the bot. ```ruby require 'telegram/bot' require 'net/http/persistent' # Global adapter + timeout configuration Telegram::Bot.configure do |config| config.adapter = :net_http_persistent # persistent connections config.connection_timeout = 30 # seconds, default: 20 config.connection_open_timeout = 10 # seconds, default: 20 end # SOCKS5 proxy example (requires excon adapter) Telegram::Bot.configure do |config| config.adapter = :excon config.adapter_options = { socks5_proxy: 'socks5://127.0.0.1:1080' } end # Custom API URL proxy Telegram::Bot::Client.run( ENV['TELEGRAM_BOT_TOKEN'], url: 'https://my-telegram-proxy.example.com', logger: Logger.new($stdout) ) do |bot| bot.listen { |msg| bot.api.send_message(chat_id: msg.chat.id, text: 'Via proxy!') if msg.is_a?(Telegram::Bot::Types::Message) } end ``` ``` -------------------------------- ### Telegram::Bot::Types::InlineKeyboardMarkup Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Create inline buttons with URLs, callback data, or switch-to-inline queries. Handle CallbackQuery updates in the same listen block. ```APIDOC ## Telegram::Bot::Types::InlineKeyboardMarkup — Inline keyboards and callback queries Create inline buttons with URLs, callback data, or switch-to-inline queries. Handle `CallbackQuery` updates in the same `listen` block. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::CallbackQuery case message.data when 'yes' bot.api.answer_callback_query(callback_query_id: message.id, text: 'You chose Yes!') bot.api.send_message(chat_id: message.from.id, text: 'Great choice!') when 'no' bot.api.answer_callback_query(callback_query_id: message.id, text: 'You chose No.') bot.api.send_message(chat_id: message.from.id, text: 'Maybe next time.') end when Telegram::Bot::Types::Message buttons = [[ Telegram::Bot::Types::InlineKeyboardButton.new(text: '✅ Yes', callback_data: 'yes'), Telegram::Bot::Types::InlineKeyboardButton.new(text: '❌ No', callback_data: 'no'), Telegram::Bot::Types::InlineKeyboardButton.new(text: '🌐 Docs', url: 'https://core.telegram.org/bots/api') ]] markup = Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: buttons) bot.api.send_message( chat_id: message.chat.id, text: 'Do you like this bot?', reply_markup: markup ) end end end ``` ``` -------------------------------- ### Proxy Configuration Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Configure the bot to use a custom API URL for accessing Telegram, useful when Telegram is blocked. ```ruby Telegram::Bot::Client.run(token, url: 'https://proxy.example.com') do |bot| # ... end ``` -------------------------------- ### Custom Keyboard Markup for Questions Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Send a message with a custom reply keyboard to ask a multiple-choice question. Users can select one of the predefined options. ```ruby bot.listen do |message| case message.text when '/start' question = 'London is a capital of which country?' # See more: https://core.telegram.org/bots/api#replykeyboardmarkup answers = Telegram::Bot::Types::ReplyKeyboardMarkup.new( keyboard: [ [{ text: 'A' }, { text: 'B' }], [{ text: 'C' }, { text: 'D' }] ], one_time_keyboard: true ) bot.api.send_message(chat_id: message.chat.id, text: question, reply_markup: answers) when '/stop' # See more: https://core.telegram.org/bots/api#replykeyboardremove kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true) bot.api.send_message(chat_id: message.chat.id, text: 'Sorry to see you go :(', reply_markup: kb) end end ``` -------------------------------- ### Respond to Inline Queries with answer_inline_query Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Implement inline bot functionality by responding to InlineQuery updates with an array of InlineQueryResult objects. This allows users to query your bot from any chat. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::InlineQuery results = [ Telegram::Bot::Types::InlineQueryResultArticle.new( id: '1', title: 'Ruby docs', description: 'Official Ruby documentation', input_message_content: Telegram::Bot::Types::InputTextMessageContent.new( message_text: 'https://ruby-doc.org' ) ), Telegram::Bot::Types::InlineQueryResultArticle.new( id: '2', title: "Query: #{message.query}", description: 'Echo the search query back', input_message_content: Telegram::Bot::Types::InputTextMessageContent.new( message_text: "You searched for: #{message.query}" ) ) ] bot.api.answer_inline_query( inline_query_id: message.id, results: results, cache_time: 10 ) when Telegram::Bot::Types::Message bot.api.send_message(chat_id: message.chat.id, text: 'Try me inline: @your_bot query') end end end ``` -------------------------------- ### Add Gem to Gemfile Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md Add this line to your Gemfile to include the gem in your project. ```ruby gem 'telegram-bot-ruby', '~> 2.7' ``` -------------------------------- ### Upload a Photo using File Upload Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This snippet demonstrates how to upload a photo file to Telegram using the bot API. It requires the `faraday-multipart` gem for `FilePart`. Make sure the file path is correct. ```ruby bot.listen do |message| case message.text when '/photo' path_to_photo = File.expand_path('~/Desktop/jennifer.jpg') bot.api.send_photo(chat_id: message.chat.id, photo: Faraday::Multipart::FilePart.new(path_to_photo, 'image/jpeg')) end end ``` -------------------------------- ### Bot Command Menu: set_my_commands / get_my_commands Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Register slash commands in Telegram's UI command menu and query them back. This allows users to see available commands when they type '/' in the chat. ```APIDOC ## bot.api.set_my_commands / get_my_commands — Bot command menu Register slash commands in Telegram's UI command menu and query them back. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| # Register commands shown in the "/" menu bot.api.set_my_commands( commands: [ Telegram::Bot::Types::BotCommand.new(command: 'start', description: 'Start the bot'), Telegram::Bot::Types::BotCommand.new(command: 'help', description: 'Show help'), Telegram::Bot::Types::BotCommand.new(command: 'stop', description: 'Stop the bot') ] ) # Verify they were registered commands = bot.api.get_my_commands commands.each { |cmd| puts "/#{cmd.command} — #{cmd.description}" } # => /start — Start the bot # => /help — Show help # => /stop — Stop the bot bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) case message.text when '/start' then bot.api.send_message(chat_id: message.chat.id, text: 'Welcome!') when '/help' then bot.api.send_message(chat_id: message.chat.id, text: 'Use /start to begin.') when '/stop' then bot.api.send_message(chat_id: message.chat.id, text: 'Bye!') end end end ``` ``` -------------------------------- ### bot.api.send_photo / send_document — File uploads Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Upload files to Telegram using `Faraday::Multipart::FilePart` for local files. This applies to any `send_*` media method. ```APIDOC ## bot.api.send_photo / send_document — File uploads Upload files to Telegram using `Faraday::Multipart::FilePart` for local files. Any `send_*` media method works the same way. ```ruby require 'telegram/bot' require 'faraday/multipart' Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) case message.text when '/photo' bot.api.send_photo( chat_id: message.chat.id, photo: Faraday::Multipart::FilePart.new('/tmp/photo.jpg', 'image/jpeg'), caption: 'Here is your photo!' ) when '/doc' bot.api.send_document( chat_id: message.chat.id, document: Faraday::Multipart::FilePart.new('/tmp/report.pdf', 'application/pdf'), caption: 'Your report' ) when '/audio' bot.api.send_audio( chat_id: message.chat.id, audio: Faraday::Multipart::FilePart.new('/tmp/track.mp3', 'audio/mpeg') ) end end end ``` ``` -------------------------------- ### bot.api.answer_inline_query Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Respond to InlineQuery updates with an array of InlineQueryResult* objects so users can query the bot from any chat. ```APIDOC ## bot.api.answer_inline_query — Inline bot mode Respond to `InlineQuery` updates with an array of `InlineQueryResult*` objects so users can query the bot from any chat. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::InlineQuery results = [ Telegram::Bot::Types::InlineQueryResultArticle.new( id: '1', title: 'Ruby docs', description: 'Official Ruby documentation', input_message_content: Telegram::Bot::Types::InputTextMessageContent.new( message_text: 'https://ruby-doc.org' ) ), Telegram::Bot::Types::InlineQueryResultArticle.new( id: '2', title: "Query: #{message.query}", description: 'Echo the search query back', input_message_content: Telegram::Bot::Types::InputTextMessageContent.new( message_text: "You searched for: #{message.query}" ) ) ] bot.api.answer_inline_query( inline_query_id: message.id, results: results, cache_time: 10 ) when Telegram::Bot::Types::Message bot.api.send_message(chat_id: message.chat.id, text: 'Try me inline: @your_bot query') end end end ``` ``` -------------------------------- ### Parse Telegram Bot API Types Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This command-line instruction uses Rake to parse the official Telegram Bot API documentation and generate type definitions into `data/types.json`. ```shell rake parse:types # Parses types to data/types.json ``` -------------------------------- ### Telegram::Bot::Types::ReplyKeyboardMarkup Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Build custom reply keyboards with ReplyKeyboardMarkup and KeyboardButton, including contact and location request buttons. ```APIDOC ## Telegram::Bot::Types::ReplyKeyboardMarkup — Custom reply keyboards Build custom reply keyboards with `ReplyKeyboardMarkup` and `KeyboardButton`, including contact and location request buttons. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) case message.text when '/quiz' keyboard = Telegram::Bot::Types::ReplyKeyboardMarkup.new( keyboard: [ [{ text: 'Paris' }, { text: 'London' }], [{ text: 'Berlin' }, { text: 'Madrid' }] ], one_time_keyboard: true, resize_keyboard: true ) bot.api.send_message( chat_id: message.chat.id, text: 'What is the capital of France?', reply_markup: keyboard ) when '/contact' kb = [[ Telegram::Bot::Types::KeyboardButton.new(text: 'Share phone', request_contact: true), Telegram::Bot::Types::KeyboardButton.new(text: 'Share location', request_location: true) ]] markup = Telegram::Bot::Types::ReplyKeyboardMarkup.new(keyboard: kb, resize_keyboard: true) bot.api.send_message(chat_id: message.chat.id, text: 'Please share:', reply_markup: markup) when '/hide' remove_kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true) bot.api.send_message(chat_id: message.chat.id, text: 'Keyboard removed.', reply_markup: remove_kb) end end end ``` ``` -------------------------------- ### Logging Bot Events Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Integrate a Ruby Logger with the Telegram bot client to record incoming messages and bot lifecycle events. The logger instance passed during client initialization is accessible via `bot.logger`. ```ruby require 'telegram/bot' require 'logger' log = Logger.new($stdout) log.level = Logger::INFO Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN'], logger: log) do |bot| bot.logger.info('Bot started successfully') bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) # bot.logger is the same Logger instance passed above bot.logger.info("Message from #{message.from.username}: #{message.text}") bot.api.send_message(chat_id: message.chat.id, text: 'Got it!') end end ``` -------------------------------- ### bot.api — Direct Bot API method calls Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Access all Telegram Bot API methods directly through `bot.api`. Methods are available in both snake_case and camelCase and return strongly-typed objects. ```APIDOC ## bot.api — Direct Bot API method calls `bot.api` exposes every [Telegram Bot API method](https://core.telegram.org/bots/api#available-methods) as a Ruby method in both `snake_case` and `camelCase`. Methods return strongly-typed objects. ```ruby # getMe → returns Telegram::Bot::Types::User me = bot.api.get_me puts "Bot username: @#{me.username}" # => Bot username: @my_awesome_bot puts "Bot id: #{me.id}" # => Bot id: 123456789 # sendMessage → returns Telegram::Bot::Types::Message msg = bot.api.send_message( chat_id: 123456789, text: 'Hello from the API!', parse_mode: 'HTML' ) puts msg.message_id # => 42 # camelCase is also valid: bot.api.sendMessage(chat_id: 123456789, text: 'Same thing') # deleteMessage → returns true/false (Bool endpoint) deleted = bot.api.delete_message(chat_id: 123456789, message_id: msg.message_id) puts deleted # => true ``` ``` -------------------------------- ### Direct Bot API Method Calls Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Access all Telegram Bot API methods via bot.api, supporting both snake_case and camelCase. Methods return strongly-typed objects. ```ruby # getMe → returns Telegram::Bot::Types::User me = bot.api.get_me puts "Bot username: @#{me.username}" # => Bot username: @my_awesome_bot puts "Bot id: #{me.id}" # => Bot id: 123456789 # sendMessage → returns Telegram::Bot::Types::Message msg = bot.api.send_message( chat_id: 123456789, text: 'Hello from the API!', parse_mode: 'HTML' ) puts msg.message_id # => 42 # camelCase is also valid: bot.api.sendMessage(chat_id: 123456789, text: 'Same thing') # deleteMessage → returns true/false (Bool endpoint) deleted = bot.api.delete_message(chat_id: 123456789, message_id: msg.message_id) puts deleted # => true ``` -------------------------------- ### Telegram::Bot::Client — Logging Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Attach a standard Ruby `Logger` to the client to record incoming messages and bot lifecycle events. This helps in debugging and monitoring bot activity. ```APIDOC ## Telegram::Bot::Client — Logging Attach a standard Ruby `Logger` (or any compatible logger) to the client to record incoming messages and bot lifecycle events. ```ruby require 'telegram/bot' require 'logger' log = Logger.new($stdout) log.level = Logger::INFO Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN'], logger: log) do |bot| bot.logger.info('Bot started successfully') bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) # bot.logger is the same Logger instance passed above bot.logger.info("Message from #{message.from.username}: #{message.text}") bot.api.send_message(chat_id: message.chat.id, text: 'Got it!') end end # Output: # I, [2024-01-01T12:00:00] INFO -- : Bot started successfully # I, [2024-01-01T12:00:05] INFO -- : Incoming message: text="Hello" uid=123456 # I, [2024-01-01T12:00:05] INFO -- : Message from alice: Hello ``` ``` -------------------------------- ### Rebuild Ruby API Endpoints from JSON Data Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This Rake task regenerates the Ruby API endpoint files (e.g., `lib/telegram/bot/api/endpoints.rb`) from the parsed JSON data. ```shell rake rebuild:methods # Rebuilds lib/telegram/bot/api/endpoints.rb ``` -------------------------------- ### Telegram::Bot::Exceptions::ResponseError — Error handling Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Handle non-200 responses from the Telegram API by rescuing `Telegram::Bot::Exceptions::ResponseError`. This exception provides `error_code` and the full error data. ```APIDOC ## Telegram::Bot::Exceptions::ResponseError — Error handling All non-200 responses from the Telegram API raise `Telegram::Bot::Exceptions::ResponseError`, which exposes `error_code` and the full parsed error body. ```ruby require 'telegram/bot' bot = Telegram::Bot::Client.new(ENV['TELEGRAM_BOT_TOKEN']) begin # Attempt to send to a nonexistent or forbidden chat bot.api.send_message(chat_id: 0, text: 'This will fail') rescue Telegram::Bot::Exceptions::ResponseError => e puts e.message # => Telegram API has returned the error. (error_code: 400, description: "Bad Request: ...") puts e.error_code # => 400 puts e.data.inspect # => {"ok"=>false, "error_code"=>400, "description"=>"Bad Request: chat not found"} end # Wrapping a full bot run with rescue Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) begin bot.api.send_message(chat_id: message.chat.id, text: 'Hello!') rescue Telegram::Bot::Exceptions::ResponseError => e warn "API error #{e.error_code}: #{e.message}" end end end ``` ``` -------------------------------- ### Edit and Delete Messages with Bot API Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Demonstrates how to edit message text and delete messages using their message_id. This is useful for updating information or removing old messages. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::CallbackQuery # Edit the original message text bot.api.edit_message_text( chat_id: message.message.chat.id, message_id: message.message.message_id, text: "Updated at #{Time.now.strftime('%H:%M:%S')}", parse_mode: 'HTML' ) bot.api.answer_callback_query(callback_query_id: message.id) when Telegram::Bot::Types::Message sent = bot.api.send_message(chat_id: message.chat.id, text: 'This will be edited...') sleep 2 bot.api.edit_message_text( chat_id: message.chat.id, message_id: sent.message_id, text: 'Edited!', parse_mode: 'HTML' ) sleep 2 bot.api.delete_message(chat_id: message.chat.id, message_id: sent.message_id) end end end ``` -------------------------------- ### Rebuild Ruby Types from JSON Data Source: https://github.com/atipugin/telegram-bot-ruby/blob/master/README.md This Rake task regenerates the Ruby type files (e.g., `lib/telegram/bot/types/*.rb`) from the parsed JSON data. ```shell rake rebuild:types # Rebuilds lib/telegram/bot/types/*.rb ``` -------------------------------- ### Handling Telegram API Errors Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Catch `Telegram::Bot::Exceptions::ResponseError` for non-200 API responses. The exception object provides `error_code` and the full parsed error `data`. ```ruby require 'telegram/bot' bot = Telegram::Bot::Client.new(ENV['TELEGRAM_BOT_TOKEN']) begin # Attempt to send to a nonexistent or forbidden chat bot.api.send_message(chat_id: 0, text: 'This will fail') rescue Telegram::Bot::Exceptions::ResponseError => e puts e.message # => Telegram API has returned the error. (error_code: 400, description: "Bad Request: ...") puts e.error_code # => 400 puts e.data.inspect # => {"ok"=>false, "error_code"=>400, "description"=>"Bad Request: chat not found"} end ``` ```ruby # Wrapping a full bot run with rescue Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| next unless message.is_a?(Telegram::Bot::Types::Message) begin bot.api.send_message(chat_id: message.chat.id, text: 'Hello!') rescue Telegram::Bot::Exceptions::ResponseError => e warn "API error #{e.error_code}: #{e.message}" end end end ``` -------------------------------- ### bot.api.edit_message_text / delete_message Source: https://context7.com/atipugin/telegram-bot-ruby/llms.txt Modify or remove previously sent messages using their `message_id`. This allows for dynamic updates to messages or their complete removal. ```APIDOC ## bot.api.edit_message_text / delete_message — Editing and deleting messages Modify or remove previously sent messages using their `message_id`. ```ruby Telegram::Bot::Client.run(ENV['TELEGRAM_BOT_TOKEN']) do |bot| bot.listen do |message| case message when Telegram::Bot::Types::CallbackQuery # Edit the original message text bot.api.edit_message_text( chat_id: message.message.chat.id, message_id: message.message.message_id, text: "Updated at #{Time.now.strftime('%H:%M:%S')}", parse_mode: 'HTML' ) bot.api.answer_callback_query(callback_query_id: message.id) when Telegram::Bot::Types::Message sent = bot.api.send_message(chat_id: message.chat.id, text: 'This will be edited...') sleep 2 bot.api.edit_message_text( chat_id: message.chat.id, message_id: sent.message_id, text: 'Edited!', parse_mode: 'HTML' ) sleep 2 bot.api.delete_message(chat_id: message.chat.id, message_id: sent.message_id) end end end ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.