rbender 0.5.35 → 0.7.3

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.
@@ -6,6 +6,7 @@ class RBender::MongoClient
6
6
  attr_reader :mongo_client
7
7
 
8
8
  public
9
+
9
10
  def self.client
10
11
  instance.mongo_client
11
12
  end
@@ -15,7 +16,7 @@ class RBender::MongoClient
15
16
  end
16
17
 
17
18
  def setup(bot_name, mongo_string)
18
- @bot_name = bot_name
19
+ @bot_name = bot_name
19
20
  @mongo_client = Mongo::Client.new(mongo_string, :database => bot_name)
20
21
 
21
22
  Mongo::Logger.logger.level = ::Logger::FATAL
@@ -2,8 +2,9 @@ module RBender
2
2
  module SessionManager
3
3
 
4
4
  private
5
+
5
6
  def session_setup(mongo_client)
6
- @mongo_client = mongo_client
7
+ @mongo_client = mongo_client
7
8
  @sessions_mongo = @mongo_client[:sessions]
8
9
  end
9
10
 
@@ -16,9 +17,9 @@ module RBender
16
17
  end
17
18
 
18
19
  def save_session(session)
19
- @sessions_mongo.update_one({chat_id: session[:user][:chat_id]},
20
- {'$set' => {session: session}},
21
- {upsert: true})
20
+ @sessions_mongo.update_one({ chat_id: session[:chat_id] },
21
+ { '$set' => { session: session } },
22
+ { upsert: true })
22
23
  end
23
24
 
24
25
  def has_session?(chat_id)
@@ -27,26 +28,22 @@ module RBender
27
28
  end
28
29
 
29
30
  public
30
- def self.chatid_list
31
- sessions = RBender::MongoClient.client[:sessions]
32
- result = sessions.distinct('chat_id')
33
- chatid_list = []
31
+
32
+ def self.chat_id_list
33
+ sessions = RBender::MongoClient.client[:sessions]
34
+ result = sessions.distinct('chat_id')
35
+ chat_id_list = []
34
36
  result.each do |doc|
35
37
  chatid_list << doc
36
38
  end
37
- chatid_list
39
+ chat_id_list
38
40
  end
39
41
  end
40
42
  end
41
43
 
42
- #
43
44
  # Mongo scheme:
44
45
  # Session
45
46
  # {chat_id: {session_key: session_value}}
46
47
  #
47
48
  # States
48
49
  # {chat_id: state}
49
- #
50
- #
51
- #
52
- #
data/lib/rbender/state.rb CHANGED
@@ -1,244 +1,308 @@
1
1
  class RBender::State
2
-
3
- def initialize(message, api, session, &state_block)
4
- @message = message
5
- @api = api
6
- @session = session
7
- @state_block = state_block
8
- @keyboard = nil
9
- @inline_keyboards = {}
10
- @action_after = nil
11
- @action_before = nil
12
- @text_action = nil
13
- @helpers_block = nil
14
- @methods = RBender::Methods.new(message, api, session)
15
- @commands = {}
16
- end
17
-
18
- def get_keyboard
19
- @keyboard
20
- end
21
-
22
- def message
23
- @message
24
- end
25
-
26
- # Invokes states and processes user's input
27
- def invoke
28
- case message
29
- when Telegram::Bot::Types::CallbackQuery
30
- process_callback
31
- when Telegram::Bot::Types::Message
32
- if @message.text
33
- if @message.text[0] == '/' and @message.text != '/start'
34
- process_command(@message.text)
35
- else
36
- process_text_message
37
- end
38
- elsif @message.photo
39
- process_photo
40
- end
41
-
42
- when Telegram::Bot::Types::Document
43
- if @message.photo
44
- process_photo
45
- end
46
- else
47
- raise "This type isn't available: #{message.class}"
48
- end
49
- end
50
-
51
- # @param command String
52
- def process_command(command_line)
53
- splitted = command_line.split(" ")
54
- command = splitted[0]
55
- splitted.delete_at 0
56
- params = splitted
57
-
58
- if @commands.include? command
59
- instance_exec(params, &@commands[command])
60
- end
61
- end
62
-
63
- def process_photo
64
- instance_exec(message.photo, &@photo_action) unless @photo_action.nil?
65
- end
66
-
67
- # Process if message is just text
68
- def process_text_message
69
-
70
- unless @keyboard.nil? # if state has keyboard
71
- @keyboard.instance_eval(&@helpers_block) unless @helpers_block.nil?
72
- build_keyboard
73
-
74
- @keyboard.markup_final.each do |btn, final_btn|
75
- if message.text == final_btn
76
- instance_exec(&@keyboard.actions[btn])
77
- end
78
- end
79
- end
80
-
81
- unless @text_action.nil?
82
- instance_exec(@message.text, &@text_action)
83
- end
84
-
85
- end
86
-
87
- # Process if message is inline keyboard callback
88
- def process_callback
89
- keyboard_name, action = @message.data.split(RBender::CALLBACK_SPLITTER)
90
- keyboard = @inline_keyboards[keyboard_name.to_sym]
91
- keyboard.instance_eval(&@helpers_block) unless @helpers_block.nil?
92
- keyboard.invoke unless keyboard.nil?
93
-
94
- unless keyboard.nil?
95
- unless keyboard.buttons_actions[action].nil?
96
- instance_eval(&keyboard.buttons_actions[action])
97
- else
98
- raise "There is no action called '#{action}'"
99
- end
100
- else
101
- edit_message_text text: "deleted"
102
- end
103
- end
104
-
105
- def build
106
- instance_exec(&@state_block)
107
- end
108
-
109
- def build_keyboard
110
- @keyboard.build(@session)
111
- end
112
-
113
- def invoke_keyboard
114
-
115
- @api.send_message(chat_id: message.from.id,
116
- text: @keyboard.response,
117
- reply_markup: @keyboard.markup_tg)
118
- end
119
-
120
- def invoke_before
121
- instance_eval(&@action_before)
122
- end
123
-
124
- def has_after?
125
- @action_after.nil? ? false : true
126
- end
127
-
128
- def has_before?
129
- @action_before.nil? ? false : true
130
- end
131
-
132
- def invoke_after
133
- instance_eval(&@action_after)
134
- end
135
-
136
- def has_keyboard?
137
- @keyboard.nil? ? false : true
138
- end
139
-
140
- public
141
-
142
- # adds inline keyboard
143
- def keyboard_inline(inline_keyboard_name, &inline_keyboard_block)
144
- @inline_keyboards[inline_keyboard_name] = RBender::KeyboardInline.new(inline_keyboard_name,
145
- @session,
146
- inline_keyboard_block)
147
- end
148
-
149
- #before hook
150
- def before(&action)
151
- if @action_before.nil?
152
- @action_before = action
153
- else
154
- raise 'Too many before hooks!'
155
- end
156
- end
157
-
158
- #after hook
159
- def after(&action)
160
- if @action_after.nil?
161
- @action_after = action
162
- else
163
- raise 'Too many after hooks!'
164
- end
165
- end
166
-
167
- # Text callbacks
168
- def text(&action)
169
- if @text_action.nil?
170
- @text_action = action
171
- else
172
- raise 'Too many text processors!'
173
- end
174
- end
175
-
176
- def keyboard(&keyboard_block)
177
- @keyboard = RBender::Keyboard.new
178
- @keyboard.session = @session
179
- @keyboard.instance_eval(&keyboard_block)
180
- end
181
-
182
- #initialize helper methods
183
- def helpers(&helpers_block)
184
- @helpers_block = helpers_block
185
- instance_eval(&helpers_block)
186
- end
187
-
188
- def photo(&action)
189
- if @photo_action.nil?
190
- @photo_action = action
191
- else
192
- raise 'Too many image processors!'
193
- end
194
- end
195
-
196
- alias image photo
197
- alias picture photo
198
-
199
- def command(command, &action)
200
- unless @commands.include? command
201
- if command[0] == '/'
202
- @commands[command] = action
203
- else
204
- raise "Command should be started from slash symbol (/)"
205
- end
206
- else
207
- raise "Command #{command} already exists"
208
- end
209
- end
210
-
211
-
212
- def method_missing(m, *args, &block)
213
- if RBender::Methods.method_defined? m
214
- if block_given?
215
- if args.empty?
216
- return @methods.send(m, &block)
217
- else
218
- args = args[0] if args.count == 1
219
- return @methods.send(m, args, &block)
220
- end
221
- else
222
- if args.empty?
223
- return @methods.send(m)
224
- else
225
- args = args[0] if args.count == 1
226
- return @methods.send(m, args)
227
- end
228
- end
229
- else
230
- raise NoMethodError, "Method #{m} is missing"
231
- end
232
- end
233
-
234
- # Returns Inline keyboard object by name
235
- def inline_markup(name)
236
- raise "Keyboard #{name} doesn't exists!" unless @inline_keyboards.member? name
237
- keyboard = @inline_keyboards[name]
238
- keyboard.instance_eval(&@helpers_block) unless @helpers_block.nil?
239
- keyboard.build
240
- keyboard.markup_tg
241
- end
242
-
2
+ def initialize(message, api, session, &state_block)
3
+ @message = message
4
+ @api = api
5
+ @session = session
6
+ @chat_id = @session[:chat_id]
7
+ @methods = RBender::Methods.new(message, api, session)
8
+ @state_block = state_block
9
+
10
+ @keyboard = nil
11
+
12
+ @inline_keyboards_blocks = {}
13
+ @after_block = nil
14
+ @before_block = nil
15
+ @text_block = nil
16
+ @helpers_block = nil
17
+ @pre_checkout_block = nil
18
+ @checkout_block = nil
19
+ @shipping_block = nil
20
+ @photo_block = nil
21
+ @contact_block = nil
22
+
23
+ @commands_blocks = {}
24
+ end
25
+
26
+ def get_keyboard
27
+ @keyboard
28
+ end
29
+
30
+ def message
31
+ @message
32
+ end
33
+
34
+ # Invokes states and processes user's input
35
+ def invoke
36
+ case message
37
+ when Telegram::Bot::Types::CallbackQuery
38
+ process_callback
39
+ when Telegram::Bot::Types::Message
40
+ if @message.text
41
+ if @message.text[0] == '/' and @message.text != '/start'
42
+ process_command(@message.text)
43
+ else
44
+ process_text_message
45
+ end
46
+ elsif @message.successful_payment
47
+ process_checkout
48
+ elsif @message.contact
49
+ process_contact
50
+ elsif @message.photo
51
+ process_photo
52
+ end
53
+ when Telegram::Bot::Types::Document
54
+ if @message.photo
55
+ process_photo
56
+ end
57
+ when Telegram::Bot::Types::PreCheckoutQuery
58
+ process_pre_checkout
59
+ when Telegram::Bot::Types::ShippingQuery
60
+ process_shipping
61
+ else
62
+ raise "This type isn't available: #{message.class}"
63
+ end
64
+ end
65
+
66
+ def process_pre_checkout
67
+ instance_exec(@message, &@pre_checkout_block)
68
+ end
69
+
70
+ def process_checkout
71
+ instance_exec(@message.successful_payment, &@checkout_block)
72
+ end
73
+
74
+ def process_shipping
75
+ instance_exec(@message.shipping_query, &@shipping_block)
76
+ end
77
+
78
+ # @param command String
79
+ def process_command(command_line)
80
+ splitted = command_line.split(" ")
81
+ command = splitted[0]
82
+ splitted.delete_at 0
83
+ params = splitted
84
+
85
+ if @commands_blocks.include? command
86
+ instance_exec(params, &@commands_blocks[command])
87
+ end
88
+ end
89
+
90
+ def process_photo
91
+ instance_exec(message.photo, &@photo_block) unless @photo_block.nil?
92
+ end
93
+
94
+ def process_contact
95
+ instance_exec(message.contact, &@contact_block) unless @contact_block.nil?
96
+ end
97
+
98
+ # Process if message is just text
99
+ def process_text_message
100
+ unless @keyboard.nil? # if state has keyboard
101
+ @keyboard.instance_eval(&@helpers_block) unless @helpers_block.nil?
102
+ build_keyboard
103
+
104
+ @keyboard.markup_final.each do |btn, final_btn|
105
+ if message.text == final_btn
106
+ instance_exec(&@keyboard.actions[btn]) # Process keyboard action
107
+ return
108
+ end
109
+ end
110
+ end
111
+
112
+ unless @text_block.nil? # Else process text action
113
+ instance_exec(@message.text, &@text_block)
114
+ end
115
+ end
116
+
117
+ # Process if message is inline keyboard callback
118
+ def process_callback
119
+ keyboard_name, action = @message.data.split(RBender::CALLBACK_SPLITTER)
120
+ keyboard = @inline_keyboards_blocks[keyboard_name.to_sym]
121
+ keyboard.instance_eval(&@helpers_block) unless @helpers_block.nil?
122
+ keyboard.invoke unless keyboard.nil?
123
+
124
+ unless keyboard.nil?
125
+ unless keyboard.buttons_actions[action].nil?
126
+ instance_eval(&keyboard.buttons_actions[action])
127
+ else
128
+ raise "There is no action called '#{action}'"
129
+ end
130
+ else
131
+ edit_message_text text: "deleted"
132
+ end
133
+ end
134
+
135
+ def build
136
+ instance_exec(&@state_block)
137
+ end
138
+
139
+ def build_keyboard
140
+ @keyboard.build(@session)
141
+ end
142
+
143
+ def invoke_keyboard
144
+ @api.send_message(chat_id: @chat_id,
145
+ text: @keyboard.response,
146
+ reply_markup: @keyboard.markup_tg)
147
+ end
148
+
149
+ def invoke_before
150
+ instance_eval(&@before_block)
151
+ end
152
+
153
+ def has_after?
154
+ @after_block.nil? ? false : true
155
+ end
156
+
157
+ def has_before?
158
+ @before_block.nil? ? false : true
159
+ end
160
+
161
+ def invoke_after
162
+ instance_eval(&@after_block)
163
+ end
164
+
165
+ def has_keyboard?
166
+ @keyboard.nil? ? false : true
167
+ end
168
+
169
+ public
170
+
171
+ # adds inline keyboard
172
+ def keyboard_inline(inline_keyboard_name, &inline_keyboard_block)
173
+ @inline_keyboards_blocks[inline_keyboard_name] = RBender::KeyboardInline.new(inline_keyboard_name,
174
+ @session,
175
+ inline_keyboard_block)
176
+ end
177
+
178
+ #before hook
179
+ def before(&action)
180
+ if @before_block.nil?
181
+ @before_block = action
182
+ else
183
+ raise 'Too many before hooks!'
184
+ end
185
+ end
186
+
187
+ #after hook
188
+ def after(&action)
189
+ if @after_block.nil?
190
+ @after_block = action
191
+ else
192
+ raise 'Too many after hooks!'
193
+ end
194
+ end
195
+
196
+ # Text callbacks
197
+ def text(&action)
198
+ if @text_block.nil?
199
+ @text_block = action
200
+ else
201
+ raise 'Too many text processors!'
202
+ end
203
+ end
204
+
205
+ def keyboard(&keyboard_block)
206
+ if @is_global
207
+ raise 'Global state doesn\'t support :keyboard method'
208
+ end
209
+ @keyboard = RBender::Keyboard.new
210
+ @keyboard.session = @session
211
+ @keyboard.instance_eval(&keyboard_block)
212
+ end
213
+
214
+ #initialize helper methods
215
+ def helpers(&helpers_block)
216
+ @helpers_block = helpers_block
217
+ instance_eval(&helpers_block)
218
+ end
219
+
220
+ def photo(&block)
221
+ if @photo_action.nil?
222
+ @photo_block = block
223
+ else
224
+ raise 'Image block already defined'
225
+ end
226
+ end
227
+
228
+ alias image photo
229
+ alias picture photo
230
+
231
+ def contact(&block)
232
+ if @contact_block.nil?
233
+ @contact_block = block
234
+ else
235
+ raise 'Contact block already defined'
236
+ end
237
+ end
238
+
239
+ def command(command, &action)
240
+ if @commands_blocks.include? command
241
+ raise "Command #{command} already exists"
242
+ else
243
+ if command[0] == '/'
244
+ @commands_blocks[command] = action
245
+ else
246
+ raise "Command should be started from slash symbol (/)"
247
+ end
248
+ end
249
+ end
250
+
251
+
252
+ def method_missing(m, *args, &block)
253
+ if RBender::Methods.method_defined? m
254
+ if block_given?
255
+ if args.empty?
256
+ return @methods.send(m, &block)
257
+ else
258
+ args = args[0] if args.count == 1
259
+ return @methods.send(m, args, &block)
260
+ end
261
+ else
262
+ if args.empty?
263
+ return @methods.send(m)
264
+ else
265
+ args = args[0] if args.count == 1
266
+ return @methods.send(m, args)
267
+ end
268
+ end
269
+ else
270
+ raise NoMethodError, "Method #{m} is missing"
271
+ end
272
+ end
273
+
274
+ # Returns Inline keyboard object by name
275
+ def inline_markup(name)
276
+ raise "Keyboard #{name} doesn't exists!" unless @inline_keyboards_blocks.member? name
277
+ keyboard = @inline_keyboards_blocks[name]
278
+ keyboard.instance_eval(&@helpers_block) unless @helpers_block.nil?
279
+ keyboard.build
280
+ keyboard.markup_tg
281
+ end
282
+
283
+ def pre_checkout(&block)
284
+ if @pre_checkout_block.nil?
285
+ @pre_checkout_block = block
286
+ else
287
+ raise 'Too many pre_checkout actions'
288
+ end
289
+ end
290
+
291
+ alias pre_checkout_query pre_checkout
292
+
293
+ def checkout(&block)
294
+ if @checkout_block.nil?
295
+ @checkout_block = block
296
+ else
297
+ raise 'Too many pre_checkout actions'
298
+ end
299
+ end
300
+
301
+ alias successful_payment checkout
302
+ alias payment checkout
303
+
304
+ def shipping(&block)
305
+ @shipping_block = block
306
+ end
243
307
  end
244
308