gruubY 0.2.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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +6 -0
  4. data/Rakefile +51 -0
  5. data/config/config.rb +5 -0
  6. data/example/bot.rb +160 -0
  7. data/example/generate_user_session.rb +81 -0
  8. data/example/ntgcalls.rb +80 -0
  9. data/example/tdlib.rb +77 -0
  10. data/example/userbot.rb +133 -0
  11. data/lib/grubY/api.rb +363 -0
  12. data/lib/grubY/async.rb +13 -0
  13. data/lib/grubY/bot.rb +90 -0
  14. data/lib/grubY/bound.rb +14 -0
  15. data/lib/grubY/client.rb +296 -0
  16. data/lib/grubY/context.rb +242 -0
  17. data/lib/grubY/dispatcher.rb +60 -0
  18. data/lib/grubY/enums.rb +62 -0
  19. data/lib/grubY/exception.rb +5 -0
  20. data/lib/grubY/file_stream.rb +17 -0
  21. data/lib/grubY/filters.rb +292 -0
  22. data/lib/grubY/group_manager.rb +213 -0
  23. data/lib/grubY/handlers.rb +170 -0
  24. data/lib/grubY/keyboard.rb +49 -0
  25. data/lib/grubY/media.rb +38 -0
  26. data/lib/grubY/middleware.rb +18 -0
  27. data/lib/grubY/ntgcalls/native.rb +100 -0
  28. data/lib/grubY/ntgcalls.rb +478 -0
  29. data/lib/grubY/plugin.rb +14 -0
  30. data/lib/grubY/raw.rb +25 -0
  31. data/lib/grubY/raw_types.rb +57 -0
  32. data/lib/grubY/retry.rb +14 -0
  33. data/lib/grubY/server.rb +18 -0
  34. data/lib/grubY/session.rb +30 -0
  35. data/lib/grubY/tdlib/client.rb +565 -0
  36. data/lib/grubY/tdlib/client_manager.rb +37 -0
  37. data/lib/grubY/tdlib/decorators.rb +17 -0
  38. data/lib/grubY/tdlib/errors.rb +6 -0
  39. data/lib/grubY/tdlib/group_manager.rb +58 -0
  40. data/lib/grubY/tdlib/native.rb +72 -0
  41. data/lib/grubY/tdlib/schema_builder.rb +237 -0
  42. data/lib/grubY/tdlib/tdjson.rb +49 -0
  43. data/lib/grubY/tdlib/user_session.rb +69 -0
  44. data/lib/grubY/types/base_object.rb +72 -0
  45. data/lib/grubY/types/bound_entities.rb +245 -0
  46. data/lib/grubY/types/chat.rb +93 -0
  47. data/lib/grubY/types/chat_info.rb +31 -0
  48. data/lib/grubY/types/extra.rb +251 -0
  49. data/lib/grubY/types/message.rb +295 -0
  50. data/lib/grubY/types/message_entity.rb +14 -0
  51. data/lib/grubY/types/registry.rb +67 -0
  52. data/lib/grubY/types/user.rb +31 -0
  53. data/lib/grubY/webapp.rb +22 -0
  54. data/lib/grubY.rb +41 -0
  55. data/plugins/logger.rb +7 -0
  56. data/plugins/media_tools.rb +13 -0
  57. metadata +110 -0
@@ -0,0 +1,292 @@
1
+ require "set"
2
+
3
+ module GrubY
4
+ module Filters
5
+ class Filter
6
+ attr_reader :name
7
+
8
+ def initialize(name = "Filter", &block)
9
+ @name = name
10
+ @block = block || proc { true }
11
+ end
12
+
13
+ def call(*args)
14
+ @block.call(*args)
15
+ end
16
+
17
+ def &(other)
18
+ Filter.new("(#{name}&#{other.name})") { |*args| call(*args) && other.call(*args) }
19
+ end
20
+
21
+ def |(other)
22
+ Filter.new("(#{name}|#{other.name})") { |*args| call(*args) || other.call(*args) }
23
+ end
24
+
25
+ def ~@
26
+ Filter.new("~#{name}") { |*args| !call(*args) }
27
+ end
28
+ end
29
+
30
+ class EntityFilter < Filter
31
+ attr_reader :values
32
+
33
+ def initialize(name, values = nil, &matcher)
34
+ @values = normalize(values)
35
+ @matcher = matcher
36
+ super(name) do |_filter, _client, update|
37
+ @matcher.call(update, @values)
38
+ end
39
+ end
40
+
41
+ def add(value)
42
+ @values.merge(normalize(value))
43
+ self
44
+ end
45
+
46
+ def delete(value)
47
+ normalize(value).each { |v| @values.delete(v) }
48
+ self
49
+ end
50
+
51
+ def clear
52
+ @values.clear
53
+ self
54
+ end
55
+
56
+ private
57
+
58
+ def normalize(v)
59
+ Array(v).flatten.compact.map(&:to_s).to_set
60
+ end
61
+ end
62
+
63
+ module_function
64
+
65
+ def create(func:, name: "CustomFilter", **kwargs)
66
+ Filter.new(name) do |filter, client, update|
67
+ func.call(filter, client, update, **kwargs)
68
+ end
69
+ end
70
+
71
+ def all
72
+ Filter.new("all") { true }
73
+ end
74
+
75
+ def me
76
+ Filter.new("me") do |_f, _c, u|
77
+ msg = message_from(u)
78
+ msg&.from&.is_bot == false && (msg&.from&.is_self == true || %w[me self].include?(msg&.from&.username.to_s.downcase))
79
+ end
80
+ end
81
+
82
+ def bot
83
+ Filter.new("bot") { |_f, _c, u| message_from(u)&.from&.is_bot == true }
84
+ end
85
+
86
+ def sender_chat
87
+ Filter.new("sender_chat") { |_f, _c, u| !message_from(u)&.sender_chat.nil? }
88
+ end
89
+
90
+ def incoming
91
+ Filter.new("incoming") { |_f, _c, u| message_from(u)&.from&.is_bot != true }
92
+ end
93
+
94
+ def outgoing
95
+ Filter.new("outgoing") do |_f, _c, u|
96
+ msg = message_from(u)
97
+ msg && msg.from && (msg.from.is_self == true || msg.from.id == msg.chat&.id)
98
+ end
99
+ end
100
+
101
+ def text = has_key_filter("text")
102
+ def reply = Filter.new("reply") { |_f, _c, u| !!(message_from(u)&.reply_to_message || message_from(u)&.reply_to_story) }
103
+ def forwarded = Filter.new("forwarded") { |_f, _c, u| !!message_from(u)&.forward_origin }
104
+ def caption = has_key_filter("caption")
105
+ def self_destruction = has_key_filter("self_destruction")
106
+ def audio = has_key_filter("audio")
107
+ def document = has_key_filter("document")
108
+ def photo = has_key_filter("photo")
109
+ def sticker = has_key_filter("sticker")
110
+ def animation = has_key_filter("animation")
111
+ def game = has_key_filter("game")
112
+ def giveaway = has_key_filter("giveaway")
113
+ def giveaway_winners = has_key_filter("giveaway_winners")
114
+ def gift_code = has_key_filter("gift_code")
115
+ def gift = has_key_filter("gift")
116
+ def users_shared = has_key_filter("users_shared")
117
+ def chat_shared = has_key_filter("chat_shared")
118
+ def video = has_key_filter("video")
119
+ def media_group = has_key_filter("media_group_id")
120
+ def voice = has_key_filter("voice")
121
+ def video_note = has_key_filter("video_note")
122
+ def contact = has_key_filter("contact")
123
+ def location = has_key_filter("location")
124
+ def live_location = Filter.new("live_location") { |_f, _c, u| !!message_from(u)&.location&.dig("live_period") }
125
+ def venue = has_key_filter("venue")
126
+ def web_page = Filter.new("web_page") { |_f, _c, u| !!message_from(u)&.link_preview_options }
127
+ def poll = has_key_filter("poll")
128
+ def dice = has_key_filter("dice")
129
+ def quote = has_key_filter("quote")
130
+ def media_spoiler = has_key_filter("has_media_spoiler")
131
+ def story = has_key_filter("story")
132
+ def new_chat_members = has_key_filter("new_chat_members")
133
+ def left_chat_member = has_key_filter("left_chat_member")
134
+ def new_chat_title = has_key_filter("new_chat_title")
135
+ def new_chat_photo = has_key_filter("new_chat_photo")
136
+ def delete_chat_photo = has_key_filter("delete_chat_photo")
137
+ def group_chat_created = has_key_filter("group_chat_created")
138
+ def supergroup_chat_created = has_key_filter("supergroup_chat_created")
139
+ def channel_chat_created = has_key_filter("channel_chat_created")
140
+ def migrate_to_chat_id = has_key_filter("migrate_to_chat_id")
141
+ def migrate_from_chat_id = has_key_filter("migrate_from_chat_id")
142
+ def pinned_message = has_key_filter("pinned_message")
143
+ def game_high_score = has_key_filter("game_high_score")
144
+ def reply_keyboard = has_key_filter("reply_markup")
145
+ def inline_keyboard = has_key_filter("reply_markup")
146
+ def mentioned = Filter.new("mentioned") { |_f, _c, u| message_from(u)&.entities&.any? { |e| e["type"] == "mention" } }
147
+ def via_bot = has_key_filter("via_bot")
148
+ def admin = Filter.new("admin") { |_f, _c, u| %w[administrator creator].include?(message_from(u)&.chat_member_status.to_s) }
149
+ def video_chat_started = has_key_filter("video_chat_started")
150
+ def video_chat_ended = has_key_filter("video_chat_ended")
151
+ def business = has_key_filter("business_connection_id")
152
+ def video_chat_members_invited = has_key_filter("video_chat_members_invited")
153
+ def successful_payment = has_key_filter("successful_payment")
154
+ def scheduled = has_key_filter("is_scheduled")
155
+ def from_scheduled = has_key_filter("from_scheduled")
156
+ def paid_message = has_key_filter("is_paid_post")
157
+ def linked_channel = has_key_filter("is_automatic_forward")
158
+ def gift_offer = has_key_filter("gift_offer")
159
+ def gift_offer_accepted = has_key_filter("gift_offer_accepted")
160
+ def gift_offer_rejected = has_key_filter("gift_offer_rejected")
161
+
162
+ def service
163
+ Filter.new("service") do |_f, _c, u|
164
+ msg = message_from(u)
165
+ next false unless msg
166
+
167
+ %w[left_chat_member new_chat_title new_chat_photo delete_chat_photo group_chat_created
168
+ supergroup_chat_created channel_chat_created migrate_to_chat_id migrate_from_chat_id
169
+ pinned_message video_chat_started video_chat_ended video_chat_members_invited successful_payment].any? do |k|
170
+ present_key?(msg, k)
171
+ end
172
+ end
173
+ end
174
+
175
+ def media
176
+ Filter.new("media") do |_f, _c, u|
177
+ msg = message_from(u)
178
+ next false unless msg
179
+
180
+ %w[audio document photo sticker video animation voice video_note contact location venue poll].any? { |k| present_key?(msg, k) }
181
+ end
182
+ end
183
+
184
+ def private
185
+ Filter.new("private") { |_f, _c, u| message_from(u)&.chat&.type == "private" }
186
+ end
187
+
188
+ def group
189
+ Filter.new("group") { |_f, _c, u| %w[group supergroup].include?(message_from(u)&.chat&.type) }
190
+ end
191
+
192
+ def channel
193
+ Filter.new("channel") { |_f, _c, u| message_from(u)&.chat&.type == "channel" }
194
+ end
195
+
196
+ def direct
197
+ Filter.new("direct") { |_f, _c, u| message_from(u)&.chat&.is_direct_messages == true }
198
+ end
199
+
200
+ def forum
201
+ Filter.new("forum") { |_f, _c, u| message_from(u)&.chat&.is_forum == true }
202
+ end
203
+
204
+ def command(commands, prefixes: "/", case_sensitive: false)
205
+ list = Array(commands).map(&:to_s)
206
+ prefix_list = prefixes.nil? ? [""] : Array(prefixes).map(&:to_s)
207
+ Filter.new("command") do |_f, _c, u|
208
+ msg = message_from(u)
209
+ text = msg&.text.to_s
210
+ next false if text.empty?
211
+ next false unless prefix_list.any? { |p| p.empty? || text.start_with?(p) }
212
+
213
+ cmd = text.split(/\s+/, 2).first.to_s
214
+ cmd = cmd.sub(/\A[#{Regexp.escape(prefix_list.join)}]/, "") unless prefix_list.include?("")
215
+ cmd = cmd.split("@", 2).first
216
+ cmd = cmd.downcase unless case_sensitive
217
+ expected = case_sensitive ? list : list.map(&:downcase)
218
+ expected.include?(cmd)
219
+ end
220
+ end
221
+
222
+ def regex(pattern, flags: 0)
223
+ reg = pattern.is_a?(Regexp) ? pattern : Regexp.new(pattern.to_s, flags)
224
+ Filter.new("regex") do |_f, _c, u|
225
+ target = if u.respond_to?(:data) && !u.data.to_s.empty?
226
+ u.data.to_s
227
+ elsif u.respond_to?(:query)
228
+ u.query.to_s
229
+ else
230
+ msg = message_from(u)
231
+ msg&.text.to_s.empty? ? msg&.caption.to_s : msg&.text.to_s
232
+ end
233
+ !!(target =~ reg)
234
+ end
235
+ end
236
+
237
+ def user(users = nil)
238
+ require "set"
239
+ EntityFilter.new("user", users) do |u, values|
240
+ msg = message_from(u)
241
+ uid = msg&.from&.id || u&.from&.id
242
+ uname = msg&.from&.username || u&.from&.username
243
+ values.empty? || values.include?(uid.to_s) || values.include?(uname.to_s) || values.include?("me")
244
+ end
245
+ end
246
+
247
+ def chat(chats = nil)
248
+ require "set"
249
+ EntityFilter.new("chat", chats) do |u, values|
250
+ msg = message_from(u)
251
+ cid = msg&.chat&.id || u&.chat&.id
252
+ uname = msg&.chat&.username || u&.chat&.username
253
+ values.empty? || values.include?(cid.to_s) || values.include?(uname.to_s) || values.include?("me")
254
+ end
255
+ end
256
+
257
+ def topic(topics = nil)
258
+ require "set"
259
+ EntityFilter.new("topic", topics) do |u, values|
260
+ msg = message_from(u)
261
+ tid = msg&.message_thread_id || msg&.direct_messages_topic&.dig("topic_id")
262
+ values.empty? || values.include?(tid.to_s)
263
+ end
264
+ end
265
+
266
+ private_class_method
267
+
268
+ def has_key_filter(key)
269
+ Filter.new(key) { |_f, _c, u| present_key?(message_from(u), key) }
270
+ end
271
+
272
+ def present_key?(obj, key)
273
+ return false unless obj
274
+ value = if obj.respond_to?(:[])
275
+ obj[key]
276
+ elsif obj.respond_to?(key)
277
+ obj.public_send(key)
278
+ end
279
+ !(value.nil? || (value.respond_to?(:empty?) && value.empty?))
280
+ end
281
+
282
+ def message_from(update)
283
+ return update if update.is_a?(GrubY::Message)
284
+ return update.message if update.respond_to?(:message)
285
+ return update.edited_message if update.respond_to?(:edited_message)
286
+ return update.business_message if update.respond_to?(:business_message)
287
+ return update.edited_business_message if update.respond_to?(:edited_business_message)
288
+
289
+ nil
290
+ end
291
+ end
292
+ end
@@ -0,0 +1,213 @@
1
+ module GrubY
2
+ class GroupManager
3
+ DEFAULT_WARN_LIMIT = 3
4
+
5
+ def initialize(api, session: nil, warn_limit: DEFAULT_WARN_LIMIT)
6
+ @api = api
7
+ @session = session
8
+ @warn_limit = warn_limit
9
+ end
10
+
11
+ def ban(chat_id, user_id, **opts)
12
+ @api.ban_chat_member(chat_id: chat_id, user_id: user_id, **opts)
13
+ end
14
+
15
+ def unban(chat_id, user_id, **opts)
16
+ @api.unban_chat_member(chat_id: chat_id, user_id: user_id, **opts)
17
+ end
18
+
19
+ def kick(chat_id, user_id, **opts)
20
+ ban(chat_id, user_id, **opts)
21
+ unban(chat_id, user_id)
22
+ end
23
+
24
+ def restrict(chat_id, user_id, permissions:, **opts)
25
+ @api.restrict_chat_member(
26
+ chat_id: chat_id,
27
+ user_id: user_id,
28
+ permissions: permissions,
29
+ **opts
30
+ )
31
+ end
32
+
33
+ def mute(chat_id, user_id, until_date: nil)
34
+ restrict(
35
+ chat_id,
36
+ user_id,
37
+ permissions: { can_send_messages: false },
38
+ until_date: until_date
39
+ )
40
+ end
41
+
42
+ def unmute(chat_id, user_id)
43
+ permissions = {
44
+ can_send_messages: true,
45
+ can_send_audios: true,
46
+ can_send_documents: true,
47
+ can_send_photos: true,
48
+ can_send_videos: true,
49
+ can_send_video_notes: true,
50
+ can_send_voice_notes: true,
51
+ can_send_polls: true,
52
+ can_send_other_messages: true,
53
+ can_add_web_page_previews: true
54
+ }
55
+ restrict(chat_id, user_id, permissions: permissions)
56
+ end
57
+
58
+ def promote(chat_id, user_id, **opts)
59
+ @api.promote_chat_member(chat_id: chat_id, user_id: user_id, **opts)
60
+ end
61
+
62
+ def demote(chat_id, user_id)
63
+ promote(
64
+ chat_id,
65
+ user_id,
66
+ can_manage_chat: false,
67
+ can_delete_messages: false,
68
+ can_manage_video_chats: false,
69
+ can_restrict_members: false,
70
+ can_promote_members: false,
71
+ can_change_info: false,
72
+ can_invite_users: false,
73
+ can_post_stories: false,
74
+ can_edit_stories: false,
75
+ can_delete_stories: false,
76
+ can_post_messages: false,
77
+ can_edit_messages: false,
78
+ can_pin_messages: false,
79
+ can_manage_topics: false
80
+ )
81
+ end
82
+
83
+ def set_member_tag(chat_id, user_id, tag = nil)
84
+ @api.set_chat_member_tag(chat_id: chat_id, user_id: user_id, tag: tag)
85
+ end
86
+
87
+ def set_admin_title(chat_id, user_id, title)
88
+ @api.set_chat_administrator_custom_title(
89
+ chat_id: chat_id,
90
+ user_id: user_id,
91
+ custom_title: title
92
+ )
93
+ end
94
+
95
+ def set_administrator_title(chat_id, user_id, title)
96
+ set_admin_title(chat_id, user_id, title)
97
+ end
98
+
99
+ def set_chat_title(chat_id, title)
100
+ @api.set_chat_title(chat_id: chat_id, title: title)
101
+ end
102
+
103
+ def set_chat_description(chat_id, description)
104
+ @api.set_chat_description(chat_id: chat_id, description: description)
105
+ end
106
+
107
+ def set_chat_photo(chat_id, photo)
108
+ @api.set_chat_photo(chat_id: chat_id, photo: photo)
109
+ end
110
+
111
+ def delete_chat_photo(chat_id)
112
+ @api.delete_chat_photo(chat_id: chat_id)
113
+ end
114
+
115
+ def leave_chat(chat_id)
116
+ @api.leave_chat(chat_id: chat_id)
117
+ end
118
+
119
+ def set_permissions(chat_id, permissions, **opts)
120
+ @api.set_chat_permissions(chat_id: chat_id, permissions: permissions, **opts)
121
+ end
122
+
123
+ def lock(chat_id)
124
+ set_permissions(chat_id, { can_send_messages: false })
125
+ end
126
+
127
+ def unlock(chat_id)
128
+ set_permissions(chat_id, { can_send_messages: true })
129
+ end
130
+
131
+ def set_slow_mode(chat_id, seconds)
132
+ @api.set_slow_mode(chat_id: chat_id, seconds: seconds)
133
+ end
134
+
135
+ def pin(chat_id, message_id, **opts)
136
+ @api.pin_chat_message(chat_id: chat_id, message_id: message_id, **opts)
137
+ end
138
+
139
+ def unpin(chat_id, message_id = nil, **opts)
140
+ params = { chat_id: chat_id }.merge(opts)
141
+ params[:message_id] = message_id if message_id
142
+ @api.unpin_chat_message(**params)
143
+ end
144
+
145
+ def unpin_all(chat_id)
146
+ @api.unpin_all_chat_messages(chat_id: chat_id)
147
+ end
148
+
149
+ def approve_join_request(chat_id, user_id)
150
+ @api.approve_chat_join_request(chat_id: chat_id, user_id: user_id)
151
+ end
152
+
153
+ def decline_join_request(chat_id, user_id)
154
+ @api.decline_chat_join_request(chat_id: chat_id, user_id: user_id)
155
+ end
156
+
157
+ def get_chat(chat_id)
158
+ @api.get_chat(chat_id: chat_id)
159
+ end
160
+
161
+ def get_member(chat_id, user_id)
162
+ @api.get_chat_member(chat_id: chat_id, user_id: user_id)
163
+ end
164
+
165
+ def warn(chat_id, user_id, reason: nil)
166
+ key = warn_key(chat_id, user_id)
167
+ current = load_warns(key)
168
+ current += 1
169
+ store_warns(key, current)
170
+
171
+ {
172
+ user_id: user_id,
173
+ warns: current,
174
+ limit: @warn_limit,
175
+ reason: reason,
176
+ action: (current >= @warn_limit ? :kick : :none)
177
+ }
178
+ end
179
+
180
+ def reset_warns(chat_id, user_id)
181
+ key = warn_key(chat_id, user_id)
182
+ store_warns(key, 0)
183
+ end
184
+
185
+ def enforce_warns(chat_id, user_id, reason: nil)
186
+ result = warn(chat_id, user_id, reason: reason)
187
+ return result unless result[:action] == :kick
188
+
189
+ kick(chat_id, user_id)
190
+ reset_warns(chat_id, user_id)
191
+ result
192
+ end
193
+
194
+ private
195
+
196
+ def warn_key(chat_id, user_id)
197
+ "warns:#{chat_id}:#{user_id}"
198
+ end
199
+
200
+ def load_warns(key)
201
+ return 0 unless @session
202
+
203
+ value = @session.get(key)
204
+ value.is_a?(Hash) ? value["count"].to_i : value.to_i
205
+ end
206
+
207
+ def store_warns(key, count)
208
+ return unless @session
209
+
210
+ @session.set(key, { "count" => count })
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,170 @@
1
+ module GrubY
2
+ module Handlers
3
+ class BaseHandler
4
+ attr_reader :callback, :filters, :group, :exceptions
5
+
6
+ def initialize(callback = nil, filters: nil, group: 0, exceptions: nil, &block)
7
+ @callback = callback || block
8
+ @filters = filters
9
+ @group = group.to_i
10
+ @exceptions = exceptions
11
+ end
12
+
13
+ def event
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def extract(ctx)
18
+ ctx
19
+ end
20
+
21
+ def client_only?
22
+ false
23
+ end
24
+ end
25
+
26
+ class MessageHandler < BaseHandler
27
+ def event = :message
28
+ def extract(ctx) = ctx.message
29
+ end
30
+
31
+ class EditedMessageHandler < BaseHandler
32
+ def event = :edited_message
33
+ def extract(ctx) = ctx.edited_message
34
+ end
35
+
36
+ class DeletedMessagesHandler < BaseHandler
37
+ def event = :deleted_messages
38
+ def extract(ctx) = ctx.deleted_messages
39
+ end
40
+
41
+ class BusinessMessageHandler < BaseHandler
42
+ def event = :business_message
43
+ def extract(ctx) = ctx.business_message
44
+ end
45
+
46
+ class EditedBusinessMessageHandler < BaseHandler
47
+ def event = :edited_business_message
48
+ def extract(ctx) = ctx.edited_business_message
49
+ end
50
+
51
+ class DeletedBusinessMessagesHandler < BaseHandler
52
+ def event = :deleted_business_messages
53
+ def extract(ctx) = ctx.deleted_business_messages
54
+ end
55
+
56
+ class BusinessConnectionHandler < BaseHandler
57
+ def event = :business_connection
58
+ def extract(ctx) = ctx.business_connection
59
+ end
60
+
61
+ class CallbackQueryHandler < BaseHandler
62
+ def event = :callback_query
63
+ def extract(ctx) = ctx.callback_query
64
+ end
65
+
66
+ class ChatBoostHandler < BaseHandler
67
+ def event = :chat_boost
68
+ def extract(ctx) = ctx.chat_boost
69
+ end
70
+
71
+ class ChatJoinRequestHandler < BaseHandler
72
+ def event = :chat_join_request
73
+ def extract(ctx) = ctx.chat_join_request
74
+ end
75
+
76
+ class ChatMemberUpdatedHandler < BaseHandler
77
+ def event = :chat_member_updated
78
+ def extract(ctx) = ctx.chat_member_updated
79
+ end
80
+
81
+ class ChosenInlineResultHandler < BaseHandler
82
+ def event = :chosen_inline_result
83
+ def extract(ctx) = ctx.chosen_inline_result
84
+ end
85
+
86
+ class InlineQueryHandler < BaseHandler
87
+ def event = :inline_query
88
+ def extract(ctx) = ctx.inline_query
89
+ end
90
+
91
+ class MessageReactionCountHandler < BaseHandler
92
+ def event = :message_reaction_count
93
+ def extract(ctx) = ctx.message_reaction_count
94
+ end
95
+
96
+ class MessageReactionHandler < BaseHandler
97
+ def event = :message_reaction
98
+ def extract(ctx) = ctx.message_reaction
99
+ end
100
+
101
+ class PollHandler < BaseHandler
102
+ def event = :poll
103
+ def extract(ctx) = ctx.poll_update
104
+ end
105
+
106
+ class PreCheckoutQueryHandler < BaseHandler
107
+ def event = :pre_checkout_query
108
+ def extract(ctx) = ctx.pre_checkout_query
109
+ end
110
+
111
+ class PurchasedPaidMediaHandler < BaseHandler
112
+ def event = :purchased_paid_media
113
+ def extract(ctx) = ctx.purchased_paid_media
114
+ end
115
+
116
+ class ShippingQueryHandler < BaseHandler
117
+ def event = :shipping_query
118
+ def extract(ctx) = ctx.shipping_query
119
+ end
120
+
121
+ class StoryHandler < BaseHandler
122
+ def event = :story
123
+ def extract(ctx) = ctx.story_update
124
+ end
125
+
126
+ class UserStatusHandler < BaseHandler
127
+ def event = :user_status
128
+ def extract(ctx) = ctx.user_status
129
+ end
130
+
131
+ class StartHandler < BaseHandler
132
+ def event = :start
133
+ def extract(_ctx) = nil
134
+ def client_only? = true
135
+ end
136
+
137
+ class StopHandler < BaseHandler
138
+ def event = :stop
139
+ def extract(_ctx) = nil
140
+ def client_only? = true
141
+ end
142
+
143
+ class ConnectHandler < BaseHandler
144
+ def event = :connect
145
+ def extract(_ctx) = nil
146
+ def client_only? = true
147
+ end
148
+
149
+ class DisconnectHandler < BaseHandler
150
+ def event = :disconnect
151
+ def extract(_ctx) = nil
152
+ def client_only? = true
153
+ end
154
+
155
+ class ErrorHandler < BaseHandler
156
+ def event = :error
157
+ def extract(ctx) = ctx.error_payload
158
+ end
159
+
160
+ class ManagedBotUpdatedHandler < BaseHandler
161
+ def event = :managed_bot
162
+ def extract(ctx) = ctx.managed_bot_updated
163
+ end
164
+
165
+ class RawUpdateHandler < BaseHandler
166
+ def event = :raw_update
167
+ def extract(ctx) = ctx.update
168
+ end
169
+ end
170
+ end