https://github.com/atipugin/telegram-bot-ruby
Ruby wrapper for Telegram's Bot API
https://github.com/atipugin/telegram-bot-ruby
ruby telegram telegram-bot
Last synced: 1 day ago
JSON representation
Ruby wrapper for Telegram's Bot API
- Host: GitHub
- URL: https://github.com/atipugin/telegram-bot-ruby
- Owner: atipugin
- License: wtfpl
- Created: 2015-06-27T17:40:29.000Z (almost 11 years ago)
- Default Branch: master
- Last Pushed: 2025-02-13T04:37:12.000Z (about 1 year ago)
- Last Synced: 2025-04-12T13:57:36.324Z (about 1 year ago)
- Topics: ruby, telegram, telegram-bot
- Language: Ruby
- Homepage: https://core.telegram.org/bots/api
- Size: 445 KB
- Stars: 1,386
- Watchers: 36
- Forks: 223
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-telegram - telegram-bot-ruby - Ruby (Bot Libraries)
- awesome-telegram - telegram-bot-ruby
- awesome-chatops - Telegram-bot-ruby
- awesome-telegram - telegram-bot-ruby
- awesome-telegram - telegram-bot-ruby - Ruby. (Bot Libraries / Unofficial)
- awesome-chatops - Telegram-bot-ruby
- awesome-telegram-cn - telegram-bot-ruby
- awesome-telegram-bots - telegram-bot-ruby - Ruby wrapper for Telegram Bot API (Libraries / Ruby)
README
# telegram-bot-ruby
Ruby wrapper for [Telegram's Bot API](https://core.telegram.org/bots/api).
[](http://badge.fury.io/rb/telegram-bot-ruby)
[](https://github.com/atipugin/telegram-bot-ruby/actions)
[](https://codeclimate.com/github/atipugin/telegram-bot-ruby/maintainability)
## Installation
Add following line to your Gemfile:
```ruby
gem 'telegram-bot-ruby', '~> 2.7'
```
And then execute:
```shell
bundle
```
Or install it system-wide:
```shell
gem install telegram-bot-ruby
```
## Usage
First things first, you need to [obtain a token](https://core.telegram.org/bots#6-botfather) for your bot.
Then create your Telegram bot like this:
```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
```
Note that `bot.api` object implements
[Telegram Bot API methods](https://core.telegram.org/bots/api#available-methods) as is.
So you can invoke any method inside the block without any problems.
All methods are available in both *snake_case* and *camelCase* notations.
If you need to start a bot in development mode you have to pass `environment: :test`:
```ruby
Telegram::Bot::Client.run(token, environment: :test) do |bot|
# ...
end
```
Same thing about `message` object: it implements [Message](https://core.telegram.org/bots/api#message) spec,
so you always know what to expect from it.
To gracefully stop the bot, for example by `INT` signal (Ctrl-C), call the `bot.stop` method:
```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
```
## Webhooks
If you are going to use [webhooks](https://core.telegram.org/bots/api#setwebhook)
instead of [long polling](https://core.telegram.org/bots/api#getupdates),
you need to implement your own webhook callbacks server.
Take a look at [this repo](https://github.com/solyaris/BOTServer) as an example.
## Proxy
As some countries block access to Telegram, you can set up your own proxy and use it to access Telegram API.
In this case you need to configure API URL:
```ruby
Telegram::Bot::Client.run(token, url: 'https://proxy.example.com') do |bot|
# ...
end
```
If you want to use a SOCKS5 proxy with the [Excon](https://github.com/excon/excon) adapter,
you can configure it like this:
```ruby
Telegram::Bot.configure do |config|
config.adapter = :excon
config.adapter_options = { socks5_proxy: 'socks5://socks.proxy:1080' }
end
```
## Custom keyboards
You can use your own [custom keyboards](https://core.telegram.org/bots#keyboards).
Here is an example:
```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
```
Furthermore, you can ask user to share location or phone number using `KeyboardButton`:
```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
```
## Inline keyboards
[Bot API 2.0](https://core.telegram.org/bots/2-0-intro) brought us new inline keyboards.
Example:
```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
```
## Inline bots
If you are going to create [inline bot](https://core.telegram.org/bots/inline), check the example below:
```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
```
Now, with `inline` mode enabled, your `message` object can be an instance of any
[update type](https://core.telegram.org/bots/api#update) supported by the Bot API.
That's why you need to check the type of each message and decide how to handle it.
Using `answer_inline_query` you can send query results to user.
`results` field must be an array of [query result objects](https://core.telegram.org/bots/api#inlinequeryresult).
## File upload
Your bot can even upload files
([photos](https://core.telegram.org/bots/api#sendphoto),
[audio](https://core.telegram.org/bots/api#sendaudio),
[documents](https://core.telegram.org/bots/api#senddocument),
[stickers](https://core.telegram.org/bots/api#sendsticker),
[video](https://core.telegram.org/bots/api#sendvideo))
to Telegram servers.
Just like this:
```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
```
## Logging
By default, bot doesn't log anything (uses `NullLogger`).
You can change this behavior and provide your own logger class.
See example below:
```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
```
## Connection adapters
We rely on [faraday](https://github.com/lostisland/faraday) under the hood.
You can use any of supported adapters (for example, `net/http/persistent`):
```ruby
require 'net/http/persistent'
Telegram::Bot.configure do |config|
config.adapter = :net_http_persistent
end
```
If your adapter supports additional configuration, you can pass options as a hash:
```ruby
Telegram::Bot.configure do |config|
config.adapter = :httpx
config.adapter_options = { persistent: false }
end
```
## Maintenance
This gem provides rake tasks to parse the official [Telegram Bot API documentation](https://core.telegram.org/bots/api) and regenerate types and API methods.
### Parsing
Parse types and methods from the official documentation:
```shell
rake parse:types # Parses types to data/types.json
rake parse:methods # Parses methods to data/methods.json
```
### Rebuilding
Regenerate Ruby code from the parsed JSON data:
```shell
rake rebuild:types # Rebuilds lib/telegram/bot/types/*.rb
rake rebuild:methods # Rebuilds lib/telegram/bot/api/endpoints.rb
```
## Contributing
1. Fork it.
2. Create your feature branch (`git checkout -b my-new-feature`).
3. Commit your changes (`git commit -am 'Add some feature'`).
4. Push to the branch (`git push origin my-new-feature`).
5. Create a new Pull Request.