telegram-bot 0.12.1 → 0.12.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68b890442fcebe77768635e83f83a3c17836fe1c
4
- data.tar.gz: d63e9386c4bbed598c8708aedbea3c19e3dbc8f9
3
+ metadata.gz: 8eb183223c86ea83c75580aa026dbf168bcff8ad
4
+ data.tar.gz: 450a6eceafca52a41e883e1a2eb4431e4fb9dfbf
5
5
  SHA512:
6
- metadata.gz: 0346c315cba86a652b0ab3914129ba426568790c5d18962b233cb60ef96b5c943562dec8cbaf348fe55d8b4592c7043987e30787707830d21791064be0d588a9
7
- data.tar.gz: 6d643748c150f11087e29ed73e61cf979746d876461582055748dafa2aec2f4ffe5d9f52048158f2005e9c1e8c41abf6481feb88b09ac7c98549576ead446f50
6
+ metadata.gz: 643300653458e8b8d865380d124b86a03266286224ef38131036a290a4d06e979ed02129482d7a20b94e125ad886e76dee9eeae3712cef9a6e837cc81e3a261f
7
+ data.tar.gz: c0874e97e40f401b980f1748db74164ab364a92ba9ba875b57ad3eb985f6322c67bcbc9d9728d9eab5b16c2962d922c365a2699836697a4a116bc8bc688b9b99
data/.gitignore CHANGED
@@ -1,6 +1,8 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
3
  /Gemfile.lock
4
+ /gemfiles/*.lock
5
+ /gemfiles/.bundle
4
6
  /_yardoc/
5
7
  /coverage/
6
8
  /doc/
data/.rubocop.yml CHANGED
@@ -1,30 +1,52 @@
1
1
  Rails: {Enabled: true}
2
2
 
3
- Style/Alias: {Enabled: false}
4
- Style/AlignParameters:
3
+ Layout/AlignParameters:
5
4
  # Disable, till rubocop supports combination of styles.
6
5
  # Use one of this styles where appropriate, keep it clean, compact and readable.
7
6
  Enabled: false
8
7
  # EnforcedStyle:
9
8
  # - with_first_parameter
10
9
  # - with_fixed_indentation
10
+
11
+ # Breaks
12
+ #
13
+ # I18n.t(key,
14
+ # param: val,
15
+ # # ...
16
+ # )
17
+ Layout/ClosingParenthesisIndentation: {Enabled: false}
18
+ Layout/DotPosition: {EnforcedStyle: trailing}
19
+ Layout/FirstParameterIndentation: {EnforcedStyle: consistent}
20
+ # Same as Layout/ClosingParenthesisIndentation
21
+ Layout/MultilineMethodCallBraceLayout: {Enabled: false}
22
+ Layout/MultilineMethodCallIndentation: {EnforcedStyle: indented}
23
+ Layout/MultilineOperationIndentation: {EnforcedStyle: indented}
24
+ Layout/SpaceInsideHashLiteralBraces: {EnforcedStyle: no_space}
25
+
26
+ # Offences named scopes and `expect {}.to change {}`.
27
+ Lint/AmbiguousBlockAssociation: {Enabled: false}
28
+
29
+ Naming/PredicateName: {Enabled: false}
30
+ Naming/VariableNumber: {EnforcedStyle: snake_case}
31
+
32
+ Style/Alias: {Enabled: false}
11
33
  Style/AndOr: {EnforcedStyle: conditionals}
12
- Style/ClosingParenthesisIndentation: {Enabled: false}
13
34
  Style/Documentation: {Enabled: false}
14
- Style/DotPosition: {EnforcedStyle: trailing}
15
- Style/FirstParameterIndentation: {EnforcedStyle: consistent}
16
35
  Style/IfUnlessModifier: {Enabled: false}
36
+
37
+ # Consistent to other definitions.
38
+ Style/EmptyMethod: {EnforcedStyle: expanded}
39
+
17
40
  Style/ModuleFunction: {Enabled: false}
18
- Style/MultilineMethodCallIndentation: {EnforcedStyle: indented}
19
- Style/MultilineOperationIndentation: {EnforcedStyle: indented}
20
41
  Style/NestedParenthesizedCalls: {Enabled: false}
21
- Style/PredicateName: {Enabled: false}
22
42
  Style/SignalException: {EnforcedStyle: only_raise}
23
- Style/SpaceInsideHashLiteralBraces: {EnforcedStyle: no_space}
24
43
  Style/TrailingCommaInArguments: {Enabled: false}
25
44
  Style/TrailingCommaInLiteral: {EnforcedStyleForMultiline: comma}
26
45
 
27
46
  Metrics/AbcSize: {Max: 21}
47
+ # Other metrics are just enough.
48
+ # This one offences all specs, routes and some initializers.
49
+ Metrics/BlockLength: {Enabled: false}
28
50
  Metrics/LineLength: {Max: 100}
29
51
  Metrics/MethodLength: {Max: 30}
30
52
  Metrics/CyclomaticComplexity: {Max: 8}
data/.travis.yml CHANGED
@@ -2,9 +2,9 @@ language: ruby
2
2
  cache: bundler
3
3
  rvm:
4
4
  - 2.2.3
5
- env:
6
- - RAILS=4
7
- - RAILS=5
8
- - RAILS=5_1
5
+ gemfile:
6
+ - gemfiles/rails_42.gemfile
7
+ - gemfiles/rails_50.gemfile
8
+ - gemfiles/rails_51.gemfile
9
9
  notifications:
10
10
  email: false
data/Appraisals ADDED
@@ -0,0 +1,14 @@
1
+ appraise 'rails-51' do
2
+ gem 'actionpack', '~> 5.1'
3
+ gem 'railties', '~> 5.1'
4
+ end
5
+
6
+ appraise 'rails-50' do
7
+ gem 'actionpack', '~> 5.0'
8
+ gem 'railties', '~> 5.0'
9
+ end
10
+
11
+ appraise 'rails-42' do
12
+ gem 'actionpack', '~> 4.2'
13
+ gem 'railties', '~> 4.2'
14
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Unreleased
2
2
 
3
+ # 0.12.2
4
+
5
+ - New methods from Bot API v3.5
6
+ - Collect all api helper-methods in Client::ApiHelper module.
7
+ - Add `bin/fetch-telegram-methods` to update API methods list from website.
8
+
3
9
  # 0.12.1
4
10
 
5
11
  - Fix `set_webhook` rake task for async bots with self-issued certificates.
data/Gemfile CHANGED
@@ -2,24 +2,11 @@ source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
4
  group :development do
5
- case ENV['RAILS']
6
- when '5_1'
7
- gem 'railties', '5.1.0'
8
- gem 'actionpack', '5.1.0'
9
- when '5'
10
- gem 'railties', '5.0.2'
11
- gem 'actionpack', '5.0.2'
12
- when '4'
13
- gem 'railties', '~> 4.2'
14
- gem 'actionpack', '~> 4.2'
15
- else
16
- gem 'railties'
17
- gem 'actionpack'
18
- end
5
+ gem 'appraisal', '~> 2.2'
19
6
 
20
- gem 'sdoc', '~> 0.4.1'
21
7
  gem 'pry', '~> 0.10.1'
22
8
  gem 'pry-byebug', '~> 3.2.0'
9
+ gem 'sdoc', '~> 0.4.1'
23
10
 
24
11
  gem 'telegram-bot-types', '~> 0.3.0'
25
12
 
@@ -27,7 +14,7 @@ group :development do
27
14
  gem 'rspec-its', '~> 1.1.0'
28
15
  gem 'rspec-rails', '~> 3.5.0'
29
16
 
30
- gem 'rubocop', '~> 0.37.0'
17
+ gem 'rubocop', '~> 0.51.0'
31
18
 
32
19
  gem 'coveralls', '~> 0.8.2', require: false
33
20
  end
data/README.md CHANGED
@@ -4,8 +4,8 @@
4
4
  [![Code Climate](https://codeclimate.com/github/telegram-bot-rb/telegram-bot/badges/gpa.svg)](https://codeclimate.com/github/telegram-bot-rb/telegram-bot)
5
5
  [![Build Status](https://travis-ci.org/telegram-bot-rb/telegram-bot.svg)](https://travis-ci.org/telegram-bot-rb/telegram-bot)
6
6
 
7
- Tools for developing bot for Telegram. Best used with Rails, but can be be used in
8
- [standalone app](https://github.com/telegram-bot-rb/telegram-bot/wiki/Non-rails-application).
7
+ Tools for developing Telegram bots. Best used with Rails, but can be used in
8
+ [standalone app](https://github.com/telegram-bot-rb/telegram-bot/wiki/Not-rails-application).
9
9
  Supposed to be used in webhook-mode in production, and poller-mode
10
10
  in development, but you can use poller in production if you want.
11
11
 
@@ -13,7 +13,7 @@ Package contains:
13
13
 
14
14
  - Ligthweight client for bot API (with fast and thread-safe
15
15
  [httpclient](https://github.com/nahi/httpclient) under the hood).
16
- - Controller with message parser. Allows to write separate methods for each command.
16
+ - Controller with message parser: define methods for commands, not `case` branches.
17
17
  - Middleware and routes helpers for production env.
18
18
  - Poller with automatic source-reloader for development env.
19
19
  - Rake tasks to update webhook urls.
@@ -53,49 +53,62 @@ require 'telegram/bot'
53
53
 
54
54
  ## Usage
55
55
 
56
- ### Configuration
56
+ ### Configuration in Rails app
57
57
 
58
58
  Add `telegram` section into `secrets.yml`:
59
59
 
60
60
  ```yml
61
- telegram:
62
- bots:
63
- # just set the token
64
- chat: TOKEN_1
65
- # or add username to support commands with mentions (/help@ChatBot)
66
- auction:
67
- token: TOKEN_2
68
- username: ChatBot
69
-
70
- # Single bot can be specified like this
71
- bot: TOKEN
72
- # or
73
- bot:
74
- token: TOKEN
75
- username: SomeBot
61
+ development:
62
+ telegram:
63
+ # Single bot can be specified like this
64
+ bot: TOKEN
65
+ # or
66
+ bot:
67
+ token: TOKEN
68
+ username: SomeBot
69
+
70
+ # For multiple bots in single app use hash of `internal_bot_id => settings`
71
+ bots:
72
+ # just set the bot token
73
+ chat: TOKEN_1
74
+ # or add username to support commands with mentions (/help@ChatBot)
75
+ auction:
76
+ token: TOKEN_2
77
+ username: ChatBot
76
78
  ```
77
79
 
78
- ### Client
79
-
80
80
  From now clients will be accessible with `Telegram.bots[:chat]` or `Telegram.bots[:auction]`.
81
81
  Single bot can be accessed with `Telegram.bot` or `Telegram.bots[:default]`.
82
82
 
83
- You can create clients manually with `Telegram::Bot::Client.new(token, username)`.
83
+ ### Client
84
+
85
+ Client is instantiated with `Telegram::Bot::Client.new(token, username)`.
84
86
  Username is optional and used only to parse commands with mentions.
85
87
 
86
88
  There is `request(path_suffix, body)` method to perform any query.
87
- And there are also shortcuts for available queries in underscored style
88
- (`answer_inline_query` instead of `answerInlineQuery`).
89
- All this methods just post given params to specific URL.
89
+ And there are shortcuts for all available requests in underscored style
90
+ (`answer_inline_query(params)` instead of `answerInlineQuery`).
90
91
 
91
92
  ```ruby
92
93
  bot.request(:getMe) or bot.get_me
93
94
  bot.request(:getupdates, offset: 1) or bot.get_updates(offset: 1)
94
- bot.send_message chat_id: chat_id, text: 'Test'
95
+ bot.send_message(chat_id: chat_id, text: 'Test')
95
96
  ```
96
97
 
98
+ There is no magic, they just pass params as is and set `path_suffix`.
99
+ See [`Client`](https://github.com/telegram-bot-rb/telegram-bot/blob/master/lib/telegram/bot/client.rb)
100
+ class for list of available methods. Please open PR or issue if it misses methods from
101
+ new API versions.
102
+
103
+ Any API request error will raise `Telegram::Bot::Error` with description in its message.
104
+ Special `Telegram::Bot::Forbidden` is raised when bot can't post messages to the chat anymore.
105
+
106
+ #### Typed responses
107
+
97
108
  By default client will return parsed json responses. You can enable
98
- response typecasting to virtus models using `telegram-bot-types` gem:
109
+ response typecasting to virtus models using
110
+ [`telegram-bot-types`](https://github.com/telegram-bot-rb/telegram-bot-types) gem:
111
+
99
112
  ```ruby
100
113
  # Add to your gemfile:
101
114
  gem 'telegram-bot-types', '~> x.x.x'
@@ -107,18 +120,23 @@ bot.extend Telegram::Bot::Client::TypedResponse
107
120
  bot.get_me.class # => Telegram::Bot::Types::User
108
121
  ```
109
122
 
110
- Any API request error will raise `Telegram::Bot::Error` with description in its message.
111
- Special `Telegram::Bot::Forbidden` is raised when bot can't post messages to the chat anymore.
112
-
113
123
  ### Controller
114
124
 
125
+ Controller makes it easy to keep bot's code readable.
126
+ It does nothing more than finding out action name for update and invoking it.
127
+ So there is almost no overhead comparing to large `switch`, while you
128
+ can represent actions as separate methods keeping source much more readable and supportable.
129
+
130
+ New instance of controller is instantiated for each update.
131
+ This way every update is processed in isolation from others.
132
+
115
133
  ```ruby
116
134
  class Telegram::WebhookController < Telegram::Bot::UpdatesController
117
135
  # use callbacks like in any other controllers
118
136
  around_action :with_locale
119
137
 
120
138
  # Every update can have one of: message, inline_query, chosen_inline_result,
121
- # callback_query.
139
+ # callback_query, etc.
122
140
  # Define method with same name to respond to this updates.
123
141
  def message(message)
124
142
  # message can be also accessed via instance method
@@ -171,7 +189,7 @@ end
171
189
  #### Reply helpers
172
190
 
173
191
  There are helpers to respond for basic actions. They just set chat/message/query
174
- identifiers from update. See `ReplyHelpers` method for more information.
192
+ identifiers from update. See [`ReplyHelpers`](https://github.com/telegram-bot-rb/telegram-bot/blob/master/lib/telegram/bot/updates_controller/reply_helpers.rb) module for more information.
175
193
  Here are this methods signatures:
176
194
 
177
195
  ```ruby
@@ -223,7 +241,8 @@ Default session id is made from bot's username and `(from || chat)['id']`.
223
241
  It means that session will be the same for updates from user in every chat,
224
242
  and different for every user in the same group chat.
225
243
  To change this behavior you can override `session_key` method, or even
226
- define multiple sessions in single controller. For details see `Session` module.
244
+ define [multiple sessions](https://github.com/telegram-bot-rb/telegram-bot/wiki/Multiple-session-objects)
245
+ in single controller. For details see `Session` module.
227
246
 
228
247
  ```ruby
229
248
  class Telegram::WebhookController < Telegram::Bot::UpdatesController
@@ -231,14 +250,14 @@ class Telegram::WebhookController < Telegram::Bot::UpdatesController
231
250
  # or just shortcut:
232
251
  use_session!
233
252
 
234
- # You can override global config
253
+ # You can override global config for this controller.
235
254
  self.session_store = :file_store
236
255
 
237
256
  def write(text = nil, *)
238
257
  session[:text] = text
239
258
  end
240
259
 
241
- def read
260
+ def read(*)
242
261
  respond_with :message, text: session[:text]
243
262
  end
244
263
 
@@ -249,11 +268,6 @@ class Telegram::WebhookController < Telegram::Bot::UpdatesController
249
268
  def session_key
250
269
  "#{bot.username}:#{chat['id']}:#{from['id']}" if chat && from
251
270
  end
252
-
253
- # This session will be the same for all updates in chat.
254
- def chat_session
255
- @_chat_session ||= self.class.build_session(chat && "#{bot.username}:#{chat['id']}")
256
- end
257
271
  end
258
272
  ```
259
273
 
@@ -292,77 +306,80 @@ class Telegram::WebhookController < Telegram::Bot::UpdatesController
292
306
  # This will call #rename like if it is called with message '/rename %text%'
293
307
  context_handler :rename
294
308
 
295
- # If you have a lot of such methods you can use
309
+ # If you have a lot of such methods you can call this method
310
+ # to use context value as action name for all contexts which miss handlers:
296
311
  context_to_action!
297
- # It'll use context value as action name for all contexts which miss handlers.
298
312
  end
299
313
  ```
300
314
 
301
- You can use `CallbackQueryContext` in the similar way to split `#callback_query` into
302
- several specific methods. It doesn't require session support, and takes context from
303
- data. If data has a prefix with colon like this `my_ctx:smth...` it'll call
304
- `my_ctx_callback_query('smth...')` when there is such action method. Otherwise
305
- it'll call `callback_query('my_ctx:smth...')` as usual.
315
+ #### Callback queries
306
316
 
307
- #### Processesing updates
308
-
309
- To process update run:
317
+ You can include `CallbackQueryContext` module to split `#callback_query` into
318
+ several methods. It doesn't require session support, and takes context from
319
+ data: if data has a prefix with colon like this `my_ctx:smth...` it invokes
320
+ `my_ctx_callback_query('smth...')` when such action method is defined. Otherwise
321
+ it invokes `callback_query('my_ctx:smth...')` as usual.
322
+ Callback queries without prefix stay untouched.
310
323
 
311
324
  ```ruby
312
- ControllerClass.dispatch(bot, update)
313
- ```
314
-
315
- There is also ability to run action without update:
325
+ # This one handles `set_value:%{something}`.
326
+ def set_value_callback_query(new_value = nil, *)
327
+ save_this(value)
328
+ answer_callback_query('Saved!)
329
+ end
316
330
 
317
- ```ruby
318
- # Most likely you'll want to pass :from and :chat
319
- controller = ControllerClass.new(bot, from: telegram_user, chat: telegram_chat)
320
- controller.process(:help, *args)
331
+ # And this one is for `make_cool:%{something}`
332
+ def make_cool_callback_query(thing = nil, *)
333
+ do_it(thing)
334
+ answer_callback_query("#{thing} is cool now! Like a callback query context.")
335
+ end
321
336
  ```
322
337
 
323
- ### Routes
338
+ ### Routes in Rails app
324
339
 
325
- Use `telegram_webhooks` helper to add routes. It will create routes for bots
326
- at "telegram/#{bot.token}" path.
340
+ There is `telegram_webhooks` helper for rails app to define routes for webhooks.
341
+ It defines routes at `telegram/#{bot.token}` and connects bots with controller.
342
+ For more options see [examples in wiki](https://github.com/telegram-bot-rb/telegram-bot/wiki/Routes-helpers-in-details).
327
343
 
328
344
  ```ruby
329
- # Create routes for all Telegram.bots to use same controller:
345
+ # Create routes for all Telegram.bots using single controller:
330
346
  telegram_webhooks TelegramController
331
347
 
332
- # Or pass custom bots usin any of supported config options:
333
- telegram_webhooks TelegramController,
334
- bot,
335
- {token: token, username: username},
336
- other_bot_token
337
-
338
348
  # Use different controllers for each bot:
339
- telegram_webhooks bot => TelegramChatController,
340
- other_bot => TelegramAuctionController
341
-
342
- # telegram_webhooks creates named routes.
343
- # Route name depends on `Telegram.bots`.
344
- # When there is single bot it will use 'telegram_webhook'.
345
- # When there are it will use bot's key in the `Telegram.bots` as prefix
346
- # (eg. `chat_telegram_webhook`).
347
- # You can override this options or specify others:
348
- telegram_webhooks TelegramController, as: :my_webhook
349
- telegram_webhooks bot => [TelegramChatController, as: :chat_webhook],
350
- other_bot => TelegramAuctionController,
351
- admin_chat: TelegramAdminChatController
349
+ telegram_webhooks chat: TelegramChatController,
350
+ auction: TelegramAuctionController
352
351
  ```
353
352
 
354
- For Rack applications you can also use `Telegram::Bot::Middleware` or just
355
- call `.dispatch(bot, update)` on controller.
353
+ #### Processesing updates
354
+
355
+ To process update with controller call `.dispatch(bot, update)` on it.
356
+ There are several options to run it automatically:
357
+
358
+ - Use webhooks with routes helper (described above).
359
+ - Use `Telegram::Bot::Middleware` with rack ([example in wiki](https://github.com/telegram-bot-rb/telegram-bot/wiki/Not-rails-application)).
360
+ - Use poller (described in the next section).
361
+
362
+ To run action without update (ex., send notifications from jobs),
363
+ you can call `#process` directly. In this case controller can be initialized
364
+ with `:from` and/or `:chat` options instead of `update` object:
365
+
366
+ ```ruby
367
+ controller = ControllerClass.new(bot, from: telegram_user, chat: telegram_chat)
368
+ controller.process(:welcome, *args)
369
+ ```
356
370
 
357
371
  ### Development & Debugging
358
372
 
359
- Use `rake telegram:bot:poller` to run poller. It'll automatically load
360
- changes without restart in development env. Optionally specify bot to run poller for
361
- with `BOT` envvar (`BOT=chat`).
373
+ Use `rake telegram:bot:poller` to run poller in rails app. It automatically loads
374
+ changes without restart in development env.
375
+ Optionally pass bot id in `BOT` envvar (`BOT=chat`) to specify bot to run poller for.
376
+
377
+ This task requires `telegram_webhooks` helper to be used as it connects bots with controller.
378
+ To run poller in other cases use:
362
379
 
363
- This task will not work if you don't use `telegram_webhooks`.
364
- You can run poller manually with
365
- `Telegram::Bot::UpdatesPoller.start(bot, controller_class)`.
380
+ ```ruby
381
+ Telegram::Bot::UpdatesPoller.start(bot, controller_class)
382
+ ```
366
383
 
367
384
  ### Testing
368
385
 
@@ -370,11 +387,11 @@ There is `Telegram::Bot::ClientStub` class to stub client for tests.
370
387
  Instead of performing API requests it stores them in `requests` hash.
371
388
 
372
389
  To stub all possible clients use `Telegram::Bot::ClientStub.stub_all!` before
373
- initializing clients. Most likely you'll want something like this:
390
+ initializing clients. Here is template for RSpec:
374
391
 
375
392
  ```ruby
376
393
  # environments/test.rb
377
- # Make sure to run it before defining routes or storing bot to some place in app!
394
+ # Make sure to run it before defining routes or accessing any bot in the app!
378
395
  Telegram.reset_bots
379
396
  Telegram::Bot::ClientStub.stub_all!
380
397
 
@@ -432,10 +449,11 @@ or just add `type: :request` to `describe`.
432
449
 
433
450
  See sample app for more examples.
434
451
 
435
- ### Deploying
452
+ ### Deployment
436
453
 
437
- Use `rake telegram:bot:set_webhook` to update webhook url for all configured bots.
438
- Certificate can be specified with `CERT=path/to/cert`.
454
+ While webhooks-mode is prefered, poller still can be used in production.
455
+ See [comparison and examples](https://github.com/telegram-bot-rb/telegram-bot/wiki/Deployment)
456
+ for details.
439
457
 
440
458
  ### Botan.io metrics
441
459
 
@@ -495,19 +513,18 @@ If you want async mode, but don't want to setup queue, know that Rails 5 are shi
495
513
  with Async adapter by default, and there is
496
514
  [Sucker Punch](https://github.com/brandonhilkert/sucker_punch) for Rails 4.
497
515
 
498
- Be aware of some limitations:
499
-
500
- - Client will not return API response.
501
- - Sending files is not available in async mode [now],
502
- because them can not be serialized.
503
-
504
516
  To disable async mode for the block of code use `bot.async(false) { bot.send_photo }`.
505
517
  Yes, it's threadsafe too.
506
518
 
519
+ #### Limitations
520
+
521
+ - Client will not return API response.
522
+ - Sending files is not available in async mode, because they can not be serialized.
523
+
507
524
  ## Development
508
525
 
509
526
  After checking out the repo, run `bin/setup` to install dependencies.
510
- Then, run `rake spec` to run the tests.
527
+ Then, run `appraisal rake spec` to run the tests.
511
528
  You can also run `bin/console` for an interactive prompt that will allow you to experiment.
512
529
 
513
530
  To install this gem onto your local machine, run `bundle exec rake install`.
@@ -515,15 +532,7 @@ To release a new version, update the version number in `version.rb`,
515
532
  and then run `bundle exec rake release`, which will create a git tag for the version,
516
533
  push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
517
534
 
518
- ### Different Rails versions
519
-
520
- To setup development for specific major Rails version use:
521
-
522
- ```
523
- RAILS=5 bundle install
524
- # or
525
- RAILS=5 bundle update
526
- ```
535
+ Use `bin/fetch-telegram-methods` to update API methods list from Telegram website.
527
536
 
528
537
  ## Contributing
529
538
 
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Fetch list of methods from Telegram docs.
4
+ # Use it to update client.rb.
5
+
6
+ require 'net/http'
7
+ require 'nokogiri'
8
+
9
+ DOCS_URL = 'https://core.telegram.org/bots/api'.freeze
10
+
11
+ page_html = Net::HTTP.get(URI(DOCS_URL))
12
+ doc = Nokogiri::HTML(page_html)
13
+
14
+ # Select `h4`s, but use `h3`s to group them.
15
+ headers = doc.css('h3, h4').
16
+ chunk_while { |_, x| x.name == 'h4' }.
17
+ map { |g| g.select { |x| x.name == 'h4' } }.
18
+ map { |g| g.map(&:text) }
19
+
20
+ # Method starts with lowercase and does not have spaces.
21
+ NOT_METHOD_REGEXP = /(\A[^a-z])|\s/
22
+
23
+ # Filter method names.
24
+ method_list = headers.
25
+ map { |g| g.reject { |x| x.match?(NOT_METHOD_REGEXP) } }.
26
+ reject(&:empty?)
27
+
28
+ api_version = doc.text.match(/^(Bot API ([\d\.]+))\.?$/)
29
+
30
+ result = ['# Generated with bin/fetch-telegram-methods']
31
+ result << "# #{api_version[1]}" if api_version
32
+ result << ''
33
+ result << method_list.map { |g| g.join("\n") }.join("\n\n")
34
+ result << ''
35
+ result_txt = result.join("\n")
36
+
37
+ puts result_txt
38
+
39
+ API_METHODS_FILE = File.expand_path('../lib/telegram/bot/client/api_methods.txt', __dir__).freeze
40
+ File.write(API_METHODS_FILE, result_txt)
41
+ puts '', "Updated #{API_METHODS_FILE}"
data/bin/setup CHANGED
@@ -3,6 +3,7 @@ set -euo pipefail
3
3
  IFS=$'\n\t'
4
4
 
5
5
  bundle install
6
+ appraisal install
6
7
  bin/install_git_hooks
7
8
 
8
9
  # Do any other automated setup that you need to do here
@@ -0,0 +1,21 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "actionpack", "~> 4.2"
6
+ gem "railties", "~> 4.2"
7
+
8
+ group :development do
9
+ gem "appraisal", "~> 2.2"
10
+ gem "pry", "~> 0.10.1"
11
+ gem "pry-byebug", "~> 3.2.0"
12
+ gem "sdoc", "~> 0.4.1"
13
+ gem "telegram-bot-types", "~> 0.3.0"
14
+ gem "rspec", "~> 3.5.0"
15
+ gem "rspec-its", "~> 1.1.0"
16
+ gem "rspec-rails", "~> 3.5.0"
17
+ gem "rubocop", "~> 0.51.0"
18
+ gem "coveralls", "~> 0.8.2", require: false
19
+ end
20
+
21
+ gemspec path: "../"
@@ -0,0 +1,21 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "actionpack", "~> 5.0"
6
+ gem "railties", "~> 5.0"
7
+
8
+ group :development do
9
+ gem "appraisal", "~> 2.2"
10
+ gem "pry", "~> 0.10.1"
11
+ gem "pry-byebug", "~> 3.2.0"
12
+ gem "sdoc", "~> 0.4.1"
13
+ gem "telegram-bot-types", "~> 0.3.0"
14
+ gem "rspec", "~> 3.5.0"
15
+ gem "rspec-its", "~> 1.1.0"
16
+ gem "rspec-rails", "~> 3.5.0"
17
+ gem "rubocop", "~> 0.51.0"
18
+ gem "coveralls", "~> 0.8.2", require: false
19
+ end
20
+
21
+ gemspec path: "../"
@@ -0,0 +1,21 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "actionpack", "~> 5.1"
6
+ gem "railties", "~> 5.1"
7
+
8
+ group :development do
9
+ gem "appraisal", "~> 2.2"
10
+ gem "pry", "~> 0.10.1"
11
+ gem "pry-byebug", "~> 3.2.0"
12
+ gem "sdoc", "~> 0.4.1"
13
+ gem "telegram-bot-types", "~> 0.3.0"
14
+ gem "rspec", "~> 3.5.0"
15
+ gem "rspec-its", "~> 1.1.0"
16
+ gem "rspec-rails", "~> 3.5.0"
17
+ gem "rubocop", "~> 0.51.0"
18
+ gem "coveralls", "~> 0.8.2", require: false
19
+ end
20
+
21
+ gemspec path: "../"
@@ -35,7 +35,7 @@ module Telegram
35
35
  def request(method, uri, query = {}, body = nil)
36
36
  res = http_request(method, uri, query.merge(token: token), body)
37
37
  status = res.status
38
- return JSON.parse(res.body) if 300 > status
38
+ return JSON.parse(res.body) if status < 300
39
39
  result = JSON.parse(res.body) rescue nil # rubocop:disable RescueModifier
40
40
  err_msg = "#{res.reason}: #{result && result['info'] || '-'}"
41
41
  raise Error, err_msg
@@ -1,11 +1,9 @@
1
1
  require 'json'
2
2
  require 'httpclient'
3
- require 'active_support/core_ext/string/inflections'
4
- require 'active_support/core_ext/hash/keys'
5
3
 
6
4
  module Telegram
7
5
  module Bot
8
- class Client # rubocop:disable ClassLength
6
+ class Client
9
7
  URL_TEMPLATE = 'https://api.telegram.org/bot%s/'.freeze
10
8
 
11
9
  autoload :TypedResponse, 'telegram/bot/client/typed_response'
@@ -14,6 +12,9 @@ module Telegram
14
12
  prepend Botan::ClientHelpers
15
13
  include DebugClient
16
14
 
15
+ require 'telegram/bot/client/api_helper'
16
+ include ApiHelper
17
+
17
18
  class << self
18
19
  def by_id(id)
19
20
  Telegram.bots[id]
@@ -49,7 +50,7 @@ module Telegram
49
50
  def request(action, body = {})
50
51
  res = http_request("#{base_uri}#{action}", self.class.prepare_body(body))
51
52
  status = res.status
52
- return JSON.parse(res.body) if 300 > status
53
+ return JSON.parse(res.body) if status < 300
53
54
  result = JSON.parse(res.body) rescue nil # rubocop:disable RescueModifier
54
55
  err_msg = result && result['description'] || '-'
55
56
  if result
@@ -62,72 +63,6 @@ module Telegram
62
63
  raise Error, "#{res.reason}: #{err_msg}"
63
64
  end
64
65
 
65
- # Splited to the sections similar to API docs.
66
- %w(
67
- deleteWebhook
68
- getUpdates
69
- getWebhookInfo
70
- setWebhook
71
-
72
- answerCallbackQuery
73
- deleteChatPhoto
74
- exportChatInviteLink
75
- forwardMessage
76
- getChat
77
- getChatAdministrators
78
- getChatMember
79
- getChatMembersCount
80
- getFile
81
- getMe
82
- getUserProfilePhotos
83
- kickChatMember
84
- leaveChat
85
- pinChatMessage
86
- promoteChatMember
87
- restrictChatMember
88
- sendAudio
89
- sendChatAction
90
- sendContact
91
- sendDocument
92
- sendLocation
93
- sendMessage
94
- sendPhoto
95
- sendVenue
96
- sendVideo
97
- sendVideoNote
98
- sendVoice
99
- setChatDescription
100
- setChatPhoto
101
- setChatTitle
102
- unbanChatMember
103
- unpinChatMessage
104
-
105
- deleteMessage
106
- editMessageCaption
107
- editMessageReplyMarkup
108
- editMessageText
109
-
110
- sendSticker
111
- getStickerSet
112
- uploadStickerFile
113
- createNewStickerSet
114
- addStickerToSet
115
- setStickerPositionInSet
116
- deleteStickerFromSet
117
-
118
- answerInlineQuery
119
-
120
- sendInvoice
121
- answerShippingQuery
122
- answerPreCheckoutQuery
123
-
124
- getGameHighScores
125
- sendGame
126
- setGameScore
127
- ).each do |method|
128
- define_method(method.underscore) { |*args| request(method, *args) }
129
- end
130
-
131
66
  # Endpoint for low-level request. For easy host highjacking & instrumentation.
132
67
  # Params are not used directly but kept for instrumentation purpose.
133
68
  # You probably don't want to use this method directly.
@@ -0,0 +1,31 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ module Telegram
4
+ module Bot
5
+ class Client
6
+ module ApiHelper
7
+ METHODS_LIST_FILE = File.expand_path('../api_methods.txt', __FILE__)
8
+
9
+ class << self
10
+ def methods_list(file = METHODS_LIST_FILE)
11
+ File.read(file).lines.
12
+ map(&:strip).
13
+ reject { |x| x.empty? || x.start_with?('#') }
14
+ end
15
+
16
+ # Defines method with underscored name to post to specific endpoint:
17
+ #
18
+ # define_method :getMe
19
+ # # defines #get_me
20
+ def define_helpers(*list)
21
+ list.map(&:to_s).each do |method|
22
+ define_method(method.underscore) { |*args| request(method, *args) }
23
+ end
24
+ end
25
+ end
26
+
27
+ define_helpers(*methods_list)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,68 @@
1
+ # Generated with bin/fetch-telegram-methods
2
+ # Bot API 3.5.
3
+
4
+ getUpdates
5
+ setWebhook
6
+ deleteWebhook
7
+ getWebhookInfo
8
+
9
+ getMe
10
+ sendMessage
11
+ forwardMessage
12
+ sendPhoto
13
+ sendAudio
14
+ sendDocument
15
+ sendVideo
16
+ sendVoice
17
+ sendVideoNote
18
+ sendMediaGroup
19
+ sendLocation
20
+ editMessageLiveLocation
21
+ stopMessageLiveLocation
22
+ sendVenue
23
+ sendContact
24
+ sendChatAction
25
+ getUserProfilePhotos
26
+ getFile
27
+ kickChatMember
28
+ unbanChatMember
29
+ restrictChatMember
30
+ promoteChatMember
31
+ exportChatInviteLink
32
+ setChatPhoto
33
+ deleteChatPhoto
34
+ setChatTitle
35
+ setChatDescription
36
+ pinChatMessage
37
+ unpinChatMessage
38
+ leaveChat
39
+ getChat
40
+ getChatAdministrators
41
+ getChatMembersCount
42
+ getChatMember
43
+ setChatStickerSet
44
+ deleteChatStickerSet
45
+ answerCallbackQuery
46
+
47
+ editMessageText
48
+ editMessageCaption
49
+ editMessageReplyMarkup
50
+ deleteMessage
51
+
52
+ sendSticker
53
+ getStickerSet
54
+ uploadStickerFile
55
+ createNewStickerSet
56
+ addStickerToSet
57
+ setStickerPositionInSet
58
+ deleteStickerFromSet
59
+
60
+ answerInlineQuery
61
+
62
+ sendInvoice
63
+ answerShippingQuery
64
+ answerPreCheckoutQuery
65
+
66
+ sendGame
67
+ setGameScore
68
+ getGameHighScores
@@ -1,3 +1,5 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+
1
3
  module Telegram
2
4
  module Bot
3
5
  module Initializers
@@ -78,7 +78,7 @@ module Telegram
78
78
 
79
79
  autoload :TypedUpdate, 'telegram/bot/updates_controller/typed_update'
80
80
 
81
- PAYLOAD_TYPES = %w(
81
+ PAYLOAD_TYPES = %w[
82
82
  message
83
83
  edited_message
84
84
  channel_post
@@ -88,7 +88,7 @@ module Telegram
88
88
  callback_query
89
89
  shipping_query
90
90
  pre_checkout_query
91
- ).freeze
91
+ ].freeze
92
92
  CMD_REGEX = %r{\A/([a-z\d_]{,31})(@(\S+))?(\s|$)}i
93
93
  CONFLICT_CMD_REGEX = Regexp.new("^(#{PAYLOAD_TYPES.join('|')}|\\d)")
94
94
 
@@ -39,7 +39,7 @@ module Telegram
39
39
  Instrumentation.instrument(:respond_with, type: type) { super }
40
40
  end
41
41
 
42
- %i(answer_callback_query answer_inline_query).each do |type|
42
+ %i[answer_callback_query answer_inline_query].each do |type|
43
43
  define_method(type) do |*args|
44
44
  Instrumentation.instrument(:respond_with, type: type) { super(*args) }
45
45
  end
@@ -17,7 +17,7 @@ module Telegram
17
17
  payload = event.payload
18
18
  additions = UpdatesController.log_process_action(payload)
19
19
  message = "Completed in #{event.duration.round}ms"
20
- message << " (#{additions.join(' | ')})" unless additions.blank?
20
+ message << " (#{additions.join(' | ')})" if additions.present?
21
21
  message
22
22
  end
23
23
  end
@@ -2,7 +2,7 @@ module Telegram
2
2
  module Bot
3
3
  class UpdatesController
4
4
  module Testing
5
- IVARS_TO_KEEP = %i(@_session).freeze
5
+ IVARS_TO_KEEP = %i[@_session].freeze
6
6
 
7
7
  # Perform multiple dispatches on same instance.
8
8
  def dispatch_again(bot = nil, update = nil)
@@ -50,7 +50,7 @@ module Telegram
50
50
  end
51
51
  rescue Interrupt
52
52
  @running = false
53
- rescue => e
53
+ rescue StandardError => e
54
54
  logger.error { ([e.message] + e.backtrace).join("\n") } if logger
55
55
  end
56
56
  end
@@ -1,6 +1,6 @@
1
1
  module Telegram
2
2
  module Bot
3
- VERSION = '0.12.1'.freeze
3
+ VERSION = '0.12.3'.freeze
4
4
 
5
5
  def self.gem_version
6
6
  Gem::Version.new VERSION
data/telegram-bot.gemspec CHANGED
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'telegram/bot/version'
@@ -20,9 +19,10 @@ Gem::Specification.new do |spec|
20
19
 
21
20
  spec.required_ruby_version = '~> 2.0'
22
21
 
23
- spec.add_dependency 'activesupport', '>= 4.0', '< 5.2'
24
- spec.add_dependency 'actionpack', '>= 4.0', '< 5.2'
22
+ spec.add_dependency 'actionpack', '>= 4.0', '< 6.0'
23
+ spec.add_dependency 'activesupport', '>= 4.0', '< 6.0'
25
24
  spec.add_dependency 'httpclient', '~> 2.7'
25
+
26
26
  spec.add_development_dependency 'bundler', '~> 1.11'
27
27
  spec.add_development_dependency 'rake', '~> 10.0'
28
28
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: telegram-bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Max Melentiev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-06 00:00:00.000000000 Z
11
+ date: 2017-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: activesupport
14
+ name: actionpack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: '4.0'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5.2'
22
+ version: '6.0'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,9 +29,9 @@ dependencies:
29
29
  version: '4.0'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5.2'
32
+ version: '6.0'
33
33
  - !ruby/object:Gem::Dependency
34
- name: actionpack
34
+ name: activesupport
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  version: '4.0'
40
40
  - - "<"
41
41
  - !ruby/object:Gem::Version
42
- version: '5.2'
42
+ version: '6.0'
43
43
  type: :runtime
44
44
  prerelease: false
45
45
  version_requirements: !ruby/object:Gem::Requirement
@@ -49,7 +49,7 @@ dependencies:
49
49
  version: '4.0'
50
50
  - - "<"
51
51
  - !ruby/object:Gem::Version
52
- version: '5.2'
52
+ version: '6.0'
53
53
  - !ruby/object:Gem::Dependency
54
54
  name: httpclient
55
55
  requirement: !ruby/object:Gem::Requirement
@@ -103,15 +103,20 @@ files:
103
103
  - ".rspec"
104
104
  - ".rubocop.yml"
105
105
  - ".travis.yml"
106
+ - Appraisals
106
107
  - CHANGELOG.md
107
108
  - Gemfile
108
109
  - LICENSE.txt
109
110
  - README.md
110
111
  - Rakefile
111
112
  - bin/console
113
+ - bin/fetch-telegram-methods
112
114
  - bin/git-hooks/pre-commit
113
115
  - bin/install_git_hooks
114
116
  - bin/setup
117
+ - gemfiles/rails_42.gemfile
118
+ - gemfiles/rails_50.gemfile
119
+ - gemfiles/rails_51.gemfile
115
120
  - lib/tasks/telegram-bot.rake
116
121
  - lib/telegram/bot.rb
117
122
  - lib/telegram/bot/async.rb
@@ -119,6 +124,8 @@ files:
119
124
  - lib/telegram/bot/botan/client_helpers.rb
120
125
  - lib/telegram/bot/botan/controller_helpers.rb
121
126
  - lib/telegram/bot/client.rb
127
+ - lib/telegram/bot/client/api_helper.rb
128
+ - lib/telegram/bot/client/api_methods.txt
122
129
  - lib/telegram/bot/client/typed_response.rb
123
130
  - lib/telegram/bot/client_stub.rb
124
131
  - lib/telegram/bot/config_methods.rb
@@ -163,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
163
170
  version: '0'
164
171
  requirements: []
165
172
  rubyforge_project:
166
- rubygems_version: 2.6.8
173
+ rubygems_version: 2.6.14
167
174
  signing_key:
168
175
  specification_version: 4
169
176
  summary: Library for building Telegram Bots with Rails integration