dialog_bot_ruby 0.8.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +13 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +68 -0
- data/Gemfile +3 -0
- data/LICENSE +14 -0
- data/README.md +197 -0
- data/Rakefile +15 -0
- data/bin/console +6 -0
- data/bin/setup +5 -0
- data/dialog_bot_ruby.gemspec +32 -0
- data/examples/bot.rb +17 -0
- data/lib/telegram/bot/adapters/socks5.rb +24 -0
- data/lib/telegram/bot/api.rb +172 -0
- data/lib/telegram/bot/client.rb +77 -0
- data/lib/telegram/bot/configuration.rb +11 -0
- data/lib/telegram/bot/exceptions/base.rb +7 -0
- data/lib/telegram/bot/exceptions/response_error.rb +32 -0
- data/lib/telegram/bot/exceptions.rb +2 -0
- data/lib/telegram/bot/null_logger.rb +11 -0
- data/lib/telegram/bot/types/animation.rb +13 -0
- data/lib/telegram/bot/types/audio.rb +14 -0
- data/lib/telegram/bot/types/base.rb +10 -0
- data/lib/telegram/bot/types/callback_game.rb +8 -0
- data/lib/telegram/bot/types/callback_query.rb +15 -0
- data/lib/telegram/bot/types/chat.rb +22 -0
- data/lib/telegram/bot/types/chat_member.rb +24 -0
- data/lib/telegram/bot/types/chat_photo.rb +10 -0
- data/lib/telegram/bot/types/chosen_inline_result.rb +15 -0
- data/lib/telegram/bot/types/compactable.rb +26 -0
- data/lib/telegram/bot/types/contact.rb +13 -0
- data/lib/telegram/bot/types/document.rb +13 -0
- data/lib/telegram/bot/types/encrypted_credentials.rb +11 -0
- data/lib/telegram/bot/types/encrypted_passport_element.rb +16 -0
- data/lib/telegram/bot/types/file.rb +11 -0
- data/lib/telegram/bot/types/force_reply.rb +10 -0
- data/lib/telegram/bot/types/game.rb +14 -0
- data/lib/telegram/bot/types/game_high_score.rb +11 -0
- data/lib/telegram/bot/types/inline_keyboard_button.rb +15 -0
- data/lib/telegram/bot/types/inline_keyboard_markup.rb +20 -0
- data/lib/telegram/bot/types/inline_query.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_article.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_audio.rb +17 -0
- data/lib/telegram/bot/types/inline_query_result_cached_audio.rb +14 -0
- data/lib/telegram/bot/types/inline_query_result_cached_document.rb +16 -0
- data/lib/telegram/bot/types/inline_query_result_cached_gif.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_cached_mpeg4_gif.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_cached_photo.rb +16 -0
- data/lib/telegram/bot/types/inline_query_result_cached_sticker.rb +13 -0
- data/lib/telegram/bot/types/inline_query_result_cached_video.rb +16 -0
- data/lib/telegram/bot/types/inline_query_result_cached_voice.rb +15 -0
- data/lib/telegram/bot/types/inline_query_result_contact.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_document.rb +20 -0
- data/lib/telegram/bot/types/inline_query_result_game.rb +12 -0
- data/lib/telegram/bot/types/inline_query_result_gif.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_location.rb +18 -0
- data/lib/telegram/bot/types/inline_query_result_mpeg4_gif.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_photo.rb +19 -0
- data/lib/telegram/bot/types/inline_query_result_venue.rb +20 -0
- data/lib/telegram/bot/types/inline_query_result_video.rb +21 -0
- data/lib/telegram/bot/types/inline_query_result_voice.rb +16 -0
- data/lib/telegram/bot/types/input_contact_message_content.rb +12 -0
- data/lib/telegram/bot/types/input_location_message_content.rb +10 -0
- data/lib/telegram/bot/types/input_media_photo.rb +11 -0
- data/lib/telegram/bot/types/input_media_video.rb +14 -0
- data/lib/telegram/bot/types/input_message_content.rb +8 -0
- data/lib/telegram/bot/types/input_text_message_content.rb +11 -0
- data/lib/telegram/bot/types/input_venue_message_content.rb +13 -0
- data/lib/telegram/bot/types/invoice.rb +13 -0
- data/lib/telegram/bot/types/keyboard_button.rb +11 -0
- data/lib/telegram/bot/types/labeled_price.rb +10 -0
- data/lib/telegram/bot/types/location.rb +10 -0
- data/lib/telegram/bot/types/mask_position.rb +12 -0
- data/lib/telegram/bot/types/message.rb +52 -0
- data/lib/telegram/bot/types/message_entity.rb +15 -0
- data/lib/telegram/bot/types/order_info.rb +12 -0
- data/lib/telegram/bot/types/passport_data.rb +10 -0
- data/lib/telegram/bot/types/passport_file.rb +11 -0
- data/lib/telegram/bot/types/photo_size.rb +12 -0
- data/lib/telegram/bot/types/pre_checkout_query.rb +15 -0
- data/lib/telegram/bot/types/reply_keyboard_markup.rb +23 -0
- data/lib/telegram/bot/types/reply_keyboard_remove.rb +10 -0
- data/lib/telegram/bot/types/shipping_address.rb +14 -0
- data/lib/telegram/bot/types/shipping_option.rb +11 -0
- data/lib/telegram/bot/types/shipping_query.rb +12 -0
- data/lib/telegram/bot/types/sticker.rb +16 -0
- data/lib/telegram/bot/types/sticker_set.rb +12 -0
- data/lib/telegram/bot/types/successful_payment.rb +15 -0
- data/lib/telegram/bot/types/update.rb +23 -0
- data/lib/telegram/bot/types/user.rb +14 -0
- data/lib/telegram/bot/types/user_profile_photos.rb +10 -0
- data/lib/telegram/bot/types/venue.rb +12 -0
- data/lib/telegram/bot/types/video.rb +15 -0
- data/lib/telegram/bot/types/video_note.rb +13 -0
- data/lib/telegram/bot/types/voice.rb +12 -0
- data/lib/telegram/bot/types.rb +77 -0
- data/lib/telegram/bot/version.rb +5 -0
- data/lib/telegram/bot.rb +29 -0
- metadata +286 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 75602caf402bd9c38556bf173265dc884083b55aa42fd91e447e97638949d586
|
4
|
+
data.tar.gz: a666b4f4813e77fa30049dd73a82db2297842e11a66d07be5d3ca910610d7a1d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5f9af8849974b68ccad6ca9ed08dc445cf921788039bf560ba7caf66744f449aa50e3f93ddb2af360b45bf66a64d59fae7961b88cf4f91776c1e4e43a665998a
|
7
|
+
data.tar.gz: e79720f970f726be57d6797885df46e32ea9a8bb1ba54f5183a603806256504bd9e5cb830bfcddec8c87c85b9d7b9c9f1d0cf6ee2577832bf3239b090c0d3dad
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
require: rubocop-rspec
|
3
|
+
|
4
|
+
Metrics/BlockLength:
|
5
|
+
Exclude:
|
6
|
+
- spec/**/*.rb
|
7
|
+
|
8
|
+
Metrics/LineLength:
|
9
|
+
Exclude:
|
10
|
+
- telegram-bot-ruby.gemspec
|
11
|
+
- examples/*.rb
|
12
|
+
|
13
|
+
Style/EmptyMethod:
|
14
|
+
EnforcedStyle: expanded
|
15
|
+
|
16
|
+
Style/PercentLiteralDelimiters:
|
17
|
+
PreferredDelimiters:
|
18
|
+
'%w': '()'
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
+
# on 2015-06-27 20:51:46 +0300 using RuboCop version 0.32.1.
|
3
|
+
# The point is for the user to remove these configuration records
|
4
|
+
# one by one as the offenses are removed from the code base.
|
5
|
+
# Note that changes in the inspected code, or installation of new
|
6
|
+
# versions of RuboCop, may require this file to be generated again.
|
7
|
+
|
8
|
+
Metrics/MethodLength:
|
9
|
+
Max: 11
|
10
|
+
|
11
|
+
# Offense count: 15
|
12
|
+
Style/Documentation:
|
13
|
+
Enabled: false
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
## 0.8.6.1
|
4
|
+
|
5
|
+
- Fix #163
|
6
|
+
|
7
|
+
## 0.8.6
|
8
|
+
|
9
|
+
- Implement [Bot API 3.5](https://core.telegram.org/bots/api#november-17-2017)
|
10
|
+
|
11
|
+
## 0.8.5
|
12
|
+
|
13
|
+
- Implement [Bot API 3.4](https://core.telegram.org/bots/api#october-11-2017) (thx [@ivanovaleksey][])
|
14
|
+
|
15
|
+
## 0.8.4
|
16
|
+
|
17
|
+
- Implement [Bot API 3.3](https://core.telegram.org/bots/api#august-23-2017) (thx [@ivanovaleksey][])
|
18
|
+
|
19
|
+
## 0.8.3
|
20
|
+
|
21
|
+
- Implement [Bot API 3.2](https://core.telegram.org/bots/api#july-21-2017) (thx [@ivanovaleksey][])
|
22
|
+
|
23
|
+
## 0.8.2
|
24
|
+
|
25
|
+
- Implement [Bot API 3.1](https://core.telegram.org/bots/api#june-30-2017) (thx [@ivanovaleksey][])
|
26
|
+
|
27
|
+
## 0.8.1
|
28
|
+
|
29
|
+
- Add [missing methods](https://github.com/atipugin/telegram-bot-ruby/pull/127) from earlier versions earlier
|
30
|
+
|
31
|
+
## 0.8.0
|
32
|
+
|
33
|
+
- Implement [Bot API 3.0](https://core.telegram.org/bots/api#may-18-2017) (thx [@ivanovaleksey][])
|
34
|
+
|
35
|
+
## 0.7.2
|
36
|
+
|
37
|
+
- Bug fixes
|
38
|
+
|
39
|
+
## 0.7.1
|
40
|
+
|
41
|
+
- Implement [Bot API 2.3.1](https://core.telegram.org/bots/api-changelog#december-4-2016)
|
42
|
+
|
43
|
+
## 0.7.0
|
44
|
+
|
45
|
+
- Implement [Bot API 2.3](https://core.telegram.org/bots/api-changelog#november-21-2016) (thx [@ivanovaleksey][])
|
46
|
+
|
47
|
+
## 0.6.0
|
48
|
+
|
49
|
+
- Implement Bot API changes (October 3, 2016 API update)
|
50
|
+
|
51
|
+
## 0.5.2
|
52
|
+
|
53
|
+
- Implement Bot API 2.1 changes
|
54
|
+
|
55
|
+
## 0.5.1
|
56
|
+
|
57
|
+
- Update `Sticker` and `Message` objects (May 6, 2016 API update)
|
58
|
+
|
59
|
+
## 0.5.0
|
60
|
+
|
61
|
+
- Replace [httparty](https://github.com/jnunemaker/httparty) with [faraday](https://github.com/lostisland/faraday)
|
62
|
+
- Implement [Bot API 2.0](https://core.telegram.org/bots/2-0-intro)
|
63
|
+
|
64
|
+
## 0.4.2
|
65
|
+
|
66
|
+
- Let `Client#logger` be overwritten later (use `attr_accessor` instead of `attr_reader`)
|
67
|
+
|
68
|
+
[@ivanovaleksey]: https://github.com/ivanovaleksey
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
14
|
+
|
data/README.md
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
# telegram-bot-ruby
|
2
|
+
|
3
|
+
Ruby wrapper for [Telegram's Bot API](https://core.telegram.org/bots/api).
|
4
|
+
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/telegram-bot-ruby.svg)](http://badge.fury.io/rb/telegram-bot-ruby)
|
6
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/7e61fbf5bec86e118fb1/maintainability)](https://codeclimate.com/github/atipugin/telegram-bot-ruby/maintainability)
|
7
|
+
[![Build Status](https://travis-ci.org/atipugin/telegram-bot-ruby.svg?branch=master)](https://travis-ci.org/atipugin/telegram-bot-ruby)
|
8
|
+
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks!-🦉-1EAEDB.svg)](https://saythanks.io/to/atipugin)
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add following line to your Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'telegram-bot-ruby'
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
```shell
|
21
|
+
$ bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
Or install it system-wide:
|
25
|
+
|
26
|
+
```shell
|
27
|
+
$ gem install telegram-bot-ruby
|
28
|
+
```
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
First things first, you need to [obtain a token](https://core.telegram.org/bots#botfather) for your bot. Then create your Telegram bot like this:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
require 'telegram/bot'
|
36
|
+
|
37
|
+
token = 'YOUR_TELEGRAM_BOT_API_TOKEN'
|
38
|
+
|
39
|
+
Telegram::Bot::Client.run(token) do |bot|
|
40
|
+
bot.listen do |message|
|
41
|
+
case message.text
|
42
|
+
when '/start'
|
43
|
+
bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}")
|
44
|
+
when '/stop'
|
45
|
+
bot.api.send_message(chat_id: message.chat.id, text: "Bye, #{message.from.first_name}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
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.
|
52
|
+
|
53
|
+
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.
|
54
|
+
|
55
|
+
## Webhooks
|
56
|
+
|
57
|
+
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.
|
58
|
+
|
59
|
+
## Custom keyboards
|
60
|
+
|
61
|
+
You can use your own [custom keyboards](https://core.telegram.org/bots#keyboards). Here is an example:
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
bot.listen do |message|
|
65
|
+
case message.text
|
66
|
+
when '/start'
|
67
|
+
question = 'London is a capital of which country?'
|
68
|
+
# See more: https://core.telegram.org/bots/api#replykeyboardmarkup
|
69
|
+
answers =
|
70
|
+
Telegram::Bot::Types::ReplyKeyboardMarkup
|
71
|
+
.new(keyboard: [%w(A B), %w(C D)], one_time_keyboard: true)
|
72
|
+
bot.api.send_message(chat_id: message.chat.id, text: question, reply_markup: answers)
|
73
|
+
when '/stop'
|
74
|
+
# See more: https://core.telegram.org/bots/api#replykeyboardremove
|
75
|
+
kb = Telegram::Bot::Types::ReplyKeyboardRemove.new(remove_keyboard: true)
|
76
|
+
bot.api.send_message(chat_id: message.chat.id, text: 'Sorry to see you go :(', reply_markup: kb)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
81
|
+
Furthermore, you can ask user to share location or phone number using `KeyboardButton`:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
bot.listen do |message|
|
85
|
+
kb = [
|
86
|
+
Telegram::Bot::Types::KeyboardButton.new(text: 'Give me your phone number', request_contact: true),
|
87
|
+
Telegram::Bot::Types::KeyboardButton.new(text: 'Show me your location', request_location: true)
|
88
|
+
]
|
89
|
+
markup = Telegram::Bot::Types::ReplyKeyboardMarkup.new(keyboard: kb)
|
90
|
+
bot.api.send_message(chat_id: message.chat.id, text: 'Hey!', reply_markup: markup)
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
## Inline keyboards
|
95
|
+
|
96
|
+
[Bot API 2.0](https://core.telegram.org/bots/2-0-intro) brought us new inline keyboards. Example:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
bot.listen do |message|
|
100
|
+
case message
|
101
|
+
when Telegram::Bot::Types::CallbackQuery
|
102
|
+
# Here you can handle your callbacks from inline buttons
|
103
|
+
if message.data == 'touch'
|
104
|
+
bot.api.send_message(chat_id: message.from.id, text: "Don't touch me!")
|
105
|
+
end
|
106
|
+
when Telegram::Bot::Types::Message
|
107
|
+
kb = [
|
108
|
+
Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Go to Google', url: 'https://google.com'),
|
109
|
+
Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Touch me', callback_data: 'touch'),
|
110
|
+
Telegram::Bot::Types::InlineKeyboardButton.new(text: 'Switch to inline', switch_inline_query: 'some text')
|
111
|
+
]
|
112
|
+
markup = Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: kb)
|
113
|
+
bot.api.send_message(chat_id: message.chat.id, text: 'Make a choice', reply_markup: markup)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
## Inline bots
|
119
|
+
|
120
|
+
If you are going to create [inline bot](https://core.telegram.org/bots/inline), check the example below:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
bot.listen do |message|
|
124
|
+
case message
|
125
|
+
when Telegram::Bot::Types::InlineQuery
|
126
|
+
results = [
|
127
|
+
[1, 'First article', 'Very interesting text goes here.'],
|
128
|
+
[2, 'Second article', 'Another interesting text here.']
|
129
|
+
].map do |arr|
|
130
|
+
Telegram::Bot::Types::InlineQueryResultArticle.new(
|
131
|
+
id: arr[0],
|
132
|
+
title: arr[1],
|
133
|
+
input_message_content: Telegram::Bot::Types::InputTextMessageContent.new(message_text: arr[2])
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
137
|
+
bot.api.answer_inline_query(inline_query_id: message.id, results: results)
|
138
|
+
when Telegram::Bot::Types::Message
|
139
|
+
bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}!")
|
140
|
+
end
|
141
|
+
end
|
142
|
+
```
|
143
|
+
|
144
|
+
Now, with `inline` mode enabled, your `message` object can be an instance of [Message](https://core.telegram.org/bots/api#message), [InlineQuery](https://core.telegram.org/bots/api#inlinequery) or [ChosenInlineResult](https://core.telegram.org/bots/api#choseninlineresult). That's why you need to check type of each message and decide how to handle it.
|
145
|
+
|
146
|
+
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).
|
147
|
+
|
148
|
+
## File upload
|
149
|
+
|
150
|
+
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:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
bot.listen do |message|
|
154
|
+
case message.text
|
155
|
+
when '/photo'
|
156
|
+
bot.api.send_photo(chat_id: message.chat.id, photo: Faraday::UploadIO.new('~/Desktop/jennifer.jpg', 'image/jpeg'))
|
157
|
+
end
|
158
|
+
end
|
159
|
+
```
|
160
|
+
|
161
|
+
## Logging
|
162
|
+
|
163
|
+
By default, bot doesn't log anything (uses `NullLoger`). You can change this behavior and provide your own logger class. See example below:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
Telegram::Bot::Client.run(token, logger: Logger.new($stderr)) do |bot|
|
167
|
+
bot.logger.info('Bot has been started')
|
168
|
+
bot.listen do |message|
|
169
|
+
# ...
|
170
|
+
end
|
171
|
+
end
|
172
|
+
```
|
173
|
+
|
174
|
+
## Connection adapters
|
175
|
+
|
176
|
+
Since version `0.5.0` we rely on [faraday](https://github.com/lostisland/faraday) under the hood. You can use any of supported adapters (for example, `net/http/persistent`):
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
require 'net/http/persistent'
|
180
|
+
|
181
|
+
Telegram::Bot.configure do |config|
|
182
|
+
config.adapter = :net_http_persistent
|
183
|
+
end
|
184
|
+
```
|
185
|
+
|
186
|
+
## Boilerplates
|
187
|
+
|
188
|
+
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:
|
189
|
+
- [Ruby Telegram Bot boilerplate](https://github.com/telegram-bots/ruby-telegram-bot-boilerplate)
|
190
|
+
|
191
|
+
## Contributing
|
192
|
+
|
193
|
+
1. Fork it
|
194
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
195
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
196
|
+
4. Push to the branch (git push origin my-new-feature)
|
197
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rubocop/rake_task'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
RuboCop::RakeTask.new(:rubocop) do |task|
|
7
|
+
task.fail_on_error = false
|
8
|
+
task.options = %w(--force-exclusion)
|
9
|
+
task.patterns = %w(lib/**/*.rb)
|
10
|
+
task.requires << 'rubocop-rspec'
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new(:spec)
|
14
|
+
|
15
|
+
task default: :spec
|
data/bin/console
ADDED
data/bin/setup
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'telegram/bot/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'dialog_bot_ruby'
|
8
|
+
s.version = Telegram::Bot::VERSION
|
9
|
+
s.authors = ['Alexander Tipugin', 'Eugene Istomin']
|
10
|
+
s.email = ['atipugin@gmail.com', 'info@innosense.org']
|
11
|
+
s.license = 'CC-BY-SA-4.0'
|
12
|
+
|
13
|
+
s.summary = "Ruby wrapper for Telegram's Bot API"
|
14
|
+
s.homepage = 'https://gitlab.com/Innosense/libs/dialog_bot_ruby'
|
15
|
+
|
16
|
+
s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
s.bindir = 'exe'
|
18
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'faraday', '~> 0'
|
22
|
+
s.add_runtime_dependency 'virtus', '~> 0'
|
23
|
+
s.add_runtime_dependency 'inflecto', '~> 0'
|
24
|
+
s.add_runtime_dependency 'socksify', '~> 0'
|
25
|
+
|
26
|
+
s.add_development_dependency 'bundler', '~> 1.9'
|
27
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
s.add_development_dependency 'pry', '~> 0'
|
29
|
+
s.add_development_dependency 'rubocop', '~> 0.48.1'
|
30
|
+
s.add_development_dependency 'rspec', '~> 3.4'
|
31
|
+
s.add_development_dependency 'rubocop-rspec', '~> 1.8'
|
32
|
+
end
|
data/examples/bot.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'telegram/bot'
|
3
|
+
|
4
|
+
token = 'replace-me-with-your-real-token'
|
5
|
+
|
6
|
+
Telegram::Bot::Client.run(token) do |bot|
|
7
|
+
bot.listen do |message|
|
8
|
+
case message.text
|
9
|
+
when '/start'
|
10
|
+
bot.api.send_message(chat_id: message.chat.id, text: "Hello, #{message.from.first_name}!")
|
11
|
+
when '/end'
|
12
|
+
bot.api.send_message(chat_id: message.chat.id, text: "Bye, #{message.from.first_name}!")
|
13
|
+
else
|
14
|
+
bot.api.send_message(chat_id: message.chat.id, text: "I don't understand you :(")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'socksify'
|
2
|
+
require 'socksify/http'
|
3
|
+
|
4
|
+
module Telegram
|
5
|
+
module Bot
|
6
|
+
module Adapters
|
7
|
+
class Socks5 < Faraday::Adapter::NetHttp
|
8
|
+
def net_http_connection(env)
|
9
|
+
if proxy = env[:request][:proxy]
|
10
|
+
if proxy[:socks]
|
11
|
+
TCPSocket.socks_username = proxy[:user] if proxy[:user]
|
12
|
+
TCPSocket.socks_password = proxy[:password] if proxy[:password]
|
13
|
+
Net::HTTP::SOCKSProxy(proxy[:uri].host, proxy[:uri].port)
|
14
|
+
else
|
15
|
+
Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:uri].user, proxy[:uri].password)
|
16
|
+
end
|
17
|
+
else
|
18
|
+
Net::HTTP
|
19
|
+
end.new(env[:url].host, env[:url].port)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
class Api
|
4
|
+
ENDPOINTS = %w(
|
5
|
+
getUpdates setWebhook deleteWebhook getWebhookInfo getMe sendMessage
|
6
|
+
forwardMessage sendPhoto sendAudio sendDocument sendVideo sendVoice
|
7
|
+
sendVideoNote sendMediaGroup sendLocation editMessageLiveLocation
|
8
|
+
stopMessageLiveLocation sendVenue sendContact sendChatAction
|
9
|
+
getUserProfilePhotos getFile kickChatMember unbanChatMember
|
10
|
+
restrictChatMember promoteChatMember leaveChat getChat
|
11
|
+
getChatAdministrators exportChatInviteLink setChatPhoto deleteChatPhoto
|
12
|
+
setChatTitle setChatDescription pinChatMessage unpinChatMessage
|
13
|
+
getChatMembersCount getChatMember setChatStickerSet deleteChatStickerSet
|
14
|
+
answerCallbackQuery editMessageText editMessageCaption
|
15
|
+
editMessageReplyMarkup deleteMessage sendSticker getStickerSet
|
16
|
+
uploadStickerFile createNewStickerSet addStickerToSet
|
17
|
+
setStickerPositionInSet deleteStickerFromSet answerInlineQuery
|
18
|
+
sendInvoice answerShippingQuery answerPreCheckoutQuery
|
19
|
+
sendGame setGameScore getGameHighScores sendInvoice
|
20
|
+
).freeze
|
21
|
+
REPLY_MARKUP_TYPES = [
|
22
|
+
Telegram::Bot::Types::ReplyKeyboardMarkup,
|
23
|
+
Telegram::Bot::Types::ReplyKeyboardRemove,
|
24
|
+
Telegram::Bot::Types::ForceReply,
|
25
|
+
Telegram::Bot::Types::InlineKeyboardMarkup
|
26
|
+
].freeze
|
27
|
+
INLINE_QUERY_RESULT_TYPES = [
|
28
|
+
Telegram::Bot::Types::InlineQueryResultArticle,
|
29
|
+
Telegram::Bot::Types::InlineQueryResultPhoto,
|
30
|
+
Telegram::Bot::Types::InlineQueryResultGif,
|
31
|
+
Telegram::Bot::Types::InlineQueryResultMpeg4Gif,
|
32
|
+
Telegram::Bot::Types::InlineQueryResultVideo,
|
33
|
+
Telegram::Bot::Types::InlineQueryResultAudio,
|
34
|
+
Telegram::Bot::Types::InlineQueryResultVoice,
|
35
|
+
Telegram::Bot::Types::InlineQueryResultDocument,
|
36
|
+
Telegram::Bot::Types::InlineQueryResultLocation,
|
37
|
+
Telegram::Bot::Types::InlineQueryResultVenue,
|
38
|
+
Telegram::Bot::Types::InlineQueryResultContact,
|
39
|
+
Telegram::Bot::Types::InlineQueryResultGame,
|
40
|
+
Telegram::Bot::Types::InlineQueryResultCachedPhoto,
|
41
|
+
Telegram::Bot::Types::InlineQueryResultCachedGif,
|
42
|
+
Telegram::Bot::Types::InlineQueryResultCachedMpeg4Gif,
|
43
|
+
Telegram::Bot::Types::InlineQueryResultCachedSticker,
|
44
|
+
Telegram::Bot::Types::InlineQueryResultCachedDocument,
|
45
|
+
Telegram::Bot::Types::InlineQueryResultCachedVideo,
|
46
|
+
Telegram::Bot::Types::InlineQueryResultCachedVoice,
|
47
|
+
Telegram::Bot::Types::InlineQueryResultCachedAudio
|
48
|
+
].freeze
|
49
|
+
|
50
|
+
attr_reader :token
|
51
|
+
|
52
|
+
def initialize(token)
|
53
|
+
@token = token
|
54
|
+
end
|
55
|
+
|
56
|
+
def method_missing(method_name, *args, &block)
|
57
|
+
endpoint = method_name.to_s
|
58
|
+
endpoint = camelize(endpoint) if endpoint.include?('_')
|
59
|
+
|
60
|
+
ENDPOINTS.include?(endpoint) ? call(endpoint, *args) : super
|
61
|
+
end
|
62
|
+
|
63
|
+
def respond_to_missing?(*args)
|
64
|
+
method_name = args[0].to_s
|
65
|
+
method_name = camelize(method_name) if method_name.include?('_')
|
66
|
+
|
67
|
+
ENDPOINTS.include?(method_name) || super
|
68
|
+
end
|
69
|
+
|
70
|
+
def call(endpoint, raw_params = {}, force = false)
|
71
|
+
params = force ? raw_params : build_params(raw_params)
|
72
|
+
response = conn.post("/bot#{token}/#{endpoint}", params.to_json)
|
73
|
+
if response.status == 200
|
74
|
+
JSON.parse(response.body)
|
75
|
+
elsif response.finished?
|
76
|
+
raise Exceptions::ResponseError.new(response),
|
77
|
+
'Telegram API has returned the error.'
|
78
|
+
else
|
79
|
+
response
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def in_parallel(&block)
|
84
|
+
conn.in_parallel(&block)
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def build_params(h)
|
90
|
+
h.each_with_object({}) do |(key, value), params|
|
91
|
+
params[key] = sanitize_value(value)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def sanitize_value(value)
|
96
|
+
jsonify_inline_query_results(jsonify_reply_markup(value))
|
97
|
+
end
|
98
|
+
|
99
|
+
def jsonify_reply_markup(value)
|
100
|
+
return value unless REPLY_MARKUP_TYPES.include?(value.class)
|
101
|
+
value.to_compact_hash.to_json
|
102
|
+
end
|
103
|
+
|
104
|
+
def jsonify_inline_query_results(value)
|
105
|
+
return value unless
|
106
|
+
value.is_a?(Array) &&
|
107
|
+
value.all? { |i| INLINE_QUERY_RESULT_TYPES.include?(i.class) }
|
108
|
+
value.map { |i| i.to_compact_hash.select { |_, v| v } }.to_json
|
109
|
+
end
|
110
|
+
|
111
|
+
def camelize(method_name)
|
112
|
+
words = method_name.split('_')
|
113
|
+
words.drop(1).map(&:capitalize!)
|
114
|
+
words.join
|
115
|
+
end
|
116
|
+
|
117
|
+
def conn
|
118
|
+
@conn ||=
|
119
|
+
case ENV['BotProxyType']
|
120
|
+
when 'https'
|
121
|
+
set_http_proxy_connection('https')
|
122
|
+
when 'http'
|
123
|
+
set_http_proxy_connection('http')
|
124
|
+
when 'socks5'
|
125
|
+
set_socks5_connection
|
126
|
+
else
|
127
|
+
set_default_connection
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def set_http_proxy_connection(proto)
|
132
|
+
host = "#{proto}://#{ENV['BotProxyHost']}:#{ENV['BotProxyPort']}"
|
133
|
+
Faraday.new(url: 'https://api.telegram.org', ssl: {verify:false}) do |faraday|
|
134
|
+
faraday.request :multipart
|
135
|
+
faraday.request :url_encoded
|
136
|
+
faraday.adapter Telegram::Bot.configuration.adapter
|
137
|
+
faraday.proxy URI.parse(host)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def set_default_connection
|
142
|
+
Faraday.new(url: 'https://api.telegram.org', ssl: {verify:false}) do |faraday|
|
143
|
+
faraday.request :multipart
|
144
|
+
faraday.request :url_encoded
|
145
|
+
faraday.adapter Telegram::Bot.configuration.adapter
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def set_socks5_connection
|
150
|
+
require 'telegram/bot/adapters/socks5'
|
151
|
+
|
152
|
+
host = "https://#{ENV['BotProxyHost']}:#{ENV['BotProxyPort']}"
|
153
|
+
proxy_opts = {
|
154
|
+
uri: URI.parse(host),
|
155
|
+
user: ENV['BotProxyLogin'],
|
156
|
+
password: ENV['BotProxyPass'],
|
157
|
+
socks: true
|
158
|
+
}
|
159
|
+
|
160
|
+
Faraday.new(url: 'https://api.telegram.org',
|
161
|
+
ssl: {verify:false},
|
162
|
+
request: { proxy: proxy_opts }) do |c|
|
163
|
+
c.request :multipart
|
164
|
+
c.request :url_encoded
|
165
|
+
c.headers['Content-Type'] = 'application/json'
|
166
|
+
Faraday::Adapter.register_middleware socks5: Telegram::Bot::Adapters::Socks5
|
167
|
+
c.adapter :socks5
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|