telegem 3.3.0 → 3.4.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.
data/lib/api/types.rb CHANGED
@@ -5,91 +5,106 @@ module Telegem
5
5
  @_raw_data = data || {}
6
6
  @_accessors_defined = {}
7
7
  end
8
-
8
+
9
9
  def method_missing(name, *args)
10
10
  return super if args.any? || block_given?
11
-
11
+
12
12
  define_accessor(name)
13
-
13
+
14
14
  if respond_to?(name)
15
15
  send(name)
16
16
  else
17
17
  super
18
18
  end
19
19
  end
20
-
20
+
21
21
  def respond_to_missing?(name, include_private = false)
22
22
  key = name.to_s
23
23
  camel_key = snake_to_camel(key)
24
24
  @_raw_data.key?(key) || @_raw_data.key?(camel_key) || super
25
25
  end
26
-
26
+
27
27
  def to_h
28
28
  @_raw_data.dup
29
29
  end
30
-
30
+
31
31
  alias_method :to_hash, :to_h
32
-
32
+
33
33
  def inspect
34
34
  "#<#{self.class.name} #{@_raw_data.inspect}>"
35
35
  end
36
-
36
+
37
37
  def to_s
38
38
  inspect
39
39
  end
40
-
40
+
41
41
  attr_reader :_raw_data
42
-
42
+
43
43
  private
44
-
44
+
45
45
  def define_accessor(name)
46
46
  return if @_accessors_defined[name]
47
-
47
+
48
48
  key = name.to_s
49
49
  camel_key = snake_to_camel(key)
50
-
50
+
51
51
  if @_raw_data.key?(key)
52
52
  define_singleton_method(name) { @_raw_data[key] }
53
53
  elsif @_raw_data.key?(camel_key)
54
54
  define_singleton_method(name) { @_raw_data[camel_key] }
55
55
  else
56
56
  define_singleton_method(name) do
57
- raise NoMethodError,
57
+ raise NoMethodError,
58
58
  "undefined method `#{name}' for #{self.class} with keys: #{@_raw_data.keys}"
59
59
  end
60
60
  end
61
-
61
+
62
62
  @_accessors_defined[name] = true
63
63
  end
64
-
64
+
65
+ # helpers for converting nested objects
66
+ def wrap(key, klass)
67
+ if @_raw_data[key] && !@_raw_data[key].is_a?(klass)
68
+ @_raw_data[key] = klass.new(@_raw_data[key])
69
+ end
70
+ end
71
+
72
+ def wrap_array(key, klass)
73
+ if @_raw_data[key] && @_raw_data[key].is_a?(Array)
74
+ @_raw_data[key] = @_raw_data[key].map do |v|
75
+ v.is_a?(klass) ? v : klass.new(v)
76
+ end
77
+ end
78
+ end
79
+
65
80
  def snake_to_camel(str)
66
81
  str.gsub(/_([a-z])/) { $1.upcase }
67
82
  end
68
-
83
+
69
84
  def camel_to_snake(str)
70
85
  str.gsub(/([A-Z])/) { "_#{$1.downcase}" }.sub(/^_/, '')
71
86
  end
72
87
  end
73
-
88
+
74
89
  class User < BaseType
75
90
  COMMON_FIELDS = %w[id is_bot first_name last_name username
76
- can_join_groups can_read_all_group_messages
77
- supports_inline_queries language_code
78
- is_premium added_to_attachment_menu
79
- can_connect_to_business].freeze
80
-
91
+ can_join_groups can_read_all_group_messages
92
+ supports_inline_queries language_code
93
+ is_premium added_to_attachment_menu
94
+ can_connect_to_business can_manage_bots].freeze
95
+
81
96
  def initialize(data)
82
97
  super(data)
83
-
98
+
84
99
  COMMON_FIELDS.each do |field|
85
100
  define_accessor(field.to_sym)
86
101
  end
87
102
  end
88
-
103
+
89
104
  def full_name
90
105
  [first_name, last_name].compact.join(' ')
91
106
  end
92
-
107
+
93
108
  def mention
94
109
  if username
95
110
  "@#{username}"
@@ -99,127 +114,127 @@ module Telegem
99
114
  "User ##{id}"
100
115
  end
101
116
  end
102
-
117
+
103
118
  def to_s
104
119
  full_name
105
120
  end
106
121
  end
107
-
122
+
108
123
  class Chat < BaseType
109
124
  COMMON_FIELDS = %w[id type username title first_name last_name
110
- photo bio has_private_forwards
125
+ photo bio has_private_forwards
111
126
  has_restricted_voice_and_video_messages
112
- description invite_link pinned_message
127
+ description invite_link pinned_message
113
128
  permissions slow_mode_delay message_auto_delete_time
114
- has_protected_content sticker_set_name
129
+ has_protected_content sticker_set_name
115
130
  can_set_sticker_set linked_chat_id location].freeze
116
-
131
+
117
132
  def initialize(data)
118
133
  super(data)
119
-
134
+
120
135
  COMMON_FIELDS.each do |field|
121
136
  define_accessor(field.to_sym)
122
137
  end
123
138
  end
124
-
139
+
125
140
  def private?
126
141
  type == 'private'
127
142
  end
128
-
143
+
129
144
  def group?
130
145
  type == 'group'
131
146
  end
132
-
147
+
133
148
  def supergroup?
134
149
  type == 'supergroup'
135
150
  end
136
-
151
+
137
152
  def channel?
138
153
  type == 'channel'
139
154
  end
140
-
155
+
141
156
  def to_s
142
157
  title || username || "Chat ##{id}"
143
158
  end
144
159
  end
145
-
160
+
146
161
  class MessageEntity < BaseType
147
162
  COMMON_FIELDS = %w[type offset length url user language
148
163
  custom_emoji_id].freeze
149
-
164
+
150
165
  def initialize(data)
151
166
  super(data)
152
-
167
+
153
168
  COMMON_FIELDS.each do |field|
154
169
  define_accessor(field.to_sym)
155
170
  end
156
-
171
+
157
172
  if @_raw_data['user'] && !@_raw_data['user'].is_a?(User)
158
173
  @_raw_data['user'] = User.new(@_raw_data['user'])
159
174
  end
160
175
  end
161
176
  end
162
-
177
+
163
178
  class Message < BaseType
164
- COMMON_FIELDS = %w[message_id from chat date edit_date
165
- text caption entities caption_entities
166
- audio document photo sticker video voice
167
- video_note contact location venue
168
- new_chat_members left_chat_member
169
- new_chat_title new_chat_photo
170
- delete_chat_photo group_chat_created
171
- supergroup_chat_created channel_chat_created
172
- migrate_to_chat_id migrate_from_chat_id
173
- pinned_message invoice successful_payment
174
- connected_website reply_markup via_bot
175
- forward_from forward_from_chat
176
- forward_from_message_id forward_signature
177
- forward_sender_name forward_date reply_to_message
178
- media_group_id author_signature
179
- has_protected_content].freeze
180
-
179
+ COMMON_FIELDS = %w[message_id from chat date edit_date
180
+ text caption entities caption_entities
181
+ audio document photo sticker video voice
182
+ video_note contact location venue
183
+ new_chat_members left_chat_member
184
+ new_chat_title new_chat_photo
185
+ delete_chat_photo group_chat_created
186
+ supergroup_chat_created channel_chat_created
187
+ migrate_to_chat_id migrate_from_chat_id
188
+ pinned_message invoice successful_payment
189
+ connected_website reply_markup via_bot
190
+ forward_from forward_from_chat
191
+ forward_from_message_id forward_signature
192
+ forward_sender_name forward_date reply_to_message
193
+ media_group_id author_signature
194
+ has_protected_content managed_bot_created managed_bot].freeze
195
+
181
196
  def initialize(data)
182
197
  super(data)
183
-
198
+
184
199
  COMMON_FIELDS.each do |field|
185
200
  define_accessor(field.to_sym)
186
201
  end
187
-
202
+
188
203
  convert_complex_fields
189
204
  end
190
-
205
+
191
206
  def command?
192
207
  return false unless text && entities
193
-
194
- entities.any? { |e| e.type == 'bot_command' &&
208
+
209
+ entities.any? { |e| e.type == 'bot_command' &&
195
210
  text[e.offset, e.length]&.start_with?('/') }
196
211
  end
197
-
212
+
198
213
  def command_name
199
214
  return nil unless command?
200
-
215
+
201
216
  command_entity = entities.find { |e| e.type == 'bot_command' }
202
217
  return nil unless command_entity
203
-
218
+
204
219
  cmd = text[command_entity.offset, command_entity.length]
205
220
  return nil if cmd.nil? || cmd.length <= 1
206
-
221
+
207
222
  cmd = cmd[1..-1]
208
223
  cmd.split('@').first.strip
209
224
  end
210
-
225
+
211
226
  def command_args
212
227
  return nil unless command?
213
-
228
+
214
229
  command_entity = entities.find { |e| e.type == 'bot_command' }
215
230
  return nil unless command_entity
216
-
231
+
217
232
  args_start = command_entity.offset + command_entity.length
218
233
  remaining = text[args_start..-1]
219
-
234
+
220
235
  next_entity = entities.select { |e| e.offset >= args_start }
221
236
  .min_by(&:offset)
222
-
237
+
223
238
  if next_entity
224
239
  args_end = next_entity.offset - 1
225
240
  text[args_start..args_end]&.strip
@@ -227,15 +242,15 @@ module Telegem
227
242
  remaining&.strip
228
243
  end
229
244
  end
230
-
245
+
231
246
  def reply?
232
247
  !!reply_to_message
233
248
  end
234
-
249
+
235
250
  def has_media?
236
251
  !!(audio || document || photo || video || voice || video_note || sticker)
237
252
  end
238
-
253
+
239
254
  def media_type
240
255
  return :audio if audio
241
256
  return :document if document
@@ -246,142 +261,166 @@ module Telegem
246
261
  return :sticker if sticker
247
262
  nil
248
263
  end
249
-
264
+
250
265
  private
251
-
266
+
252
267
  def convert_complex_fields
253
- if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
254
- @_raw_data['date'] = Time.at(@_raw_data['date'])
255
- end
256
-
257
- if @_raw_data['edit_date'] && !@_raw_data['edit_date'].is_a?(Time)
258
- @_raw_data['edit_date'] = Time.at(@_raw_data['edit_date'])
259
- end
260
-
261
- if @_raw_data['forward_date'] && !@_raw_data['forward_date'].is_a?(Time)
262
- @_raw_data['forward_date'] = Time.at(@_raw_data['forward_date'])
263
- end
264
-
265
- @_raw_data['from'] = User.new(@_raw_data['from']) if @_raw_data['from'] && !@_raw_data['from'].is_a?(User)
266
- @_raw_data['chat'] = Chat.new(@_raw_data['chat']) if @_raw_data['chat'] && !@_raw_data['chat'].is_a?(Chat)
267
- @_raw_data['via_bot'] = User.new(@_raw_data['via_bot']) if @_raw_data['via_bot'] && !@_raw_data['via_bot'].is_a?(User)
268
- @_raw_data['forward_from'] = User.new(@_raw_data['forward_from']) if @_raw_data['forward_from'] && !@_raw_data['forward_from'].is_a?(User)
269
- @_raw_data['forward_from_chat'] = Chat.new(@_raw_data['forward_from_chat']) if @_raw_data['forward_from_chat'] && !@_raw_data['forward_from_chat'].is_a?(Chat)
270
- @_raw_data['left_chat_member'] = User.new(@_raw_data['left_chat_member']) if @_raw_data['left_chat_member'] && !@_raw_data['left_chat_member'].is_a?(User)
271
-
272
- if @_raw_data['entities'] && @_raw_data['entities'].is_a?(Array)
273
- @_raw_data['entities'] = @_raw_data['entities'].map do |e|
274
- e.is_a?(MessageEntity) ? e : MessageEntity.new(e)
275
- end
276
- end
277
-
278
- if @_raw_data['caption_entities'] && @_raw_data['caption_entities'].is_a?(Array)
279
- @_raw_data['caption_entities'] = @_raw_data['caption_entities'].map do |e|
280
- e.is_a?(MessageEntity) ? e : MessageEntity.new(e)
281
- end
282
- end
283
-
284
- if @_raw_data['reply_to_message'] && !@_raw_data['reply_to_message'].is_a?(Message)
285
- @_raw_data['reply_to_message'] = Message.new(@_raw_data['reply_to_message'])
286
- end
287
-
288
- if @_raw_data['pinned_message'] && !@_raw_data['pinned_message'].is_a?(Message)
289
- @_raw_data['pinned_message'] = Message.new(@_raw_data['pinned_message'])
290
- end
291
-
292
- if @_raw_data['new_chat_members'] && @_raw_data['new_chat_members'].is_a?(Array)
293
- @_raw_data['new_chat_members'] = @_raw_data['new_chat_members'].map do |u|
294
- u.is_a?(User) ? u : User.new(u)
295
- end
296
- end
297
-
268
+ # time conversions
269
+ @_raw_data['date'] = Time.at(@_raw_data['date']) if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
270
+ @_raw_data['edit_date'] = Time.at(@_raw_data['edit_date']) if @_raw_data['edit_date'] && !@_raw_data['edit_date'].is_a?(Time)
271
+ @_raw_data['forward_date'] = Time.at(@_raw_data['forward_date']) if @_raw_data['forward_date'] && !@_raw_data['forward_date'].is_a?(Time)
272
+
273
+ # basic object wrappers
274
+ wrap('from', User)
275
+ wrap('chat', Chat)
276
+ wrap('via_bot', User)
277
+ wrap('forward_from', User)
278
+ wrap('forward_from_chat', Chat)
279
+ wrap('left_chat_member', User)
280
+
281
+ wrap_array('entities', MessageEntity)
282
+ wrap_array('caption_entities', MessageEntity)
283
+
284
+ wrap('reply_to_message', Message)
285
+ wrap('pinned_message', Message)
286
+ wrap_array('new_chat_members', User)
287
+
288
+ # media and other nested types
289
+ wrap('contact', Contact)
290
+ wrap('location', Location)
291
+ wrap('venue', Venue)
292
+ wrap('dice', Dice)
293
+ wrap('poll', Poll)
294
+ wrap('proximity_alert_triggered', ProximityAlertTriggered)
295
+ wrap('web_app_data', WebAppData)
296
+
297
+ wrap('animation', Animation)
298
+ wrap('audio', Audio)
299
+ wrap('document', Document)
300
+ wrap('video', Video)
301
+ wrap('voice', Voice)
302
+ wrap('video_note', VideoNote)
303
+ wrap('sticker', Sticker)
304
+
305
+ wrap('invoice', Invoice)
306
+ wrap('successful_payment', SuccessfulPayment)
307
+ wrap('reply_markup', BaseType)
308
+
309
+ wrap('passport_data', PassportData)
310
+
311
+ wrap('video_chat_scheduled', VideoChatScheduled)
312
+ wrap('video_chat_started', VideoChatStarted)
313
+ wrap('video_chat_ended', VideoChatEnded)
314
+ wrap('video_chat_participants_invited', VideoChatParticipantsInvited)
315
+ wrap('video_chat_location', VideoChatLocation)
316
+
317
+ # new message event objects introduced in later API versions
318
+ wrap('message_auto_delete_timer_changed', MessageAutoDeleteTimerChanged)
319
+ wrap('forum_topic_created', ForumTopicCreated)
320
+ wrap('forum_topic_edited', ForumTopicEdited)
321
+ wrap('forum_topic_closed', ForumTopicClosed)
322
+ wrap('forum_topic_reopened', ForumTopicReopened)
323
+ wrap('general_forum_topic_hidden', GeneralForumTopicHidden)
324
+ wrap('general_forum_topic_unhidden', GeneralForumTopicUnhidden)
325
+ wrap('write_access_allowed', WriteAccessAllowed)
326
+
327
+ # Bot API 9.6 - Managed Bot Support
328
+ wrap('managed_bot_created', ManagedBotCreated)
329
+ wrap('managed_bot', ManagedBotUpdated)
330
+
331
+ # arrays of sizes and photos
332
+ wrap_array('photo', PhotoSize)
333
+ wrap_array('new_chat_photo', PhotoSize)
334
+
335
+ # fall back to original media wrapper for backward compatibility
298
336
  wrap_media_objects
299
337
  end
300
-
338
+
301
339
  def wrap_media_objects
302
- # Media files
303
- @_raw_data['document'] = BaseType.new(@_raw_data['document']) if @_raw_data['document'] && !@_raw_data['document'].is_a?(BaseType)
304
- @_raw_data['audio'] = BaseType.new(@_raw_data['audio']) if @_raw_data['audio'] && !@_raw_data['audio'].is_a?(BaseType)
305
- @_raw_data['video'] = BaseType.new(@_raw_data['video']) if @_raw_data['video'] && !@_raw_data['video'].is_a?(BaseType)
306
- @_raw_data['voice'] = BaseType.new(@_raw_data['voice']) if @_raw_data['voice'] && !@_raw_data['voice'].is_a?(BaseType)
307
- @_raw_data['video_note'] = BaseType.new(@_raw_data['video_note']) if @_raw_data['video_note'] && !@_raw_data['video_note'].is_a?(BaseType)
308
- @_raw_data['sticker'] = BaseType.new(@_raw_data['sticker']) if @_raw_data['sticker'] && !@_raw_data['sticker'].is_a?(BaseType)
309
-
340
+ # Media files (fall‑back to generic types if no specific class defined)
341
+ @_raw_data['document'] = Document.new(@_raw_data['document']) if @_raw_data['document'] && !@_raw_data['document'].is_a?(Document)
342
+ @_raw_data['animation'] = Animation.new(@_raw_data['animation']) if @_raw_data['animation'] && !@_raw_data['animation'].is_a?(Animation)
343
+ @_raw_data['audio'] = Audio.new(@_raw_data['audio']) if @_raw_data['audio'] && !@_raw_data['audio'].is_a?(Audio)
344
+ @_raw_data['video'] = Video.new(@_raw_data['video']) if @_raw_data['video'] && !@_raw_data['video'].is_a?(Video)
345
+ @_raw_data['voice'] = Voice.new(@_raw_data['voice']) if @_raw_data['voice'] && !@_raw_data['voice'].is_a?(Voice)
346
+ @_raw_data['video_note'] = VideoNote.new(@_raw_data['video_note']) if @_raw_data['video_note'] && !@_raw_data['video_note'].is_a?(VideoNote)
347
+ @_raw_data['sticker'] = Sticker.new(@_raw_data['sticker']) if @_raw_data['sticker'] && !@_raw_data['sticker'].is_a?(Sticker)
348
+
310
349
  # Photo array
311
350
  if @_raw_data['photo'] && @_raw_data['photo'].is_a?(Array)
312
351
  @_raw_data['photo'] = @_raw_data['photo'].map do |p|
313
- p.is_a?(BaseType) ? p : BaseType.new(p)
352
+ p.is_a?(PhotoSize) ? p : PhotoSize.new(p)
314
353
  end
315
354
  end
316
-
355
+
317
356
  # Contact, location, venue
318
- @_raw_data['contact'] = BaseType.new(@_raw_data['contact']) if @_raw_data['contact'] && !@_raw_data['contact'].is_a?(BaseType)
319
- @_raw_data['location'] = BaseType.new(@_raw_data['location']) if @_raw_data['location'] && !@_raw_data['location'].is_a?(BaseType)
320
- @_raw_data['venue'] = BaseType.new(@_raw_data['venue']) if @_raw_data['venue'] && !@_raw_data['venue'].is_a?(BaseType)
321
-
357
+ @_raw_data['contact'] = Contact.new(@_raw_data['contact']) if @_raw_data['contact'] && !@_raw_data['contact'].is_a?(Contact)
358
+ @_raw_data['location'] = Location.new(@_raw_data['location']) if @_raw_data['location'] && !@_raw_data['location'].is_a?(Location)
359
+ @_raw_data['venue'] = Venue.new(@_raw_data['venue']) if @_raw_data['venue'] && !@_raw_data['venue'].is_a?(Venue)
360
+
322
361
  # Payment & other
323
- @_raw_data['invoice'] = BaseType.new(@_raw_data['invoice']) if @_raw_data['invoice'] && !@_raw_data['invoice'].is_a?(BaseType)
324
- @_raw_data['successful_payment'] = BaseType.new(@_raw_data['successful_payment']) if @_raw_data['successful_payment'] && !@_raw_data['successful_payment'].is_a?(BaseType)
362
+ @_raw_data['invoice'] = Invoice.new(@_raw_data['invoice']) if @_raw_data['invoice'] && !@_raw_data['invoice'].is_a?(Invoice)
363
+ @_raw_data['successful_payment'] = SuccessfulPayment.new(@_raw_data['successful_payment']) if @_raw_data['successful_payment'] && !@_raw_data['successful_payment'].is_a?(SuccessfulPayment)
325
364
  @_raw_data['reply_markup'] = BaseType.new(@_raw_data['reply_markup']) if @_raw_data['reply_markup'] && !@_raw_data['reply_markup'].is_a?(BaseType)
326
-
365
+
327
366
  # Chat photo array
328
367
  if @_raw_data['new_chat_photo'] && @_raw_data['new_chat_photo'].is_a?(Array)
329
368
  @_raw_data['new_chat_photo'] = @_raw_data['new_chat_photo'].map do |p|
330
- p.is_a?(BaseType) ? p : BaseType.new(p)
369
+ p.is_a?(PhotoSize) ? p : PhotoSize.new(p)
331
370
  end
332
371
  end
333
372
  end
334
373
  end
335
-
374
+
336
375
  class CallbackQuery < BaseType
337
376
  COMMON_FIELDS = %w[id from message inline_message_id chat_instance data game_short_name].freeze
338
-
377
+
339
378
  def initialize(data)
340
379
  super(data)
341
-
380
+
342
381
  COMMON_FIELDS.each do |field|
343
382
  define_accessor(field.to_sym)
344
383
  end
345
-
384
+
346
385
  if @_raw_data['from'] && !@_raw_data['from'].is_a?(User)
347
386
  @_raw_data['from'] = User.new(@_raw_data['from'])
348
387
  end
349
-
388
+
350
389
  if @_raw_data['message'] && !@_raw_data['message'].is_a?(Message)
351
390
  @_raw_data['message'] = Message.new(@_raw_data['message'])
352
391
  end
353
392
  end
354
-
393
+
355
394
  def from_user?
356
395
  !!from
357
396
  end
358
-
397
+
359
398
  def message?
360
399
  !!message
361
400
  end
362
-
401
+
363
402
  def inline_message?
364
403
  !!inline_message_id
365
404
  end
366
405
  end
367
-
406
+
368
407
  class Update < BaseType
369
- COMMON_FIELDS = %w[update_id message edited_message channel_post
370
- edited_channel_post inline_query chosen_inline_result
371
- callback_query shipping_query pre_checkout_query
372
- poll poll_answer my_chat_member chat_member
373
- chat_join_request].freeze
374
-
408
+ COMMON_FIELDS = %w[update_id message edited_message channel_post
409
+ edited_channel_post inline_query chosen_inline_result
410
+ callback_query shipping_query pre_checkout_query
411
+ poll poll_answer my_chat_member chat_member
412
+ chat_join_request managed_bot_created managed_bot].freeze
413
+
375
414
  def initialize(data)
376
415
  super(data)
377
-
416
+
378
417
  COMMON_FIELDS.each do |field|
379
418
  define_accessor(field.to_sym)
380
419
  end
381
-
420
+
382
421
  convert_update_objects
383
422
  end
384
-
423
+
385
424
  def type
386
425
  return :message if message
387
426
  return :edited_message if edited_message
@@ -397,9 +436,11 @@ module Telegem
397
436
  return :my_chat_member if my_chat_member
398
437
  return :chat_member if chat_member
399
438
  return :chat_join_request if chat_join_request
439
+ return :managed_bot_created if managed_bot_created
440
+ return :managed_bot if managed_bot
400
441
  :unknown
401
442
  end
402
-
443
+
403
444
  def from
404
445
  case type
405
446
  when :message, :edited_message
@@ -420,23 +461,243 @@ module Telegem
420
461
  my_chat_member&.from || chat_member&.from
421
462
  when :chat_join_request
422
463
  chat_join_request.from
464
+ when :managed_bot_created, :managed_bot
465
+ managed_bot_created&.from || managed_bot&.from
423
466
  else
424
467
  nil
425
468
  end
426
469
  end
427
-
470
+
428
471
  private
429
-
472
+
430
473
  def convert_update_objects
431
- @_raw_data['message'] = Message.new(@_raw_data['message']) if @_raw_data['message'] && !@_raw_data['message'].is_a?(Message)
432
- @_raw_data['edited_message'] = Message.new(@_raw_data['edited_message']) if @_raw_data['edited_message'] && !@_raw_data['edited_message'].is_a?(Message)
433
- @_raw_data['channel_post'] = Message.new(@_raw_data['channel_post']) if @_raw_data['channel_post'] && !@_raw_data['channel_post'].is_a?(Message)
434
- @_raw_data['edited_channel_post'] = Message.new(@_raw_data['edited_channel_post']) if @_raw_data['edited_channel_post'] && !@_raw_data['edited_channel_post'].is_a?(Message)
435
-
436
- if @_raw_data['callback_query'] && !@_raw_data['callback_query'].is_a?(CallbackQuery)
437
- @_raw_data['callback_query'] = CallbackQuery.new(@_raw_data['callback_query'])
474
+ wrap('message', Message)
475
+ wrap('edited_message', Message)
476
+ wrap('channel_post', Message)
477
+ wrap('edited_channel_post', Message)
478
+
479
+ wrap('inline_query', InlineQuery)
480
+ wrap('chosen_inline_result', ChosenInlineResult)
481
+ wrap('callback_query', CallbackQuery)
482
+ wrap('shipping_query', ShippingQuery)
483
+ wrap('pre_checkout_query', PreCheckoutQuery)
484
+ wrap('poll', Poll)
485
+ wrap('poll_answer', PollAnswer)
486
+ wrap('my_chat_member', ChatMemberUpdated)
487
+ wrap('chat_member', ChatMemberUpdated)
488
+ wrap('chat_join_request', ChatJoinRequest)
489
+ wrap('forum_topic_created', ForumTopicCreated)
490
+ wrap('forum_topic_edited', ForumTopicEdited)
491
+ wrap('forum_topic_closed', ForumTopicClosed)
492
+ wrap('forum_topic_reopened', ForumTopicReopened)
493
+ wrap('general_forum_topic_hidden', GeneralForumTopicHidden)
494
+ wrap('general_forum_topic_unhidden', GeneralForumTopicUnhidden)
495
+ wrap('write_access_allowed', WriteAccessAllowed)
496
+
497
+ # Bot API 9.6 - Managed Bot Support
498
+ wrap('managed_bot_created', ManagedBotCreated)
499
+ wrap('managed_bot', ManagedBotUpdated)
500
+ end
501
+ end
502
+
503
+ # additional types returned by various methods / updates
504
+ class PhotoSize < BaseType; end
505
+ class Audio < BaseType; end
506
+ class Document < BaseType; end
507
+ class Video < BaseType; end
508
+ class Voice < BaseType; end
509
+ class VideoNote < BaseType; end
510
+ class Animation < BaseType; end
511
+ class Sticker < BaseType; end
512
+ class Contact < BaseType; end
513
+ class Dice < BaseType; end
514
+
515
+ class Location < BaseType; end
516
+ class Venue < BaseType; end
517
+ class ProximityAlertTriggered < BaseType; end
518
+ class WebAppData < BaseType; end
519
+ class PassportData < BaseType; end
520
+
521
+ class Invoice < BaseType; end
522
+ class SuccessfulPayment < BaseType; end
523
+ class ShippingAddress < BaseType; end
524
+ class OrderInfo < BaseType; end
525
+
526
+ class ShippingQuery < BaseType
527
+ def initialize(data)
528
+ super(data)
529
+ wrap('from', User)
530
+ wrap('shipping_address', ShippingAddress)
531
+ end
532
+ end
533
+
534
+ class PreCheckoutQuery < BaseType
535
+ def initialize(data)
536
+ super(data)
537
+ wrap('from', User)
538
+ wrap('shipping_address', ShippingAddress)
539
+ wrap('order_info', OrderInfo)
540
+ end
541
+ end
542
+
543
+ class PollOption < BaseType
544
+ def initialize(data)
545
+ super(data)
546
+ # Bot API 9.6 enhancements
547
+ wrap('added_by_user', User)
548
+ wrap('added_by_chat', Chat)
549
+ end
550
+ end
551
+
552
+ class PollAnswer < BaseType; end
553
+
554
+ class Poll < BaseType
555
+ def initialize(data)
556
+ super(data)
557
+ wrap_array('options', PollOption)
558
+ wrap_array('explanation_entities', MessageEntity)
559
+ end
560
+ end
561
+
562
+ class ChatPermissions < BaseType; end
563
+ class ChatPhoto < BaseType; end
564
+ class ChatInviteLink < BaseType; end
565
+
566
+ # status-specific chat member objects. they inherit from ChatMember
567
+ class ChatMember < BaseType; end
568
+ class ChatMemberOwner < ChatMember; end
569
+ class ChatMemberAdministrator < ChatMember; end
570
+ class ChatMemberMember < ChatMember; end
571
+ class ChatMemberRestricted < ChatMember; end
572
+ class ChatMemberLeft < ChatMember; end
573
+ class ChatMemberBanned < ChatMember; end
574
+
575
+ class ChatAdministratorRights < BaseType; end
576
+
577
+ class ChatMemberUpdated < BaseType
578
+ def initialize(data)
579
+ super(data)
580
+ wrap('chat', Chat)
581
+ wrap('from', User)
582
+ wrap_member('old_chat_member')
583
+ wrap_member('new_chat_member')
584
+ wrap('invite_link', ChatInviteLink)
585
+ if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
586
+ @_raw_data['date'] = Time.at(@_raw_data['date'])
438
587
  end
439
588
  end
589
+
590
+ private
591
+
592
+ def wrap_member(key)
593
+ return unless @_raw_data[key]
594
+ status = @_raw_data[key]['status']
595
+ klass = case status
596
+ when 'creator' then ChatMemberOwner
597
+ when 'administrator' then ChatMemberAdministrator
598
+ when 'member' then ChatMemberMember
599
+ when 'restricted' then ChatMemberRestricted
600
+ when 'left' then ChatMemberLeft
601
+ when 'kicked' then ChatMemberBanned
602
+ else ChatMember
603
+ end
604
+ @_raw_data[key] = klass.new(@_raw_data[key])
605
+ end
606
+ end
607
+
608
+ class ChatJoinRequest < BaseType
609
+ def initialize(data)
610
+ super(data)
611
+ wrap('chat', Chat)
612
+ wrap('from', User)
613
+ wrap('invite_link', ChatInviteLink)
614
+ if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
615
+ @_raw_data['date'] = Time.at(@_raw_data['date'])
616
+ end
617
+ end
618
+ end
619
+
620
+ class InlineQuery < BaseType
621
+ def initialize(data)
622
+ super(data)
623
+ wrap('from', User)
624
+ wrap('location', Location)
625
+ end
626
+ end
627
+
628
+ class ChosenInlineResult < BaseType
629
+ def initialize(data)
630
+ super(data)
631
+ wrap('from', User)
632
+ wrap('location', Location)
633
+ end
634
+ end
635
+
636
+ class InlineQueryResult < BaseType; end
637
+ class InlineQueryResultArticle < InlineQueryResult; end
638
+ class InlineQueryResultPhoto < InlineQueryResult; end
639
+ class InlineQueryResultGif < InlineQueryResult; end
640
+ class InlineQueryResultMpeg4Gif < InlineQueryResult; end
641
+ class InlineQueryResultVideo < InlineQueryResult; end
642
+ class InlineQueryResultAudio < InlineQueryResult; end
643
+ class InlineQueryResultVoice < InlineQueryResult; end
644
+ class InlineQueryResultDocument < InlineQueryResult; end
645
+ class InlineQueryResultLocation < InlineQueryResult; end
646
+ class InlineQueryResultVenue < InlineQueryResult; end
647
+ class InlineQueryResultContact < InlineQueryResult; end
648
+ class InlineQueryResultGame < InlineQueryResult; end
649
+ class InlineQueryResultSticker < InlineQueryResult; end
650
+ class InlineQueryResultCachedPhoto < InlineQueryResult; end
651
+ class InlineQueryResultCachedGif < InlineQueryResult; end
652
+ class InlineQueryResultCachedMpeg4Gif < InlineQueryResult; end
653
+ class InlineQueryResultCachedSticker < InlineQueryResult; end
654
+ class InlineQueryResultCachedDocument < InlineQueryResult; end
655
+ class InlineQueryResultCachedVideo < InlineQueryResult; end
656
+ class InlineQueryResultCachedAudio < InlineQueryResult; end
657
+ class InlineQueryResultCachedVoice < InlineQueryResult; end
658
+
659
+ class UserProfilePhotos < BaseType
660
+ def initialize(data)
661
+ super(data)
662
+ wrap_array('photos', PhotoSize)
663
+ end
664
+ end
665
+
666
+ class UserProfileAudios < BaseType
667
+ def initialize(data)
668
+ super(data)
669
+ wrap_array('audios', Audio)
670
+ end
671
+ end
672
+
673
+ # generic utility objects returned by the API
674
+ class File < BaseType; end
675
+ class ResponseParameters < BaseType; end
676
+ class MaskPosition < BaseType; end
677
+ class StickerSet < BaseType; end
678
+
679
+ # new message event payloads (each a simple wrapper)
680
+ class MessageAutoDeleteTimerChanged < BaseType; end
681
+ class ForumTopicCreated < BaseType; end
682
+ class ForumTopicEdited < BaseType; end
683
+ class ForumTopicClosed < BaseType; end
684
+ class ForumTopicReopened < BaseType; end
685
+ class GeneralForumTopicHidden < BaseType; end
686
+ class GeneralForumTopicUnhidden < BaseType; end
687
+ class WriteAccessAllowed < BaseType; end
688
+
689
+ class BotCommand < BaseType; end
690
+ class BotCommandScope < BaseType; end
691
+ class WebhookInfo < BaseType; end
692
+
693
+ class VideoChatScheduled < BaseType; end
694
+ class VideoChatStarted < BaseType; end
695
+ class VideoChatEnded < BaseType; end
696
+ class VideoChatParticipantsInvited < BaseType; end
697
+ class VideoChatLocation < BaseType; end
698
+ # Bot API 9.6 - Managed Bot Support
699
+ class ManagedBotCreated < BaseType; end
700
+ class ManagedBotDeleted < BaseType; end
701
+ class ManagedBotUpdated < BaseType; end
440
702
  end
441
703
  end
442
- end