telegem 3.3.1 → 3.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 +57 -0
- data/CHANGELOG.md +45 -1
- data/README.md +148 -0
- data/bin/telegem-ssl +71 -25
- data/contributing.md +375 -0
- data/docs/api.md +663 -0
- data/docs/bot.md +332 -0
- data/docs/changelog.md +182 -0
- data/docs/context.md +554 -0
- data/docs/core_concepts.md +218 -0
- data/docs/deployment.md +702 -0
- data/docs/error_handling.md +435 -0
- data/docs/examples.md +752 -0
- data/docs/getting_started.md +151 -0
- data/docs/handlers.md +580 -0
- data/docs/keyboards.md +446 -0
- data/docs/middleware.md +536 -0
- data/docs/plugins.md +384 -0
- data/docs/scenes.md +517 -0
- data/docs/sessions.md +544 -0
- data/docs/testing.md +612 -0
- data/docs/troubleshooting.md +574 -0
- data/docs/types.md +538 -0
- data/docs/webhooks.md +456 -0
- data/lib/api/client.rb +38 -10
- data/lib/api/types.rb +184 -107
- data/lib/core/composer.rb +3 -3
- data/lib/core/context.rb +17 -11
- data/lib/core/rate_limit.rb +6 -3
- data/lib/plugins/cc +3 -0
- data/lib/plugins/translate.rb +43 -0
- data/lib/session/redis.rb +91 -0
- data/lib/telegem.rb +3 -3
- data/lib/webhook/server.rb +5 -3
- metadata +45 -33
- data/Contributing.md +0 -161
- data/Readme.md +0 -298
- data/bin/telegem-init +0 -32
- data/examples/.gitkeep +0 -0
- data/public/.gitkeep +0 -0
data/lib/api/types.rb
CHANGED
|
@@ -5,70 +5,70 @@ 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
65
|
# helpers for converting nested objects
|
|
66
66
|
def wrap(key, klass)
|
|
67
67
|
if @_raw_data[key] && !@_raw_data[key].is_a?(klass)
|
|
68
68
|
@_raw_data[key] = klass.new(@_raw_data[key])
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
def wrap_array(key, klass)
|
|
73
73
|
if @_raw_data[key] && @_raw_data[key].is_a?(Array)
|
|
74
74
|
@_raw_data[key] = @_raw_data[key].map do |v|
|
|
@@ -76,35 +76,36 @@ module Telegem
|
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
def snake_to_camel(str)
|
|
81
81
|
str.gsub(/_([a-z])/) { $1.upcase }
|
|
82
82
|
end
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
def camel_to_snake(str)
|
|
85
85
|
str.gsub(/([A-Z])/) { "_#{$1.downcase}" }.sub(/^_/, '')
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
class User < BaseType
|
|
90
90
|
COMMON_FIELDS = %w[id is_bot first_name last_name username
|
|
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
|
|
95
|
-
|
|
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
|
|
95
|
+
supports_guest_queries].freeze
|
|
96
|
+
|
|
96
97
|
def initialize(data)
|
|
97
98
|
super(data)
|
|
98
|
-
|
|
99
|
+
|
|
99
100
|
COMMON_FIELDS.each do |field|
|
|
100
101
|
define_accessor(field.to_sym)
|
|
101
102
|
end
|
|
102
103
|
end
|
|
103
|
-
|
|
104
|
+
|
|
104
105
|
def full_name
|
|
105
106
|
[first_name, last_name].compact.join(' ')
|
|
106
107
|
end
|
|
107
|
-
|
|
108
|
+
|
|
108
109
|
def mention
|
|
109
110
|
if username
|
|
110
111
|
"@#{username}"
|
|
@@ -114,127 +115,129 @@ module Telegem
|
|
|
114
115
|
"User ##{id}"
|
|
115
116
|
end
|
|
116
117
|
end
|
|
117
|
-
|
|
118
|
+
|
|
118
119
|
def to_s
|
|
119
120
|
full_name
|
|
120
121
|
end
|
|
121
122
|
end
|
|
122
|
-
|
|
123
|
+
|
|
123
124
|
class Chat < BaseType
|
|
124
125
|
COMMON_FIELDS = %w[id type username title first_name last_name
|
|
125
|
-
photo bio has_private_forwards
|
|
126
|
+
photo bio has_private_forwards
|
|
126
127
|
has_restricted_voice_and_video_messages
|
|
127
|
-
description invite_link pinned_message
|
|
128
|
+
description invite_link pinned_message
|
|
128
129
|
permissions slow_mode_delay message_auto_delete_time
|
|
129
|
-
has_protected_content sticker_set_name
|
|
130
|
+
has_protected_content sticker_set_name
|
|
130
131
|
can_set_sticker_set linked_chat_id location].freeze
|
|
131
|
-
|
|
132
|
+
|
|
132
133
|
def initialize(data)
|
|
133
134
|
super(data)
|
|
134
|
-
|
|
135
|
+
|
|
135
136
|
COMMON_FIELDS.each do |field|
|
|
136
137
|
define_accessor(field.to_sym)
|
|
137
138
|
end
|
|
138
139
|
end
|
|
139
|
-
|
|
140
|
+
|
|
140
141
|
def private?
|
|
141
142
|
type == 'private'
|
|
142
143
|
end
|
|
143
|
-
|
|
144
|
+
|
|
144
145
|
def group?
|
|
145
146
|
type == 'group'
|
|
146
147
|
end
|
|
147
|
-
|
|
148
|
+
|
|
148
149
|
def supergroup?
|
|
149
150
|
type == 'supergroup'
|
|
150
151
|
end
|
|
151
|
-
|
|
152
|
+
|
|
152
153
|
def channel?
|
|
153
154
|
type == 'channel'
|
|
154
155
|
end
|
|
155
|
-
|
|
156
|
+
|
|
156
157
|
def to_s
|
|
157
158
|
title || username || "Chat ##{id}"
|
|
158
159
|
end
|
|
159
160
|
end
|
|
160
|
-
|
|
161
|
+
|
|
161
162
|
class MessageEntity < BaseType
|
|
162
163
|
COMMON_FIELDS = %w[type offset length url user language
|
|
163
164
|
custom_emoji_id].freeze
|
|
164
|
-
|
|
165
|
+
|
|
165
166
|
def initialize(data)
|
|
166
167
|
super(data)
|
|
167
|
-
|
|
168
|
+
|
|
168
169
|
COMMON_FIELDS.each do |field|
|
|
169
170
|
define_accessor(field.to_sym)
|
|
170
171
|
end
|
|
171
|
-
|
|
172
|
+
|
|
172
173
|
if @_raw_data['user'] && !@_raw_data['user'].is_a?(User)
|
|
173
174
|
@_raw_data['user'] = User.new(@_raw_data['user'])
|
|
174
175
|
end
|
|
175
176
|
end
|
|
176
177
|
end
|
|
177
|
-
|
|
178
|
+
|
|
178
179
|
class Message < BaseType
|
|
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
|
|
195
|
-
|
|
180
|
+
COMMON_FIELDS = %w[message_id from chat date edit_date
|
|
181
|
+
text caption entities caption_entities
|
|
182
|
+
audio document photo sticker video voice
|
|
183
|
+
video_note contact location venue
|
|
184
|
+
new_chat_members left_chat_member
|
|
185
|
+
new_chat_title new_chat_photo
|
|
186
|
+
delete_chat_photo group_chat_created
|
|
187
|
+
supergroup_chat_created channel_chat_created
|
|
188
|
+
migrate_to_chat_id migrate_from_chat_id
|
|
189
|
+
pinned_message invoice successful_payment
|
|
190
|
+
connected_website reply_markup via_bot
|
|
191
|
+
forward_from forward_from_chat
|
|
192
|
+
forward_from_message_id forward_signature
|
|
193
|
+
forward_sender_name forward_date reply_to_message
|
|
194
|
+
media_group_id author_signature
|
|
195
|
+
has_protected_content managed_bot_created managed_bot
|
|
196
|
+
guest_bot_caller_user guest_bot_caller_chat
|
|
197
|
+
guest_query_id live_photo].freeze
|
|
198
|
+
|
|
196
199
|
def initialize(data)
|
|
197
200
|
super(data)
|
|
198
|
-
|
|
201
|
+
|
|
199
202
|
COMMON_FIELDS.each do |field|
|
|
200
203
|
define_accessor(field.to_sym)
|
|
201
204
|
end
|
|
202
|
-
|
|
205
|
+
|
|
203
206
|
convert_complex_fields
|
|
204
207
|
end
|
|
205
|
-
|
|
208
|
+
|
|
206
209
|
def command?
|
|
207
210
|
return false unless text && entities
|
|
208
|
-
|
|
209
|
-
entities.any? { |e| e.type == 'bot_command' &&
|
|
211
|
+
|
|
212
|
+
entities.any? { |e| e.type == 'bot_command' &&
|
|
210
213
|
text[e.offset, e.length]&.start_with?('/') }
|
|
211
214
|
end
|
|
212
|
-
|
|
215
|
+
|
|
213
216
|
def command_name
|
|
214
217
|
return nil unless command?
|
|
215
|
-
|
|
218
|
+
|
|
216
219
|
command_entity = entities.find { |e| e.type == 'bot_command' }
|
|
217
220
|
return nil unless command_entity
|
|
218
|
-
|
|
221
|
+
|
|
219
222
|
cmd = text[command_entity.offset, command_entity.length]
|
|
220
223
|
return nil if cmd.nil? || cmd.length <= 1
|
|
221
|
-
|
|
224
|
+
|
|
222
225
|
cmd = cmd[1..-1]
|
|
223
226
|
cmd.split('@').first.strip
|
|
224
227
|
end
|
|
225
|
-
|
|
228
|
+
|
|
226
229
|
def command_args
|
|
227
230
|
return nil unless command?
|
|
228
|
-
|
|
231
|
+
|
|
229
232
|
command_entity = entities.find { |e| e.type == 'bot_command' }
|
|
230
233
|
return nil unless command_entity
|
|
231
|
-
|
|
234
|
+
|
|
232
235
|
args_start = command_entity.offset + command_entity.length
|
|
233
236
|
remaining = text[args_start..-1]
|
|
234
|
-
|
|
237
|
+
|
|
235
238
|
next_entity = entities.select { |e| e.offset >= args_start }
|
|
236
239
|
.min_by(&:offset)
|
|
237
|
-
|
|
240
|
+
|
|
238
241
|
if next_entity
|
|
239
242
|
args_end = next_entity.offset - 1
|
|
240
243
|
text[args_start..args_end]&.strip
|
|
@@ -242,15 +245,15 @@ module Telegem
|
|
|
242
245
|
remaining&.strip
|
|
243
246
|
end
|
|
244
247
|
end
|
|
245
|
-
|
|
248
|
+
|
|
246
249
|
def reply?
|
|
247
250
|
!!reply_to_message
|
|
248
251
|
end
|
|
249
|
-
|
|
252
|
+
|
|
250
253
|
def has_media?
|
|
251
254
|
!!(audio || document || photo || video || voice || video_note || sticker)
|
|
252
255
|
end
|
|
253
|
-
|
|
256
|
+
|
|
254
257
|
def media_type
|
|
255
258
|
return :audio if audio
|
|
256
259
|
return :document if document
|
|
@@ -261,9 +264,9 @@ module Telegem
|
|
|
261
264
|
return :sticker if sticker
|
|
262
265
|
nil
|
|
263
266
|
end
|
|
264
|
-
|
|
267
|
+
|
|
265
268
|
private
|
|
266
|
-
|
|
269
|
+
|
|
267
270
|
def convert_complex_fields
|
|
268
271
|
# time conversions
|
|
269
272
|
@_raw_data['date'] = Time.at(@_raw_data['date']) if @_raw_data['date'] && !@_raw_data['date'].is_a?(Time)
|
|
@@ -301,6 +304,10 @@ module Telegem
|
|
|
301
304
|
wrap('voice', Voice)
|
|
302
305
|
wrap('video_note', VideoNote)
|
|
303
306
|
wrap('sticker', Sticker)
|
|
307
|
+
wrap('live_photo', LivePhoto)
|
|
308
|
+
|
|
309
|
+
wrap('guest_bot_caller_user', User)
|
|
310
|
+
wrap('guest_bot_caller_chat', Chat)
|
|
304
311
|
|
|
305
312
|
wrap('invoice', Invoice)
|
|
306
313
|
wrap('successful_payment', SuccessfulPayment)
|
|
@@ -324,6 +331,10 @@ module Telegem
|
|
|
324
331
|
wrap('general_forum_topic_unhidden', GeneralForumTopicUnhidden)
|
|
325
332
|
wrap('write_access_allowed', WriteAccessAllowed)
|
|
326
333
|
|
|
334
|
+
# Bot API 9.6 - Managed Bot Support
|
|
335
|
+
wrap('managed_bot_created', ManagedBotCreated)
|
|
336
|
+
wrap('managed_bot', ManagedBotUpdated)
|
|
337
|
+
|
|
327
338
|
# arrays of sizes and photos
|
|
328
339
|
wrap_array('photo', PhotoSize)
|
|
329
340
|
wrap_array('new_chat_photo', PhotoSize)
|
|
@@ -331,7 +342,7 @@ module Telegem
|
|
|
331
342
|
# fall back to original media wrapper for backward compatibility
|
|
332
343
|
wrap_media_objects
|
|
333
344
|
end
|
|
334
|
-
|
|
345
|
+
|
|
335
346
|
def wrap_media_objects
|
|
336
347
|
# Media files (fall‑back to generic types if no specific class defined)
|
|
337
348
|
@_raw_data['document'] = Document.new(@_raw_data['document']) if @_raw_data['document'] && !@_raw_data['document'].is_a?(Document)
|
|
@@ -367,56 +378,57 @@ module Telegem
|
|
|
367
378
|
end
|
|
368
379
|
end
|
|
369
380
|
end
|
|
370
|
-
|
|
381
|
+
|
|
371
382
|
class CallbackQuery < BaseType
|
|
372
383
|
COMMON_FIELDS = %w[id from message inline_message_id chat_instance data game_short_name].freeze
|
|
373
|
-
|
|
384
|
+
|
|
374
385
|
def initialize(data)
|
|
375
386
|
super(data)
|
|
376
|
-
|
|
387
|
+
|
|
377
388
|
COMMON_FIELDS.each do |field|
|
|
378
389
|
define_accessor(field.to_sym)
|
|
379
390
|
end
|
|
380
|
-
|
|
391
|
+
|
|
381
392
|
if @_raw_data['from'] && !@_raw_data['from'].is_a?(User)
|
|
382
393
|
@_raw_data['from'] = User.new(@_raw_data['from'])
|
|
383
394
|
end
|
|
384
|
-
|
|
395
|
+
|
|
385
396
|
if @_raw_data['message'] && !@_raw_data['message'].is_a?(Message)
|
|
386
397
|
@_raw_data['message'] = Message.new(@_raw_data['message'])
|
|
387
398
|
end
|
|
388
399
|
end
|
|
389
|
-
|
|
400
|
+
|
|
390
401
|
def from_user?
|
|
391
402
|
!!from
|
|
392
403
|
end
|
|
393
|
-
|
|
404
|
+
|
|
394
405
|
def message?
|
|
395
406
|
!!message
|
|
396
407
|
end
|
|
397
|
-
|
|
408
|
+
|
|
398
409
|
def inline_message?
|
|
399
410
|
!!inline_message_id
|
|
400
411
|
end
|
|
401
412
|
end
|
|
402
|
-
|
|
413
|
+
|
|
403
414
|
class Update < BaseType
|
|
404
|
-
COMMON_FIELDS = %w[update_id message edited_message channel_post
|
|
405
|
-
edited_channel_post inline_query chosen_inline_result
|
|
406
|
-
callback_query shipping_query pre_checkout_query
|
|
407
|
-
poll poll_answer my_chat_member chat_member
|
|
408
|
-
chat_join_request
|
|
409
|
-
|
|
415
|
+
COMMON_FIELDS = %w[update_id message edited_message channel_post
|
|
416
|
+
edited_channel_post inline_query chosen_inline_result
|
|
417
|
+
callback_query shipping_query pre_checkout_query
|
|
418
|
+
poll poll_answer my_chat_member chat_member
|
|
419
|
+
chat_join_request managed_bot_created managed_bot
|
|
420
|
+
guest_message].freeze
|
|
421
|
+
|
|
410
422
|
def initialize(data)
|
|
411
423
|
super(data)
|
|
412
|
-
|
|
424
|
+
|
|
413
425
|
COMMON_FIELDS.each do |field|
|
|
414
426
|
define_accessor(field.to_sym)
|
|
415
427
|
end
|
|
416
|
-
|
|
428
|
+
|
|
417
429
|
convert_update_objects
|
|
418
430
|
end
|
|
419
|
-
|
|
431
|
+
|
|
420
432
|
def type
|
|
421
433
|
return :message if message
|
|
422
434
|
return :edited_message if edited_message
|
|
@@ -432,9 +444,12 @@ module Telegem
|
|
|
432
444
|
return :my_chat_member if my_chat_member
|
|
433
445
|
return :chat_member if chat_member
|
|
434
446
|
return :chat_join_request if chat_join_request
|
|
447
|
+
return :managed_bot_created if managed_bot_created
|
|
448
|
+
return :managed_bot if managed_bot
|
|
449
|
+
return :guest_message if guest_message
|
|
435
450
|
:unknown
|
|
436
451
|
end
|
|
437
|
-
|
|
452
|
+
|
|
438
453
|
def from
|
|
439
454
|
case type
|
|
440
455
|
when :message, :edited_message
|
|
@@ -455,13 +470,17 @@ module Telegem
|
|
|
455
470
|
my_chat_member&.from || chat_member&.from
|
|
456
471
|
when :chat_join_request
|
|
457
472
|
chat_join_request.from
|
|
473
|
+
when :managed_bot_created, :managed_bot
|
|
474
|
+
managed_bot_created&.from || managed_bot&.from
|
|
475
|
+
when :guest_message
|
|
476
|
+
guest_message.from
|
|
458
477
|
else
|
|
459
478
|
nil
|
|
460
479
|
end
|
|
461
480
|
end
|
|
462
|
-
|
|
481
|
+
|
|
463
482
|
private
|
|
464
|
-
|
|
483
|
+
|
|
465
484
|
def convert_update_objects
|
|
466
485
|
wrap('message', Message)
|
|
467
486
|
wrap('edited_message', Message)
|
|
@@ -485,6 +504,12 @@ module Telegem
|
|
|
485
504
|
wrap('general_forum_topic_hidden', GeneralForumTopicHidden)
|
|
486
505
|
wrap('general_forum_topic_unhidden', GeneralForumTopicUnhidden)
|
|
487
506
|
wrap('write_access_allowed', WriteAccessAllowed)
|
|
507
|
+
|
|
508
|
+
# Bot API 9.6 - Managed Bot Support
|
|
509
|
+
wrap('managed_bot_created', ManagedBotCreated)
|
|
510
|
+
wrap('managed_bot', ManagedBotUpdated)
|
|
511
|
+
# Bot API 10.0 - Guest Message Support
|
|
512
|
+
wrap('guest_message', SentGuestMessage)
|
|
488
513
|
end
|
|
489
514
|
end
|
|
490
515
|
|
|
@@ -528,7 +553,17 @@ module Telegem
|
|
|
528
553
|
end
|
|
529
554
|
end
|
|
530
555
|
|
|
531
|
-
class PollOption < BaseType
|
|
556
|
+
class PollOption < BaseType
|
|
557
|
+
def initialize(data)
|
|
558
|
+
super(data)
|
|
559
|
+
# Bot API 9.6 enhancements
|
|
560
|
+
wrap('added_by_user', User)
|
|
561
|
+
wrap('added_by_chat', Chat)
|
|
562
|
+
# Bot API 10.0 - media support
|
|
563
|
+
wrap('media', InputPollOptionMedia)
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
|
|
532
567
|
class PollAnswer < BaseType; end
|
|
533
568
|
|
|
534
569
|
class Poll < BaseType
|
|
@@ -536,10 +571,19 @@ module Telegem
|
|
|
536
571
|
super(data)
|
|
537
572
|
wrap_array('options', PollOption)
|
|
538
573
|
wrap_array('explanation_entities', MessageEntity)
|
|
574
|
+
# Bot API 10.0 - poll media support
|
|
575
|
+
wrap('media', PollMedia)
|
|
576
|
+
wrap('explanation_media', PollMedia)
|
|
539
577
|
end
|
|
540
578
|
end
|
|
541
579
|
|
|
542
|
-
class ChatPermissions < BaseType
|
|
580
|
+
class ChatPermissions < BaseType
|
|
581
|
+
def initialize(data)
|
|
582
|
+
super(data)
|
|
583
|
+
# Bot API 10.0 - reaction support
|
|
584
|
+
define_accessor(:can_react_to_messages)
|
|
585
|
+
end
|
|
586
|
+
end
|
|
543
587
|
class ChatPhoto < BaseType; end
|
|
544
588
|
class ChatInviteLink < BaseType; end
|
|
545
589
|
|
|
@@ -548,7 +592,13 @@ module Telegem
|
|
|
548
592
|
class ChatMemberOwner < ChatMember; end
|
|
549
593
|
class ChatMemberAdministrator < ChatMember; end
|
|
550
594
|
class ChatMemberMember < ChatMember; end
|
|
551
|
-
class ChatMemberRestricted < ChatMember
|
|
595
|
+
class ChatMemberRestricted < ChatMember
|
|
596
|
+
def initialize(data)
|
|
597
|
+
super(data)
|
|
598
|
+
# Bot API 10.0 - reaction support
|
|
599
|
+
define_accessor(:can_react_to_messages)
|
|
600
|
+
end
|
|
601
|
+
end
|
|
552
602
|
class ChatMemberLeft < ChatMember; end
|
|
553
603
|
class ChatMemberBanned < ChatMember; end
|
|
554
604
|
|
|
@@ -675,6 +725,33 @@ module Telegem
|
|
|
675
725
|
class VideoChatEnded < BaseType; end
|
|
676
726
|
class VideoChatParticipantsInvited < BaseType; end
|
|
677
727
|
class VideoChatLocation < BaseType; end
|
|
728
|
+
# Bot API 9.6 - Managed Bot Support
|
|
729
|
+
class ManagedBotCreated < BaseType; end
|
|
730
|
+
class ManagedBotDeleted < BaseType; end
|
|
731
|
+
class ManagedBotUpdated < BaseType; end
|
|
732
|
+
|
|
733
|
+
# Bot API 10.0 - Guest Mode Support
|
|
734
|
+
class SentGuestMessage < BaseType; end
|
|
735
|
+
|
|
736
|
+
# Bot API 10.0 - Poll Media Support
|
|
737
|
+
class PollMedia < BaseType; end
|
|
738
|
+
class InputPollMedia < BaseType; end
|
|
739
|
+
class InputPollOptionMedia < BaseType; end
|
|
740
|
+
|
|
741
|
+
# Bot API 10.0 - Live Photo Support
|
|
742
|
+
class LivePhoto < BaseType
|
|
743
|
+
def initialize(data)
|
|
744
|
+
super(data)
|
|
745
|
+
wrap('photo', PhotoSize)
|
|
746
|
+
wrap('video', Video)
|
|
747
|
+
end
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
class InputMediaLivePhoto < BaseType; end
|
|
751
|
+
class PaidMediaLivePhoto < BaseType; end
|
|
752
|
+
class InputPaidMediaLivePhoto < BaseType; end
|
|
678
753
|
|
|
754
|
+
# Bot API 10.0 - Business Access Settings
|
|
755
|
+
class BotAccessSettings < BaseType; end
|
|
756
|
+
end
|
|
679
757
|
end
|
|
680
|
-
end
|
data/lib/core/composer.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# lib/core/composer.rb
|
|
1
|
+
# lib/core/composer.rb
|
|
2
2
|
module Telegem
|
|
3
3
|
module Core
|
|
4
4
|
class Composer
|
|
@@ -40,7 +40,7 @@ module Telegem
|
|
|
40
40
|
# Call the middleware with next in chain
|
|
41
41
|
middleware_instance.call(context, next_middleware)
|
|
42
42
|
else
|
|
43
|
-
raise "Invalid middleware: #{middleware.
|
|
43
|
+
raise "Invalid middleware: #{middleware.inspect} does not respond to :call"
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
end
|
|
@@ -58,4 +58,4 @@ module Telegem
|
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
|
-
end
|
|
61
|
+
end
|
data/lib/core/context.rb
CHANGED
|
@@ -436,16 +436,8 @@ module Telegem
|
|
|
436
436
|
scene&.next_step(self, step_name)
|
|
437
437
|
end
|
|
438
438
|
def with_typing(&block)
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
typing
|
|
442
|
-
sleep 5
|
|
443
|
-
end
|
|
444
|
-
end
|
|
445
|
-
result = block.call
|
|
446
|
-
@typing_active = false
|
|
447
|
-
thread.join
|
|
448
|
-
result
|
|
439
|
+
typing
|
|
440
|
+
block.call
|
|
449
441
|
end
|
|
450
442
|
|
|
451
443
|
def command?
|
|
@@ -463,6 +455,20 @@ module Telegem
|
|
|
463
455
|
scene.enter(self, options[:step], options.except(:step))
|
|
464
456
|
scene_name
|
|
465
457
|
end
|
|
458
|
+
|
|
459
|
+
# Essential 9.6 methods for context.rb
|
|
460
|
+
def business_connection_id
|
|
461
|
+
message&.business_connection_id || @update.business_connection_id
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
def reply_draft(text, **options)
|
|
465
|
+
return unless chat
|
|
466
|
+
@bot.api.call('sendMessageDraft', { chat_id: chat.id, text: text }.merge(options))
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
def managed_bot
|
|
470
|
+
@update.managed_bot
|
|
471
|
+
end
|
|
466
472
|
|
|
467
473
|
def logger
|
|
468
474
|
@bot.logger
|
|
@@ -488,4 +494,4 @@ module Telegem
|
|
|
488
494
|
end
|
|
489
495
|
end
|
|
490
496
|
end
|
|
491
|
-
end
|
|
497
|
+
end
|
data/lib/core/rate_limit.rb
CHANGED
|
@@ -63,7 +63,6 @@ module Telegem
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def increment_counters(ctx)
|
|
66
|
-
now = Time.now.to_i
|
|
67
66
|
if @options[:global]
|
|
68
67
|
key = "global"
|
|
69
68
|
@counters[:global].increment(key, 1, ttl: @options[:global][:per])
|
|
@@ -80,8 +79,12 @@ module Telegem
|
|
|
80
79
|
end
|
|
81
80
|
end
|
|
82
81
|
def rate_limit_response(ctx)
|
|
83
|
-
|
|
82
|
+
begin
|
|
83
|
+
ctx.reply("⏳ Please wait a moment before sending another request.")
|
|
84
|
+
rescue StandardError => e
|
|
85
|
+
ctx.logger&.warn("Failed to send rate limit response: #{e.class}: #{e.message}")
|
|
86
|
+
end
|
|
84
87
|
nil
|
|
85
88
|
end
|
|
86
89
|
end
|
|
87
|
-
end
|
|
90
|
+
end
|
data/lib/plugins/cc
ADDED