Skip to content

Commit

Permalink
Release v1 version (#265)
Browse files Browse the repository at this point in the history
  • Loading branch information
atipugin authored Feb 13, 2023
1 parent 0685a5b commit 02de716
Show file tree
Hide file tree
Showing 152 changed files with 3,049 additions and 916 deletions.
2 changes: 2 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BOT_API_ENV=test
BOT_API_TOKEN=
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
matrix:
ruby:
- 2.7
- 3.1
- 3.2
steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -31,7 +31,7 @@ jobs:
matrix:
ruby:
- 2.7
- 3.1
- 3.2
env:
BOT_API_ENV: test
BOT_API_TOKEN: ${{ secrets.BOT_API_TOKEN }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Gemfile.lock

.bundle/
.env
pkg/
vendor/bundle/
3 changes: 2 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ Style/FrozenStringLiteralComment:
- bin/console

Metrics/BlockLength:
IgnoredMethods:
AllowedMethods:
- context
- describe
- task

Layout/LineLength:
Max: 120
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 1.0.0

- Replace [virtus](https://github.com/solnic/virtus) with [dry-struct](https://github.com/dry-rb/dry-struct)
- Use [zeitwerk](https://github.com/fxn/zeitwerk) for code loading
- Implement [Bot API 6.4](https://core.telegram.org/bots/api#december-30-2022)
- Implement [Bot API 6.5](https://core.telegram.org/bots/api#february-3-2023)

## 0.23.0

- Rename `Telegram::Bot.configuration` options:
Expand Down
9 changes: 9 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,12 @@
source 'https://rubygems.org'

gemspec

gem 'dotenv', '~> 2.8'
gem 'nokogiri', '~> 1.13'
gem 'pry'
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.4'
gem 'rubocop', '~> 1.27'
gem 'rubocop-rake'
gem 'rubocop-rspec', '~> 2.10'
53 changes: 40 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ Ruby wrapper for [Telegram's Bot API](https://core.telegram.org/bots/api).
[![Maintainability](https://api.codeclimate.com/v1/badges/7e61fbf5bec86e118fb1/maintainability)](https://codeclimate.com/github/atipugin/telegram-bot-ruby/maintainability)
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks!-🦉-1EAEDB.svg)](https://saythanks.io/to/atipugin)

## 🚧 Upgrading to 1.0

Since v1.0 telegram-bot-ruby uses [dry-struct](https://github.com/dry-rb/dry-struct) instead of [virtus](https://github.com/solnic/virtus). This means that type objects are now immutable and you can't change them after initialization:

```ruby
# This won't work
kb = Telegram::Bot::Types::ReplyKeyboardRemove.new
kb.remove_keyboard = true

# You have to set attributes in constructor instead
kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true)
```

Please make sure it doesn't break your existing code before upgrading to 1.0.

## Installation

Add following line to your Gemfile:
Expand All @@ -18,13 +33,13 @@ gem 'telegram-bot-ruby'
And then execute:

```shell
$ bundle
bundle
```

Or install it system-wide:

```shell
$ gem install telegram-bot-ruby
gem install telegram-bot-ruby
```

## Usage
Expand All @@ -50,8 +65,13 @@ 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 on development mode you have to pass `enviroment: :test` <br>
example: `Telegram::Bot::Client.run(token, enviroment: :test)`
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.

Expand Down Expand Up @@ -80,8 +100,13 @@ bot.listen do |message|
question = 'London is a capital of which country?'
# See more: https://core.telegram.org/bots/api#replykeyboardmarkup
answers =
Telegram::Bot::Types::ReplyKeyboardMarkup
.new(keyboard: [%w(A B), %w(C D)], one_time_keyboard: true)
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
Expand All @@ -95,10 +120,10 @@ Furthermore, you can ask user to share location or phone number using `KeyboardB

```ruby
bot.listen do |message|
kb = [
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
Expand All @@ -117,11 +142,11 @@ bot.listen do |message|
bot.api.send_message(chat_id: message.from.id, text: "Don't touch me!")
end
when Telegram::Bot::Types::Message
kb = [
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
Expand All @@ -137,8 +162,8 @@ 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.']
['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],
Expand Down Expand Up @@ -166,7 +191,8 @@ Your bot can even upload files ([photos](https://core.telegram.org/bots/api#send
bot.listen do |message|
case message.text
when '/photo'
bot.api.send_photo(chat_id: message.chat.id, photo: Faraday::UploadIO.new('~/Desktop/jennifer.jpg', 'image/jpeg'))
path_to_photo = File.expand_path('~/Desktop/jennifer.jpg')
bot.api.send_photo(chat_id: message.chat.id, photo: Faraday::UploadIO.new(path_to_photo, 'image/jpeg'))
end
end
```
Expand Down Expand Up @@ -199,6 +225,7 @@ end
## Boilerplates

If you don't know how to setup database for your bot or how to use it with different languages here are some boilerplates which can help you to start faster:

- [Ruby Telegram Bot boilerplate](https://github.com/telegram-bots/ruby-telegram-bot-boilerplate)

## Contributing
Expand Down
43 changes: 43 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,46 @@ end
RSpec::Core::RakeTask.new(:spec)

task default: :spec

desc 'Dump type definitions from docs to YAML'
task :dump_type_attributes do
require File.expand_path('lib/telegram/bot', __dir__)
require 'nokogiri'
require 'open-uri'
require 'yaml'

# Preload every type we have
Zeitwerk::Loader.eager_load_all
types = Telegram::Bot::Types::Base.descendants.map { |c| c.name.split('::').last }

# Fetch and parse docs
doc = Nokogiri::HTML(URI.open('https://core.telegram.org/bots/api').read)

result = types.to_h do |type|
# This is very hacky but working way to find table containing attributes for
# given type. Basic idea is to find heading with type and then iterate until
# we find table with attributes or next heading (because sometimes type
# doesn't have any attributes).
element = doc.at_xpath(%{//h4[text() = "#{type}"]})
loop do
element = element.next_element
break if %w[table h4].include?(element.name)
end

attributes = element.xpath('.//tbody//tr').map do |el|
cells = el.children.select { |c| c.name == 'td' }
{
'name' => cells[0].text,
'required' => !cells[2].text.start_with?('Optional.')
}
end

[type, attributes]
end

# Write everything to fixture file
File.write(
File.expand_path('spec/support/type_attributes.yml', __dir__),
result.to_yaml
)
end
16 changes: 7 additions & 9 deletions lib/telegram/bot.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
# frozen_string_literal: true

require 'virtus'
require 'logger'
require 'json'
require 'faraday'
require 'faraday/multipart'

require 'telegram/bot/types'
require 'telegram/bot/exceptions'
require 'telegram/bot/api'
require 'telegram/bot/null_logger'
require 'telegram/bot/client'
require 'telegram/bot/version'
require 'telegram/bot/configuration'
require 'zeitwerk'
require 'dry-struct'

module Telegram
module Bot
Expand All @@ -29,3 +22,8 @@ def self.configure
end
end
end

loader = Zeitwerk::Loader.new
loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
loader.push_dir("#{__dir__}/bot", namespace: Telegram::Bot)
loader.setup
4 changes: 3 additions & 1 deletion lib/telegram/bot/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class Api
approveChatJoinRequest declineChatJoinRequest banChatSenderChat
unbanChatSenderChat answerWebAppQuery setChatMenuButton
getChatMenuButton setMyDefaultAdministratorRights
getMyDefaultAdministratorRights createInvoiceLink
getMyDefaultAdministratorRights createInvoiceLink editGeneralForumTopic
closeGeneralForumTopic reopenGeneralForumTopic hideGeneralForumTopic
unhideGeneralForumTopic
].freeze

attr_reader :token, :url, :environment
Expand Down
4 changes: 0 additions & 4 deletions lib/telegram/bot/exceptions.rb

This file was deleted.

Loading

0 comments on commit 02de716

Please sign in to comment.