dialog_bot_ruby 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +18 -0
  5. data/.rubocop_todo.yml +13 -0
  6. data/.travis.yml +6 -0
  7. data/CHANGELOG.md +68 -0
  8. data/Gemfile +3 -0
  9. data/LICENSE +14 -0
  10. data/README.md +197 -0
  11. data/Rakefile +15 -0
  12. data/bin/console +6 -0
  13. data/bin/setup +5 -0
  14. data/dialog_bot_ruby.gemspec +32 -0
  15. data/examples/bot.rb +17 -0
  16. data/lib/telegram/bot/adapters/socks5.rb +24 -0
  17. data/lib/telegram/bot/api.rb +172 -0
  18. data/lib/telegram/bot/client.rb +77 -0
  19. data/lib/telegram/bot/configuration.rb +11 -0
  20. data/lib/telegram/bot/exceptions/base.rb +7 -0
  21. data/lib/telegram/bot/exceptions/response_error.rb +32 -0
  22. data/lib/telegram/bot/exceptions.rb +2 -0
  23. data/lib/telegram/bot/null_logger.rb +11 -0
  24. data/lib/telegram/bot/types/animation.rb +13 -0
  25. data/lib/telegram/bot/types/audio.rb +14 -0
  26. data/lib/telegram/bot/types/base.rb +10 -0
  27. data/lib/telegram/bot/types/callback_game.rb +8 -0
  28. data/lib/telegram/bot/types/callback_query.rb +15 -0
  29. data/lib/telegram/bot/types/chat.rb +22 -0
  30. data/lib/telegram/bot/types/chat_member.rb +24 -0
  31. data/lib/telegram/bot/types/chat_photo.rb +10 -0
  32. data/lib/telegram/bot/types/chosen_inline_result.rb +15 -0
  33. data/lib/telegram/bot/types/compactable.rb +26 -0
  34. data/lib/telegram/bot/types/contact.rb +13 -0
  35. data/lib/telegram/bot/types/document.rb +13 -0
  36. data/lib/telegram/bot/types/encrypted_credentials.rb +11 -0
  37. data/lib/telegram/bot/types/encrypted_passport_element.rb +16 -0
  38. data/lib/telegram/bot/types/file.rb +11 -0
  39. data/lib/telegram/bot/types/force_reply.rb +10 -0
  40. data/lib/telegram/bot/types/game.rb +14 -0
  41. data/lib/telegram/bot/types/game_high_score.rb +11 -0
  42. data/lib/telegram/bot/types/inline_keyboard_button.rb +15 -0
  43. data/lib/telegram/bot/types/inline_keyboard_markup.rb +20 -0
  44. data/lib/telegram/bot/types/inline_query.rb +15 -0
  45. data/lib/telegram/bot/types/inline_query_result_article.rb +19 -0
  46. data/lib/telegram/bot/types/inline_query_result_audio.rb +17 -0
  47. data/lib/telegram/bot/types/inline_query_result_cached_audio.rb +14 -0
  48. data/lib/telegram/bot/types/inline_query_result_cached_document.rb +16 -0
  49. data/lib/telegram/bot/types/inline_query_result_cached_gif.rb +15 -0
  50. data/lib/telegram/bot/types/inline_query_result_cached_mpeg4_gif.rb +15 -0
  51. data/lib/telegram/bot/types/inline_query_result_cached_photo.rb +16 -0
  52. data/lib/telegram/bot/types/inline_query_result_cached_sticker.rb +13 -0
  53. data/lib/telegram/bot/types/inline_query_result_cached_video.rb +16 -0
  54. data/lib/telegram/bot/types/inline_query_result_cached_voice.rb +15 -0
  55. data/lib/telegram/bot/types/inline_query_result_contact.rb +19 -0
  56. data/lib/telegram/bot/types/inline_query_result_document.rb +20 -0
  57. data/lib/telegram/bot/types/inline_query_result_game.rb +12 -0
  58. data/lib/telegram/bot/types/inline_query_result_gif.rb +19 -0
  59. data/lib/telegram/bot/types/inline_query_result_location.rb +18 -0
  60. data/lib/telegram/bot/types/inline_query_result_mpeg4_gif.rb +19 -0
  61. data/lib/telegram/bot/types/inline_query_result_photo.rb +19 -0
  62. data/lib/telegram/bot/types/inline_query_result_venue.rb +20 -0
  63. data/lib/telegram/bot/types/inline_query_result_video.rb +21 -0
  64. data/lib/telegram/bot/types/inline_query_result_voice.rb +16 -0
  65. data/lib/telegram/bot/types/input_contact_message_content.rb +12 -0
  66. data/lib/telegram/bot/types/input_location_message_content.rb +10 -0
  67. data/lib/telegram/bot/types/input_media_photo.rb +11 -0
  68. data/lib/telegram/bot/types/input_media_video.rb +14 -0
  69. data/lib/telegram/bot/types/input_message_content.rb +8 -0
  70. data/lib/telegram/bot/types/input_text_message_content.rb +11 -0
  71. data/lib/telegram/bot/types/input_venue_message_content.rb +13 -0
  72. data/lib/telegram/bot/types/invoice.rb +13 -0
  73. data/lib/telegram/bot/types/keyboard_button.rb +11 -0
  74. data/lib/telegram/bot/types/labeled_price.rb +10 -0
  75. data/lib/telegram/bot/types/location.rb +10 -0
  76. data/lib/telegram/bot/types/mask_position.rb +12 -0
  77. data/lib/telegram/bot/types/message.rb +52 -0
  78. data/lib/telegram/bot/types/message_entity.rb +15 -0
  79. data/lib/telegram/bot/types/order_info.rb +12 -0
  80. data/lib/telegram/bot/types/passport_data.rb +10 -0
  81. data/lib/telegram/bot/types/passport_file.rb +11 -0
  82. data/lib/telegram/bot/types/photo_size.rb +12 -0
  83. data/lib/telegram/bot/types/pre_checkout_query.rb +15 -0
  84. data/lib/telegram/bot/types/reply_keyboard_markup.rb +23 -0
  85. data/lib/telegram/bot/types/reply_keyboard_remove.rb +10 -0
  86. data/lib/telegram/bot/types/shipping_address.rb +14 -0
  87. data/lib/telegram/bot/types/shipping_option.rb +11 -0
  88. data/lib/telegram/bot/types/shipping_query.rb +12 -0
  89. data/lib/telegram/bot/types/sticker.rb +16 -0
  90. data/lib/telegram/bot/types/sticker_set.rb +12 -0
  91. data/lib/telegram/bot/types/successful_payment.rb +15 -0
  92. data/lib/telegram/bot/types/update.rb +23 -0
  93. data/lib/telegram/bot/types/user.rb +14 -0
  94. data/lib/telegram/bot/types/user_profile_photos.rb +10 -0
  95. data/lib/telegram/bot/types/venue.rb +12 -0
  96. data/lib/telegram/bot/types/video.rb +15 -0
  97. data/lib/telegram/bot/types/video_note.rb +13 -0
  98. data/lib/telegram/bot/types/voice.rb +12 -0
  99. data/lib/telegram/bot/types.rb +77 -0
  100. data/lib/telegram/bot/version.rb +5 -0
  101. data/lib/telegram/bot.rb +29 -0
  102. 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
@@ -0,0 +1,6 @@
1
+ Gemfile.lock
2
+ *.gem
3
+
4
+ .bundle/
5
+ pkg/
6
+ vendor/bundle/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --color
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
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.0
4
+ script:
5
+ - bundle exec rubocop
6
+ - bundle exec rspec
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
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require 'bundler/setup'
3
+ require 'telegram/bot'
4
+
5
+ require 'pry'
6
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
@@ -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