telegram-bot 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +2 -0
- data/CHANGELOG.md +7 -0
- data/README.md +84 -5
- data/lib/telegram/bot/client.rb +4 -1
- data/lib/telegram/bot/client_stub.rb +29 -0
- data/lib/telegram/bot/config_methods.rb +7 -0
- data/lib/telegram/bot/routes_helper.rb +3 -1
- data/lib/telegram/bot/updates_controller.rb +92 -10
- data/lib/telegram/bot/updates_controller/message_context.rb +102 -0
- data/lib/telegram/bot/updates_controller/rspec_helpers.rb +16 -10
- data/lib/telegram/bot/updates_controller/session.rb +4 -12
- data/lib/telegram/bot/updates_controller/testing.rb +47 -0
- data/lib/telegram/bot/updates_controller/typed_update.rb +1 -1
- data/lib/telegram/bot/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a045d870c213b5136f08e93b6f6e243b9276c6bb
|
4
|
+
data.tar.gz: f83f3bfd325fbb5014939ea0c4db049c2d8a228a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed51cc7ddcb72060182cc6f22ef8e0ab11c7ac07223a03c6c24b301db7a46bab88800b1a00044558d40d17a87fde09bdfa0b7c310039c97a31b7bb172d9f0e56
|
7
|
+
data.tar.gz: 5617505f1d36c7967777bb27c0b1fd1025f7f0617629c884a67ca8092702642760526295ea21683b7d924b2d9f2e5f8350b847600a3506f289b225511fc73d5f
|
data/.rubocop.yml
CHANGED
@@ -8,9 +8,11 @@ Style/AlignParameters:
|
|
8
8
|
# EnforcedStyle:
|
9
9
|
# - with_first_parameter
|
10
10
|
# - with_fixed_indentation
|
11
|
+
Style/AndOr: {EnforcedStyle: conditionals}
|
11
12
|
Style/ClosingParenthesisIndentation: {Enabled: false}
|
12
13
|
Style/Documentation: {Enabled: false}
|
13
14
|
Style/DotPosition: {EnforcedStyle: trailing}
|
15
|
+
Style/FirstParameterIndentation: {EnforcedStyle: consistent}
|
14
16
|
Style/IfUnlessModifier: {Enabled: false}
|
15
17
|
Style/ModuleFunction: {Enabled: false}
|
16
18
|
Style/MultilineOperationIndentation: {EnforcedStyle: indented}
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -142,7 +142,7 @@ You can enable typecasting of `update` with `telegram-bot-types` by including
|
|
142
142
|
|
143
143
|
```ruby
|
144
144
|
class Telegram::WebhookController < Telegram::Bot::UpdatesController
|
145
|
-
include Telegram::Bot::
|
145
|
+
include Telegram::Bot::UpdatesController::TypedUpdate
|
146
146
|
|
147
147
|
def message(message)
|
148
148
|
message.class # => Telegram::Bot::Types::Message
|
@@ -158,6 +158,9 @@ config.telegram_updates_controller.session_store = :redis_store, {expires_in: 1.
|
|
158
158
|
|
159
159
|
class Telegram::WebhookController < Telegram::Bot::UpdatesController
|
160
160
|
include Telegram::Bot::UpdatesController::Session
|
161
|
+
# or just shortcut:
|
162
|
+
use_session!
|
163
|
+
|
161
164
|
# You can override global config
|
162
165
|
self.session_store = :file_store
|
163
166
|
|
@@ -166,7 +169,7 @@ class Telegram::WebhookController < Telegram::Bot::UpdatesController
|
|
166
169
|
end
|
167
170
|
|
168
171
|
def read
|
169
|
-
session[:text]
|
172
|
+
reply_with :message, text: session[:text]
|
170
173
|
end
|
171
174
|
|
172
175
|
private
|
@@ -180,6 +183,59 @@ class Telegram::WebhookController < Telegram::Bot::UpdatesController
|
|
180
183
|
end
|
181
184
|
```
|
182
185
|
|
186
|
+
It's usual to support chain of messages like BotFather: after receiving command
|
187
|
+
it asks you for additional argument. There is `MessageContext` for this:
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
class Telegram::WebhookController < Telegram::Bot::UpdatesController
|
191
|
+
include Telegram::Bot::UpdatesController::MessageContext
|
192
|
+
|
193
|
+
def rename(*)
|
194
|
+
# set context for the next message
|
195
|
+
save_context :rename
|
196
|
+
reply_with :message, text: 'What name do you like?'
|
197
|
+
end
|
198
|
+
|
199
|
+
# register context handlers to handle this context
|
200
|
+
context_handler :rename do |message|
|
201
|
+
update_name message[:text]
|
202
|
+
reply_with :message, text: 'Renamed!'
|
203
|
+
end
|
204
|
+
|
205
|
+
# You can do it in other way:
|
206
|
+
def rename(name = nil, *)
|
207
|
+
if name
|
208
|
+
update_name name
|
209
|
+
reply_with :message, text: 'Renamed!'
|
210
|
+
else
|
211
|
+
save_context :rename
|
212
|
+
reply_with :message, text: 'What name do you like?'
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# This will call #rename like if it is called with message '/rename %text%'
|
217
|
+
context_handler :rename
|
218
|
+
|
219
|
+
# If you have a lot of such methods you can use
|
220
|
+
context_to_action!
|
221
|
+
# It'll use context value as action name for all contexts which miss handlers.
|
222
|
+
end
|
223
|
+
```
|
224
|
+
|
225
|
+
To process update run:
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
ControllerClass.dispatch(bot, update)
|
229
|
+
```
|
230
|
+
|
231
|
+
There is also ability to run action without update:
|
232
|
+
|
233
|
+
```ruby
|
234
|
+
# Most likely you'll want to pass :from and :chat
|
235
|
+
controller = ControllerClass.new(bot, from: telegram_user, chat: telegram_chat)
|
236
|
+
controller.process(:help, *args)
|
237
|
+
```
|
238
|
+
|
183
239
|
### Routes
|
184
240
|
|
185
241
|
Use `telegram_webhooks` helper to add routes. It will create routes for bots
|
@@ -215,13 +271,36 @@ call `.dispatch(bot, update)` on controller.
|
|
215
271
|
|
216
272
|
### Development & Debugging
|
217
273
|
|
218
|
-
Use `rake telegram:bot:poller
|
219
|
-
changes without restart in development env.
|
220
|
-
`
|
274
|
+
Use `rake telegram:bot:poller` to run poller. It'll automatically load
|
275
|
+
changes without restart in development env. Optionally specify bot to run poller for
|
276
|
+
with `BOT` envvar (`BOT=chat`).
|
221
277
|
|
278
|
+
This task will not work if you don't use `telegram_webhooks`.
|
222
279
|
You can run poller manually with
|
223
280
|
`Telegram::Bot::UpdatesPoller.start(bot, controller_class)`.
|
224
281
|
|
282
|
+
### Testing
|
283
|
+
|
284
|
+
There is `Telegram::Bot::ClientStub` class to stub client for tests.
|
285
|
+
Instead of performing API requests it stores them in `requests` hash.
|
286
|
+
|
287
|
+
To stub all possible clients use `Telegram::Bot::ClientStub.stub_all!` before
|
288
|
+
initializing clients. Most likely you'll want something like this:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
RSpec.configure do |config|
|
292
|
+
# ...
|
293
|
+
Telegram.reset_bots
|
294
|
+
Telegram::Bot::ClientStub.stub_all!
|
295
|
+
config.after { Telegram.bot.reset }
|
296
|
+
# ...
|
297
|
+
end
|
298
|
+
```
|
299
|
+
|
300
|
+
There are also some helpers for controller tests.
|
301
|
+
Check out `telegram/bot/updates_controller/rspec_helpers` and
|
302
|
+
`telegram/bot/updates_controller/testing`.
|
303
|
+
|
225
304
|
### Deploying
|
226
305
|
|
227
306
|
Use `rake telegram:bot:set_webhook` to update webhook url for all configured bots.
|
data/lib/telegram/bot/client.rb
CHANGED
@@ -19,6 +19,9 @@ module Telegram
|
|
19
19
|
when Hash then
|
20
20
|
input = input.stringify_keys
|
21
21
|
new input['token'], input['username']
|
22
|
+
when Symbol
|
23
|
+
Telegram.bots[input] or
|
24
|
+
raise "Bot #{input} not configured, check Telegram.bots_config."
|
22
25
|
else
|
23
26
|
new(input)
|
24
27
|
end
|
@@ -104,7 +107,7 @@ module Telegram
|
|
104
107
|
end
|
105
108
|
|
106
109
|
def inspect
|
107
|
-
"
|
110
|
+
"#<#{self.class.name}##{object_id}(#{@username})>"
|
108
111
|
end
|
109
112
|
end
|
110
113
|
end
|
@@ -4,6 +4,35 @@ module Telegram
|
|
4
4
|
class ClientStub < Client
|
5
5
|
attr_reader :requests
|
6
6
|
|
7
|
+
module StubbedConstructor
|
8
|
+
def new(*args)
|
9
|
+
if self == ClientStub || !ClientStub.stub_all?
|
10
|
+
super
|
11
|
+
else
|
12
|
+
ClientStub.new(args[1])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# Makes all
|
19
|
+
def stub_all!(enabled = true)
|
20
|
+
Client.extend(StubbedConstructor) unless Client < StubbedConstructor
|
21
|
+
return @_stub_all = enabled unless block_given?
|
22
|
+
begin
|
23
|
+
old = @_stub_all
|
24
|
+
stub_all!(enabled)
|
25
|
+
yield
|
26
|
+
ensure
|
27
|
+
stub_all!(old)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def stub_all?
|
32
|
+
@_stub_all
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
7
36
|
def initialize(username = nil)
|
8
37
|
@username = username
|
9
38
|
reset
|
@@ -42,7 +42,9 @@ module Telegram
|
|
42
42
|
# # You can override this options or specify others:
|
43
43
|
# telegram_webhooks TelegramController, as: :my_webhook
|
44
44
|
# telegram_webhooks bot => [TelegramChatController, as: :chat_webhook],
|
45
|
-
# other_bot =>
|
45
|
+
# other_bot => TelegramAuctionController,
|
46
|
+
# admin_chat: TelegramAdminChatController
|
47
|
+
#
|
46
48
|
def telegram_webhooks(controllers, bots = nil, **options)
|
47
49
|
unless controllers.is_a?(Hash)
|
48
50
|
bots = bots ? Array.wrap(bots) : Telegram.bots.values
|
@@ -4,12 +4,59 @@ require 'active_support/version'
|
|
4
4
|
|
5
5
|
module Telegram
|
6
6
|
module Bot
|
7
|
+
# Base class to create update processors. With callbacks, session and helpers.
|
8
|
+
#
|
9
|
+
# Define public methods for each command and they will be called when
|
10
|
+
# update has this command. Message is automatically parsed and
|
11
|
+
# words are passed as method arguments. Be sure to use default values and
|
12
|
+
# splat arguments in every action method to not get errors, when user
|
13
|
+
# sends command without necessary args / with extra args.
|
14
|
+
#
|
15
|
+
# def start(token = nil, *)
|
16
|
+
# if token
|
17
|
+
# # ...
|
18
|
+
# else
|
19
|
+
# # ...
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# def help(*)
|
24
|
+
# reply_with :message, text:
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# To process plain text messages (without commands) or other updates just
|
28
|
+
# define public method with name of payload type. They will receive payload
|
29
|
+
# as an argument.
|
30
|
+
#
|
31
|
+
# def message(message)
|
32
|
+
# reply_with :message, text: "Echo: #{message['text']}"
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# def inline_query(query)
|
36
|
+
# answer_inline_query results_for_query(query), is_personal: true
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# # To process conflicting commands (`/message args`) just use `on_` prefix:
|
40
|
+
# def on_message(*args)
|
41
|
+
# # ...
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# To process update run:
|
45
|
+
#
|
46
|
+
# ControllerClass.dispatch(bot, update)
|
47
|
+
#
|
48
|
+
# There is also ability to run action without update:
|
49
|
+
#
|
50
|
+
# ControllerClass.new(bot, from: telegram_user, chat: telegram_chat).
|
51
|
+
# process(:help, *args)
|
52
|
+
#
|
7
53
|
class UpdatesController < AbstractController::Base
|
8
54
|
abstract!
|
9
55
|
|
10
56
|
require 'telegram/bot/updates_controller/session'
|
11
57
|
require 'telegram/bot/updates_controller/log_subscriber'
|
12
58
|
require 'telegram/bot/updates_controller/instrumentation'
|
59
|
+
autoload :MessageContext, 'telegram/bot/updates_controller/message_context'
|
13
60
|
|
14
61
|
include AbstractController::Callbacks
|
15
62
|
# Redefine callbacks with default terminator.
|
@@ -37,6 +84,7 @@ module Telegram
|
|
37
84
|
CONFLICT_CMD_REGEX = Regexp.new("^(#{PAYLOAD_TYPES.join('|')}|\\d)")
|
38
85
|
|
39
86
|
class << self
|
87
|
+
# Initialize controller and process update.
|
40
88
|
def dispatch(*args)
|
41
89
|
new(*args).dispatch
|
42
90
|
end
|
@@ -59,7 +107,7 @@ module Telegram
|
|
59
107
|
match = text.match CMD_REGEX
|
60
108
|
return unless match
|
61
109
|
return if match[3] && username != true && match[3] != username
|
62
|
-
[match[1], text.split
|
110
|
+
[match[1], text.split.drop(1)]
|
63
111
|
end
|
64
112
|
end
|
65
113
|
|
@@ -67,18 +115,39 @@ module Telegram
|
|
67
115
|
alias_method :command?, :is_command
|
68
116
|
delegate :username, to: :bot, prefix: true, allow_nil: true
|
69
117
|
|
118
|
+
# Second argument can be either update object with hash access & string
|
119
|
+
# keys or Hash with `:from` or `:chat` to override this values and assume
|
120
|
+
# that update is nil.
|
70
121
|
def initialize(bot = nil, update = nil)
|
122
|
+
if update.is_a?(Hash) && (update.key?(:from) || update.key?(:chat))
|
123
|
+
options = update
|
124
|
+
update = nil
|
125
|
+
end
|
71
126
|
@_update = update
|
72
127
|
@_bot = bot
|
128
|
+
@_chat, @_from = options && options.values_at(:chat, :from)
|
73
129
|
|
130
|
+
payload_data = nil
|
74
131
|
update && PAYLOAD_TYPES.find do |type|
|
75
132
|
item = update[type]
|
76
|
-
|
77
|
-
@_payload = item
|
78
|
-
@_payload_type = type
|
133
|
+
payload_data = [item, type] if item
|
79
134
|
end
|
135
|
+
@_payload, @_payload_type = payload_data
|
136
|
+
end
|
137
|
+
|
138
|
+
# Accessor to `'chat'` field of payload. Can be overriden with `chat` option
|
139
|
+
# for #initialize.
|
140
|
+
def chat
|
141
|
+
@_chat || payload && payload['chat']
|
80
142
|
end
|
81
143
|
|
144
|
+
# Accessor to `'from'` field of payload. Can be overriden with `from` option
|
145
|
+
# for #initialize.
|
146
|
+
def from
|
147
|
+
@_from || payload && payload['from']
|
148
|
+
end
|
149
|
+
|
150
|
+
# Processes current update.
|
82
151
|
def dispatch
|
83
152
|
@_is_command, action, args = action_for_payload
|
84
153
|
process(action, *args)
|
@@ -102,19 +171,32 @@ module Telegram
|
|
102
171
|
def action_missing(*)
|
103
172
|
end
|
104
173
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
174
|
+
# Helper to call bot's `send_#{type}` method with already set `chat_id` and
|
175
|
+
# `reply_to_message_id`:
|
176
|
+
#
|
177
|
+
# reply_with :message, text: 'Hello!'
|
178
|
+
# reply_with :message, text: '__Hello!__', parse_mode: :Markdown
|
179
|
+
# reply_with :photo, photo: File.open(photo_to_send), caption: "It's incredible!"
|
109
180
|
def reply_with(type, params)
|
110
181
|
method = "send_#{type}"
|
182
|
+
chat = self.chat
|
183
|
+
payload = self.payload
|
111
184
|
params = params.merge(
|
112
|
-
chat_id: chat['id'],
|
113
|
-
reply_to_message: payload['message_id'],
|
185
|
+
chat_id: (chat && chat['id'] or raise 'Can not reply_with when chat is not present'),
|
186
|
+
reply_to_message: payload && payload['message_id'],
|
114
187
|
)
|
115
188
|
bot.public_send(method, params)
|
116
189
|
end
|
117
190
|
|
191
|
+
# Same as reply_with, but for inline queries.
|
192
|
+
def answer_inline_query(results, params = {})
|
193
|
+
params = params.merge(
|
194
|
+
inline_query_id: payload['id'],
|
195
|
+
results: results,
|
196
|
+
)
|
197
|
+
bot.answer_inline_query(params)
|
198
|
+
end
|
199
|
+
|
118
200
|
ActiveSupport.run_load_hooks('telegram.bot.updates_controller', self)
|
119
201
|
end
|
120
202
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
class UpdatesController
|
4
|
+
# Allows to store context in session and treat next message according to this context.
|
5
|
+
module MessageContext
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
include Session
|
9
|
+
|
10
|
+
included do
|
11
|
+
# As we use before_action context is cleared anyway,
|
12
|
+
# no matter we used it or not.
|
13
|
+
before_action :fetch_context
|
14
|
+
singleton_class.send :attr_reader, :context_handlers, :context_to_action
|
15
|
+
@context_handlers = {}
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
# Registers handler for context.
|
20
|
+
#
|
21
|
+
# context_handler :rename do |message|
|
22
|
+
# resource.update!(name: message['text'])
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# # To run other action with all the callbacks:
|
26
|
+
# context_handler :rename do |message|
|
27
|
+
# process(:rename, *m['text'].split)
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # Or just
|
31
|
+
# context_handler :rename, :your_action_to_call
|
32
|
+
# context_handler :rename # to call :rename
|
33
|
+
#
|
34
|
+
# # For messages without context use this instead of `message` method:
|
35
|
+
# context_handle do |message|
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
def context_handler(context = nil, action = nil, &block)
|
39
|
+
context &&= context.to_sym
|
40
|
+
context_handlers[context] = block || action || context
|
41
|
+
end
|
42
|
+
|
43
|
+
# Use it to use context value as action name for all contexts
|
44
|
+
# which miss handlers.
|
45
|
+
# For security reasons it supports only action methods and will
|
46
|
+
# raise AbstractController::ActionNotFound if context is invalid.
|
47
|
+
def context_to_action!
|
48
|
+
@context_to_action = true
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Finds handler for current context and processes message with it.
|
53
|
+
def message(message)
|
54
|
+
handler = handler_for_context
|
55
|
+
return unless handler
|
56
|
+
if handler.respond_to?(:call)
|
57
|
+
instance_exec(message, &handler)
|
58
|
+
else
|
59
|
+
process(handler, *message['text'].split)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Action to clear context.
|
64
|
+
def cancel
|
65
|
+
# Context is already cleared in before_action
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
# Context is read from the session to treat messages
|
71
|
+
# according to previous request.
|
72
|
+
attr_reader :context
|
73
|
+
|
74
|
+
# Fetches and removes context from session.
|
75
|
+
def fetch_context
|
76
|
+
val = session.delete(:context)
|
77
|
+
@context = val && val.to_sym
|
78
|
+
true # TODO: remove in Rails 5.0
|
79
|
+
end
|
80
|
+
|
81
|
+
# Save context for the next request.
|
82
|
+
def save_context(context)
|
83
|
+
session[:context] = context
|
84
|
+
end
|
85
|
+
|
86
|
+
def handler_for_context
|
87
|
+
self.class.context_handlers[context] || self.class.context_to_action && begin
|
88
|
+
action_name = context.to_s
|
89
|
+
unless action_method?(action_name)
|
90
|
+
raise AbstractController::ActionNotFound,
|
91
|
+
"The action '#{action_name}' could not be set from context " \
|
92
|
+
"for #{self.class.name}. " \
|
93
|
+
'context_to_action! supports only action methods for security reasons. ' \
|
94
|
+
'If you need to call this action use context_handler for it.'
|
95
|
+
end
|
96
|
+
action_name
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -1,23 +1,29 @@
|
|
1
|
+
require 'telegram/bot/updates_controller/testing'
|
2
|
+
|
1
3
|
RSpec.shared_context 'telegram/bot/updates_controller' do
|
2
4
|
let(:controller_class) { described_class }
|
3
|
-
let(:
|
4
|
-
|
5
|
-
|
5
|
+
let(:controller) do
|
6
|
+
controller_class.new(bot, update).tap do |x|
|
7
|
+
x.extend Telegram::Bot::UpdatesController::Testing
|
8
|
+
end
|
9
|
+
end
|
10
|
+
let(:update) { build_update(payload_type, payload) }
|
11
|
+
let(:payload_type) { :some_type }
|
6
12
|
let(:payload) { double(:payload) }
|
7
13
|
let(:bot) { Telegram::Bot::ClientStub.new(bot_name) }
|
8
14
|
let(:bot_name) { 'bot' }
|
9
|
-
let(:session)
|
10
|
-
|
11
|
-
|
12
|
-
|
15
|
+
let(:session) { controller.send(:session) }
|
16
|
+
|
17
|
+
def dispatch(bot = self.bot, update = self.update)
|
18
|
+
controller.dispatch_again(bot, update)
|
13
19
|
end
|
14
20
|
|
15
21
|
def dispatch_message(text, options = {})
|
16
|
-
|
17
|
-
|
22
|
+
update = build_update :message, options.merge(text: text)
|
23
|
+
dispatch bot, update
|
18
24
|
end
|
19
25
|
|
20
|
-
def
|
26
|
+
def build_update(type, content)
|
21
27
|
deep_stringify type => content
|
22
28
|
end
|
23
29
|
|
@@ -59,24 +59,16 @@ module Telegram
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
class TestSessionHash < SessionHash
|
63
|
-
def initialize
|
64
|
-
@data = {}
|
65
|
-
@loaded = true
|
66
|
-
@exists = true
|
67
|
-
end
|
68
|
-
|
69
|
-
alias_method :destroy, :clear
|
70
|
-
alias_method :load!, :id
|
71
|
-
alias_method :commit, :id
|
72
|
-
end
|
73
|
-
|
74
62
|
module ConfigMethods
|
75
63
|
delegate :session_store, to: :config
|
76
64
|
|
77
65
|
def session_store=(store)
|
78
66
|
config.session_store = ActiveSupport::Cache.lookup_store(store)
|
79
67
|
end
|
68
|
+
|
69
|
+
def use_session!
|
70
|
+
include Session
|
71
|
+
end
|
80
72
|
end
|
81
73
|
end
|
82
74
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Telegram
|
2
|
+
module Bot
|
3
|
+
class UpdatesController
|
4
|
+
module Testing
|
5
|
+
IVARS_TO_KEEP = %i(@_session).freeze
|
6
|
+
|
7
|
+
# Perform multiple dispatches on same instance.
|
8
|
+
def dispatch_again(bot = nil, update = nil)
|
9
|
+
recycle!
|
10
|
+
initialize(bot, update)
|
11
|
+
dispatch
|
12
|
+
end
|
13
|
+
|
14
|
+
# Cleans controller between dispatches.
|
15
|
+
# Seems like there is nothing to clean between requests for now:
|
16
|
+
# everything will be rewriten with #initialize.
|
17
|
+
#
|
18
|
+
# With `full` set to `true` it'll clear all cached instance variables.
|
19
|
+
def recycle!(full = false)
|
20
|
+
return unless full
|
21
|
+
(instance_variables - IVARS_TO_KEEP).each do |ivar|
|
22
|
+
remove_instance_variable(ivar)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
# Stubs session.
|
29
|
+
def session
|
30
|
+
@_session ||= Testing::SessionHash.new
|
31
|
+
end
|
32
|
+
|
33
|
+
class SessionHash < Session::SessionHash
|
34
|
+
def initialize
|
35
|
+
@data = {}
|
36
|
+
@loaded = true
|
37
|
+
@exists = true
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :destroy, :clear
|
41
|
+
alias_method :load!, :id
|
42
|
+
alias_method :commit, :id
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -4,7 +4,7 @@ module Telegram
|
|
4
4
|
# Include this module to type cast update to Virtus model
|
5
5
|
# using `telegram-bot-types` gem (install this gem first).
|
6
6
|
module TypedUpdate
|
7
|
-
def initialize(bot, update)
|
7
|
+
def initialize(bot = nil, update = nil)
|
8
8
|
update = Types::Update.new(update) if update && !update.is_a?(Types::Update)
|
9
9
|
super
|
10
10
|
end
|
data/lib/telegram/bot/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: telegram-bot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Max Melentiev
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- ".rspec"
|
92
92
|
- ".rubocop.yml"
|
93
93
|
- ".travis.yml"
|
94
|
+
- CHANGELOG.md
|
94
95
|
- Gemfile
|
95
96
|
- LICENSE.txt
|
96
97
|
- README.md
|
@@ -111,8 +112,10 @@ files:
|
|
111
112
|
- lib/telegram/bot/updates_controller.rb
|
112
113
|
- lib/telegram/bot/updates_controller/instrumentation.rb
|
113
114
|
- lib/telegram/bot/updates_controller/log_subscriber.rb
|
115
|
+
- lib/telegram/bot/updates_controller/message_context.rb
|
114
116
|
- lib/telegram/bot/updates_controller/rspec_helpers.rb
|
115
117
|
- lib/telegram/bot/updates_controller/session.rb
|
118
|
+
- lib/telegram/bot/updates_controller/testing.rb
|
116
119
|
- lib/telegram/bot/updates_controller/typed_update.rb
|
117
120
|
- lib/telegram/bot/updates_poller.rb
|
118
121
|
- lib/telegram/bot/version.rb
|