discorb 0.16.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/build_main.yml +2 -2
  4. data/.github/workflows/build_version.yml +1 -1
  5. data/.github/workflows/codeql-analysis.yml +1 -1
  6. data/.github/workflows/lint-push.yml +3 -5
  7. data/.github/workflows/lint.yml +2 -4
  8. data/.github/workflows/spec.yml +33 -0
  9. data/.github/workflows/validate.yml +21 -0
  10. data/.gitignore +2 -0
  11. data/.lefthook/commit-msg/validator.rb +5 -0
  12. data/.rspec +2 -0
  13. data/.rspec_parallel +2 -0
  14. data/.rubocop.yml +43 -6
  15. data/Changelog.md +30 -1
  16. data/Gemfile +20 -8
  17. data/Rakefile +226 -98
  18. data/Steepfile +28 -0
  19. data/bin/console +3 -3
  20. data/docs/Examples.md +1 -1
  21. data/docs/application_command.md +156 -47
  22. data/docs/cli/irb.md +2 -2
  23. data/docs/cli/new.md +14 -9
  24. data/docs/cli/run.md +7 -11
  25. data/docs/cli.md +17 -10
  26. data/docs/events.md +247 -213
  27. data/docs/extension.md +1 -2
  28. data/docs/faq.md +0 -1
  29. data/docs/tutorial.md +18 -18
  30. data/docs/voice_events.md +106 -106
  31. data/examples/commands/message.rb +68 -0
  32. data/examples/commands/permission.rb +19 -0
  33. data/examples/commands/slash.rb +48 -0
  34. data/examples/commands/user.rb +54 -0
  35. data/examples/components/authorization_button.rb +4 -3
  36. data/examples/components/select_menu.rb +6 -3
  37. data/examples/extension/main.rb +2 -1
  38. data/examples/extension/message_expander.rb +6 -2
  39. data/examples/sig/commands/message.rbs +5 -0
  40. data/examples/simple/eval.rb +3 -2
  41. data/examples/simple/ping_pong.rb +2 -1
  42. data/examples/simple/rolepanel.rb +17 -6
  43. data/examples/simple/shard.rb +3 -2
  44. data/examples/simple/wait_for_message.rb +4 -1
  45. data/exe/discorb +33 -18
  46. data/lefthook.yml +45 -0
  47. data/lib/discorb/allowed_mentions.rb +2 -1
  48. data/lib/discorb/app_command/command.rb +130 -72
  49. data/lib/discorb/app_command/common.rb +25 -0
  50. data/lib/discorb/app_command/handler.rb +130 -33
  51. data/lib/discorb/app_command.rb +2 -1
  52. data/lib/discorb/application.rb +1 -0
  53. data/lib/discorb/asset.rb +1 -2
  54. data/lib/discorb/attachment.rb +1 -1
  55. data/lib/discorb/audit_logs.rb +19 -10
  56. data/lib/discorb/automod.rb +269 -0
  57. data/lib/discorb/channel/base.rb +108 -0
  58. data/lib/discorb/channel/category.rb +32 -0
  59. data/lib/discorb/channel/container.rb +44 -0
  60. data/lib/discorb/channel/dm.rb +28 -0
  61. data/lib/discorb/channel/guild.rb +246 -0
  62. data/lib/discorb/channel/stage.rb +140 -0
  63. data/lib/discorb/channel/text.rb +336 -0
  64. data/lib/discorb/channel/thread.rb +325 -0
  65. data/lib/discorb/channel/voice.rb +79 -0
  66. data/lib/discorb/channel.rb +2 -1165
  67. data/lib/discorb/client.rb +50 -36
  68. data/lib/discorb/color.rb +37 -60
  69. data/lib/discorb/common.rb +2 -1
  70. data/lib/discorb/components/button.rb +2 -1
  71. data/lib/discorb/components/select_menu.rb +4 -2
  72. data/lib/discorb/components/text_input.rb +12 -2
  73. data/lib/discorb/components.rb +1 -1
  74. data/lib/discorb/dictionary.rb +1 -1
  75. data/lib/discorb/embed.rb +26 -10
  76. data/lib/discorb/emoji.rb +31 -4
  77. data/lib/discorb/emoji_table.rb +4969 -3
  78. data/lib/discorb/event.rb +29 -4
  79. data/lib/discorb/exe/about.rb +2 -1
  80. data/lib/discorb/exe/irb.rb +2 -4
  81. data/lib/discorb/exe/new.rb +89 -26
  82. data/lib/discorb/exe/run.rb +8 -22
  83. data/lib/discorb/exe/setup.rb +25 -12
  84. data/lib/discorb/exe/show.rb +4 -3
  85. data/lib/discorb/extend.rb +1 -0
  86. data/lib/discorb/extension.rb +6 -7
  87. data/lib/discorb/flag.rb +13 -2
  88. data/lib/discorb/gateway.rb +79 -589
  89. data/lib/discorb/gateway_events.rb +638 -0
  90. data/lib/discorb/guild.rb +318 -67
  91. data/lib/discorb/guild_template.rb +11 -5
  92. data/lib/discorb/http.rb +53 -24
  93. data/lib/discorb/integration.rb +4 -1
  94. data/lib/discorb/intents.rb +28 -19
  95. data/lib/discorb/interaction/autocomplete.rb +28 -16
  96. data/lib/discorb/interaction/command.rb +42 -14
  97. data/lib/discorb/interaction/components.rb +5 -2
  98. data/lib/discorb/interaction/modal.rb +0 -1
  99. data/lib/discorb/interaction/response.rb +125 -26
  100. data/lib/discorb/interaction/root.rb +13 -13
  101. data/lib/discorb/interaction.rb +1 -0
  102. data/lib/discorb/invite.rb +5 -2
  103. data/lib/discorb/member.rb +28 -8
  104. data/lib/discorb/message.rb +60 -25
  105. data/lib/discorb/message_meta.rb +3 -3
  106. data/lib/discorb/modules.rb +59 -16
  107. data/lib/discorb/presence.rb +2 -0
  108. data/lib/discorb/rate_limit.rb +7 -2
  109. data/lib/discorb/reaction.rb +2 -2
  110. data/lib/discorb/role.rb +20 -5
  111. data/lib/discorb/shard.rb +1 -1
  112. data/lib/discorb/sticker.rb +9 -8
  113. data/lib/discorb/user.rb +4 -3
  114. data/lib/discorb/utils/colored_puts.rb +1 -0
  115. data/lib/discorb/voice_state.rb +6 -2
  116. data/lib/discorb/webhook.rb +64 -31
  117. data/lib/discorb.rb +7 -5
  118. data/po/yard.pot +20 -20
  119. data/rbs_collection.lock.yaml +88 -0
  120. data/rbs_collection.yaml +21 -0
  121. data/sig/async.rbs +11 -0
  122. data/sig/discorb/activity.rbs +23 -0
  123. data/sig/discorb/allowed_mentions.rbs +44 -0
  124. data/sig/discorb/app_command/base.rbs +282 -0
  125. data/sig/discorb/app_command/handler.rbs +171 -0
  126. data/sig/discorb/application.rbs +142 -0
  127. data/sig/discorb/asset.rbs +32 -0
  128. data/sig/discorb/attachment.rbs +91 -0
  129. data/sig/discorb/audit_log.rbs +231 -0
  130. data/sig/discorb/automod.rbs +128 -0
  131. data/sig/discorb/avatar.rbs +26 -0
  132. data/sig/discorb/channel/base.rbs +179 -0
  133. data/sig/discorb/channel/category.rbs +56 -0
  134. data/sig/discorb/channel/container.rbs +29 -0
  135. data/sig/discorb/channel/dm.rbs +14 -0
  136. data/sig/discorb/channel/news.rbs +20 -0
  137. data/sig/discorb/channel/stage.rbs +77 -0
  138. data/sig/discorb/channel/text.rbs +158 -0
  139. data/sig/discorb/channel/thread.rbs +185 -0
  140. data/sig/discorb/channel/voice.rbs +41 -0
  141. data/sig/discorb/client.rbs +2495 -0
  142. data/sig/discorb/color.rbs +142 -0
  143. data/sig/discorb/component/base.rbs +28 -0
  144. data/sig/discorb/component/button.rbs +65 -0
  145. data/sig/discorb/component/select_menu.rbs +107 -0
  146. data/sig/discorb/component/text_input.rbs +69 -0
  147. data/sig/discorb/connectable.rbs +8 -0
  148. data/sig/discorb/custom_emoji.rbs +90 -0
  149. data/sig/discorb/dictionary.rbs +85 -0
  150. data/sig/discorb/discord_model.rbs +15 -0
  151. data/sig/discorb/embed.rbs +279 -0
  152. data/sig/discorb/emoji.rbs +13 -0
  153. data/sig/discorb/error.rbs +73 -0
  154. data/sig/discorb/event_handler.rbs +27 -0
  155. data/sig/discorb/extension.rbs +1734 -0
  156. data/sig/discorb/flag.rbs +72 -0
  157. data/sig/discorb/gateway.rbs +481 -0
  158. data/sig/discorb/guild.rbs +870 -0
  159. data/sig/discorb/guild_template.rbs +174 -0
  160. data/sig/discorb/http.rbs +147 -0
  161. data/sig/discorb/image.rbs +20 -0
  162. data/sig/discorb/integration.rbs +118 -0
  163. data/sig/discorb/intents.rbs +97 -0
  164. data/sig/discorb/interaction/autocomplete.rbs +9 -0
  165. data/sig/discorb/interaction/base.rbs +66 -0
  166. data/sig/discorb/interaction/command.rbs +66 -0
  167. data/sig/discorb/interaction/message_component.rbs +140 -0
  168. data/sig/discorb/interaction/modal.rbs +50 -0
  169. data/sig/discorb/interaction/responder.rbs +157 -0
  170. data/sig/discorb/invite.rbs +86 -0
  171. data/sig/discorb/member.rbs +187 -0
  172. data/sig/discorb/message.rbs +469 -0
  173. data/sig/discorb/messageable.rbs +153 -0
  174. data/sig/discorb/partial_emoji.rbs +35 -0
  175. data/sig/discorb/permissions.rbs +149 -0
  176. data/sig/discorb/presence.rbs +237 -0
  177. data/sig/discorb/reaction.rbs +33 -0
  178. data/sig/discorb/role.rbs +145 -0
  179. data/sig/discorb/scheduled_event.rbs +148 -0
  180. data/sig/discorb/shard.rbs +62 -0
  181. data/sig/discorb/snowflake.rbs +56 -0
  182. data/sig/discorb/stage_instance.rbs +63 -0
  183. data/sig/discorb/sticker.rbs +116 -0
  184. data/sig/discorb/system_channel_flag.rbs +17 -0
  185. data/sig/discorb/unicode_emoji.rbs +49 -0
  186. data/sig/discorb/user.rbs +93 -0
  187. data/sig/discorb/utils.rbs +8 -0
  188. data/sig/discorb/voice_region.rbs +30 -0
  189. data/sig/discorb/voice_state.rbs +71 -0
  190. data/sig/discorb/webhook.rbs +327 -0
  191. data/sig/discorb/welcome_screen.rbs +78 -0
  192. data/sig/discorb.rbs +6 -7230
  193. data/sig/manifest.yaml +3 -0
  194. data/sig/override.rbs +19 -0
  195. data/template-replace/files/css/common.css +4 -0
  196. metadata +102 -6
  197. data/examples/commands/bookmarker.rb +0 -42
  198. data/examples/commands/hello.rb +0 -10
  199. data/examples/commands/inspect.rb +0 -25
@@ -12,572 +12,12 @@ module Discorb
12
12
  # This module is internal use only.
13
13
  #
14
14
  module Gateway
15
- #
16
- # Represents an event.
17
- # @abstract
18
- #
19
- class GatewayEvent
20
- #
21
- # Initializes a new instance of the GatewayEvent class.
22
- # @private
23
- #
24
- # @param [Hash] data The data of the event.
25
- #
26
- def initialize(data)
27
- @data = data
28
- end
29
-
30
- def inspect
31
- "#<#{self.class}>"
32
- end
33
- end
34
-
35
- #
36
- # Represents a reaction event.
37
- #
38
- class ReactionEvent < GatewayEvent
39
- # @return [Hash] The raw data of the event.
40
- attr_reader :data
41
- # @return [Discorb::Snowflake] The ID of the user who reacted.
42
- attr_reader :user_id
43
- alias member_id user_id
44
- # @return [Discorb::Snowflake] The ID of the channel the message was sent in.
45
- attr_reader :channel_id
46
- # @return [Discorb::Snowflake] The ID of the message.
47
- attr_reader :message_id
48
- # @return [Discorb::Snowflake] The ID of the guild the message was sent in.
49
- attr_reader :guild_id
50
- # @macro client_cache
51
- # @return [Discorb::User] The user who reacted.
52
- attr_reader :user
53
- # @macro client_cache
54
- # @return [Discorb::Channel] The channel the message was sent in.
55
- attr_reader :channel
56
- # @macro client_cache
57
- # @return [Discorb::Guild] The guild the message was sent in.
58
- attr_reader :guild
59
- # @macro client_cache
60
- # @return [Discorb::Message] The message the reaction was sent in.
61
- attr_reader :message
62
- # @macro client_cache
63
- # @return [Discorb::Member] The member who reacted.
64
- attr_reader :member
65
- # @return [Discorb::UnicodeEmoji, Discorb::PartialEmoji] The emoji that was reacted with.
66
- attr_reader :emoji
67
- # @macro client_cache
68
- # @return [Discorb::Member, Discorb::User] The user or member who reacted.
69
- attr_reader :fired_by
70
-
71
- alias reactor fired_by
72
- alias from fired_by
73
-
74
- #
75
- # Initializes a new instance of the ReactionEvent class.
76
- # @private
77
- #
78
- # @param [Discorb::Client] client The client that instantiated the object.
79
- # @param [Hash] data The data of the event.
80
- #
81
- def initialize(client, data)
82
- @client = client
83
- @data = data
84
- if data.key?(:user_id)
85
- @user_id = Snowflake.new(data[:user_id])
86
- else
87
- @member_data = data[:member]
88
- end
89
- @channel_id = Snowflake.new(data[:channel_id])
90
- @message_id = Snowflake.new(data[:message_id])
91
- @guild_id = Snowflake.new(data[:guild_id])
92
- @guild = client.guilds[data[:guild_id]]
93
- @channel = client.channels[data[:channel_id]] unless @guild.nil?
94
-
95
- @user = client.users[data[:user_id]] if data.key?(:user_id)
96
-
97
- unless @guild.nil?
98
- @member = if data.key?(:member)
99
- @guild.members[data[:member][:user][:id]] || Member.new(@client, @guild_id, data[:member][:user], data[:member])
100
- else
101
- @guild.members[data[:user_id]]
102
- end
103
- end
104
-
105
- @fired_by = @member || @user || @client.users[data[:user_id]]
106
-
107
- @message = client.messages[data[:message_id]]
108
- @emoji = data[:emoji][:id].nil? ? UnicodeEmoji.new(data[:emoji][:name]) : PartialEmoji.new(data[:emoji])
109
- end
110
-
111
- # Fetch the message.
112
- # If message is cached, it will be returned.
113
- # @async
114
- #
115
- # @param [Boolean] force Whether to force fetching the message.
116
- #
117
- # @return [Async::Task<Discorb::Message>] The message.
118
- def fetch_message(force: false)
119
- Async do
120
- next @message if !force && @message
121
-
122
- @message = @channel.fetch_message(@message_id).wait
123
- end
124
- end
125
- end
126
-
127
- #
128
- # Represents a `INTEGRATION_DELETE` event.
129
- #
130
- class IntegrationDeleteEvent < GatewayEvent
131
- # @return [Discorb::Snowflake] The ID of the integration.
132
- attr_reader :id
133
- # @!attribute [r] guild
134
- # @macro client_cache
135
- # @return [Discorb::Guild] The guild of the integration.
136
- # @!attribute [r] user
137
- # @macro client_cache
138
- # @return [Discorb::User] The user associated with the integration.
139
-
140
- #
141
- # Initialize a new instance of the IntegrationDeleteEvent class.
142
- # @private
143
- #
144
- #
145
- # @param [Hash] data The data of the event.
146
- #
147
- #
148
- def initialize(_client, data)
149
- @id = Snowflake.new(data[:id])
150
- @guild_id = data[:guild_id]
151
- @user_id = data[:application_id]
152
- end
153
-
154
- def guild
155
- @client.guilds[@guild_id]
156
- end
157
-
158
- def user
159
- @client.users[@user_id]
160
- end
161
- end
162
-
163
- #
164
- # Represents a `MESSAGE_REACTION_REMOVE_ALL` event.
165
- #
166
- class ReactionRemoveAllEvent < GatewayEvent
167
- # @return [Discorb::Snowflake] The ID of the channel the message was sent in.
168
- attr_reader :channel_id
169
- # @return [Discorb::Snowflake] The ID of the message.
170
- attr_reader :message_id
171
- # @return [Discorb::Snowflake] The ID of the guild the message was sent in.
172
- attr_reader :guild_id
173
- # @macro client_cache
174
- # @return [Discorb::Channel] The channel the message was sent in.
175
- attr_reader :channel
176
- # @macro client_cache
177
- # @return [Discorb::Guild] The guild the message was sent in.
178
- attr_reader :guild
179
- # @macro client_cache
180
- # @return [Discorb::Message] The message the reaction was sent in.
181
- attr_reader :message
182
-
183
- #
184
- # Initialize a new instance of the ReactionRemoveAllEvent class.
185
- # @private
186
- #
187
- # @param [Discorb::Client] client The client that instantiated the object.
188
- # @param [Hash] data The data of the event.
189
- #
190
- def initialize(client, data)
191
- @client = client
192
- @data = data
193
- @guild_id = Snowflake.new(data[:guild_id])
194
- @channel_id = Snowflake.new(data[:channel_id])
195
- @message_id = Snowflake.new(data[:message_id])
196
- @guild = client.guilds[data[:guild_id]]
197
- @channel = client.channels[data[:channel_id]]
198
- @message = client.messages[data[:message_id]]
199
- end
200
-
201
- # Fetch the message.
202
- # If message is cached, it will be returned.
203
- # @async
204
- #
205
- # @param [Boolean] force Whether to force fetching the message.
206
- #
207
- # @return [Async::Task<Discorb::Message>] The message.
208
- def fetch_message(force: false)
209
- Async do
210
- next @message if !force && @message
211
-
212
- @message = @channel.fetch_message(@message_id).wait
213
- end
214
- end
215
- end
216
-
217
- #
218
- # Represents a `MESSAGE_REACTION_REMOVE_EMOJI` event.
219
- #
220
- class ReactionRemoveEmojiEvent < GatewayEvent
221
- # @return [Discorb::Snowflake] The ID of the channel the message was sent in.
222
- attr_reader :channel_id
223
- # @return [Discorb::Snowflake] The ID of the message.
224
- attr_reader :message_id
225
- # @return [Discorb::Snowflake] The ID of the guild the message was sent in.
226
- attr_reader :guild_id
227
- # @macro client_cache
228
- # @return [Discorb::Channel] The channel the message was sent in.
229
- attr_reader :channel
230
- # @macro client_cache
231
- # @return [Discorb::Guild] The guild the message was sent in.
232
- attr_reader :guild
233
- # @macro client_cache
234
- # @return [Discorb::Message] The message the reaction was sent in.
235
- attr_reader :message
236
- # @return [Discorb::UnicodeEmoji, Discorb::PartialEmoji] The emoji that was reacted with.
237
- attr_reader :emoji
238
-
239
- #
240
- # Initialize a new instance of the ReactionRemoveEmojiEvent class.
241
- # @private
242
- #
243
- # @param [Discorb::Client] client The client that instantiated the object.
244
- # @param [Hash] data The data of the event.
245
- #
246
- def initialize(client, data)
247
- @client = client
248
- @data = data
249
- @guild_id = Snowflake.new(data[:guild_id])
250
- @channel_id = Snowflake.new(data[:channel_id])
251
- @message_id = Snowflake.new(data[:message_id])
252
- @guild = client.guilds[data[:guild_id]]
253
- @channel = client.channels[data[:channel_id]]
254
- @message = client.messages[data[:message_id]]
255
- @emoji = data[:emoji][:id].nil? ? DiscordEmoji.new(data[:emoji][:name]) : PartialEmoji.new(data[:emoji])
256
- end
257
-
258
- # Fetch the message.
259
- # If message is cached, it will be returned.
260
- # @async
261
- #
262
- # @param [Boolean] force Whether to force fetching the message.
263
- #
264
- # @return [Async::Task<Discorb::Message>] The message.
265
- def fetch_message(force: false)
266
- Async do
267
- next @message if !force && @message
268
-
269
- @message = @channel.fetch_message(@message_id).wait
270
- end
271
- end
272
- end
273
-
274
- #
275
- # Represents a `GUILD_SCHEDULED_EVENT_USER_ADD` and `GUILD_SCHEDULED_EVENT_USER_REMOVE` event.
276
- #
277
- class ScheduledEventUserEvent < GatewayEvent
278
- # @return [Discorb::User] The user that triggered the event.
279
- attr_reader :user
280
- # @return [Discorb::Guild] The guild the event was triggered in.
281
- attr_reader :guild
282
- # @return [Discorb::ScheduledEvent] The scheduled event.
283
- attr_reader :scheduled_event
284
- #
285
- # Initialize a new instance of the ScheduledEventUserEvent class.
286
- # @private
287
- #
288
- # @param [Discorb::Client] client The client that instantiated the object.
289
- # @param [Hash] data The data of the event.
290
- #
291
- def initialize(client, data)
292
- @client = client
293
- @scheduled_event_id = Snowflake.new(data[:scheduled_event_id])
294
- @user_id = Snowflake.new(data[:user_id])
295
- @guild_id = Snowflake.new(data[:guild_id])
296
- @guild = client.guilds[data[:guild_id]]
297
- @scheduled_event = @guild.scheduled_events[@scheduled_event_id]
298
- @user = client.users[data[:user_id]]
299
- end
300
- end
301
-
302
- #
303
- # Represents a `MESSAGE_UPDATE` event.
304
- #
305
- class MessageUpdateEvent < GatewayEvent
306
- # @return [Discorb::Message] The message before update.
307
- attr_reader :before
308
- # @return [Discorb::Message] The message after update.
309
- attr_reader :after
310
- # @return [Discorb::Snowflake] The ID of the message.
311
- attr_reader :id
312
- # @return [Discorb::Snowflake] The ID of the channel the message was sent in.
313
- attr_reader :channel_id
314
- # @return [Discorb::Snowflake] The ID of the guild the message was sent in.
315
- attr_reader :guild_id
316
- # @return [String] The new content of the message.
317
- attr_reader :content
318
- # @return [Time] The time the message was edited.
319
- attr_reader :timestamp
320
- # @return [Boolean] Whether the message pings @everyone.
321
- attr_reader :mention_everyone
322
- # @macro client_cache
323
- # @return [Array<Discorb::Role>] The roles mentioned in the message.
324
- attr_reader :mention_roles
325
- # @return [Array<Discorb::Attachment>] The attachments in the message.
326
- attr_reader :attachments
327
- # @return [Array<Discorb::Embed>] The embeds in the message.
328
- attr_reader :embeds
329
-
330
- # @!attribute [r] channel
331
- # @macro client_cache
332
- # @return [Discorb::Channel] The channel the message was sent in.
333
- # @!attribute [r] guild
334
- # @macro client_cache
335
- # @return [Discorb::Guild] The guild the message was sent in.
336
-
337
- def initialize(client, data, before, after)
338
- @client = client
339
- @data = data
340
- @before = before
341
- @after = after
342
- @id = Snowflake.new(data[:id])
343
- @channel_id = Snowflake.new(data[:channel_id])
344
- @guild_id = Snowflake.new(data[:guild_id]) if data.key?(:guild_id)
345
- @content = data[:content]
346
- @timestamp = Time.iso8601(data[:edited_timestamp])
347
- @mention_everyone = data[:mention_everyone]
348
- @mention_roles = data[:mention_roles].map { |r| guild.roles[r] } if data.key?(:mention_roles)
349
- @attachments = data[:attachments].map { |a| Attachment.from_hash(a) } if data.key?(:attachments)
350
- @embeds = data[:embeds] ? data[:embeds].map { |e| Embed.from_hash(e) } : [] if data.key?(:embeds)
351
- end
352
-
353
- def channel
354
- @client.channels[@channel_id]
355
- end
356
-
357
- def guild
358
- @client.guilds[@guild_id]
359
- end
360
-
361
- # Fetch the message.
362
- # @async
363
- #
364
- # @return [Async::Task<Discorb::Message>] The message.
365
- def fetch_message
366
- Async do
367
- channel.fetch_message(@id).wait
368
- end
369
- end
370
- end
371
-
372
- #
373
- # Represents a message but it has only ID.
374
- #
375
- class UnknownDeleteBulkMessage < GatewayEvent
376
- # @return [Discorb::Snowflake] The ID of the message.
377
- attr_reader :id
378
-
379
- # @!attribute [r] channel
380
- # @macro client_cache
381
- # @return [Discorb::Channel] The channel the message was sent in.
382
- # @!attribute [r] guild
383
- # @macro client_cache
384
- # @return [Discorb::Guild] The guild the message was sent in.
385
-
386
- #
387
- # Initialize a new instance of the UnknownDeleteBulkMessage class.
388
- # @private
389
- #
390
- # @param [Discorb::Client] client The client that instantiated the object.
391
- # @param [Hash] data The data of the event.
392
- #
393
- def initialize(client, id, data)
394
- @client = client
395
- @id = id
396
- @data = data
397
- @channel_id = Snowflake.new(data[:channel_id])
398
- @guild_id = Snowflake.new(data[:guild_id]) if data.key?(:guild_id)
399
- end
400
-
401
- def channel
402
- @client.channels[@channel_id]
403
- end
404
-
405
- def guild
406
- @client.guilds[@guild_id]
407
- end
408
- end
409
-
410
- #
411
- # Represents a `INVITE_DELETE` event.
412
- #
413
- class InviteDeleteEvent < GatewayEvent
414
- # @return [String] The invite code.
415
- attr_reader :code
416
-
417
- # @!attribute [r] channel
418
- # @macro client_cache
419
- # @return [Discorb::Channel] The channel the message was sent in.
420
- # @!attribute [r] guild
421
- # @macro client_cache
422
- # @return [Discorb::Guild] The guild the message was sent in.
423
-
424
- #
425
- # Initialize a new instance of the InviteDeleteEvent class.
426
- # @private
427
- #
428
- # @param [Discorb::Client] client The client that instantiated the object.
429
- # @param [Hash] data The data of the event.
430
- #
431
- def initialize(client, data)
432
- @client = client
433
- @data = data
434
- @channel_id = Snowflake.new(data[:channel])
435
- @guild_id = Snowflake.new(data[:guild_id])
436
- @code = data[:code]
437
- end
438
-
439
- def channel
440
- @client.channels[@channel_id]
441
- end
442
-
443
- def guild
444
- @client.guilds[@guild_id]
445
- end
446
- end
447
-
448
- #
449
- # Represents a `TYPING_START` event.
450
- #
451
- class TypingStartEvent < GatewayEvent
452
- # @return [Discorb::Snowflake] The ID of the channel the user is typing in.
453
- attr_reader :user_id
454
- # @macro client_cache
455
- # @return [Discorb::Member] The member that is typing.
456
- attr_reader :member
457
-
458
- # @!attribute [r] channel
459
- # @macro client_cache
460
- # @return [Discorb::Channel] The channel the user is typing in.
461
- # @!attribute [r] guild
462
- # @macro client_cache
463
- # @return [Discorb::Guild] The guild the user is typing in.
464
- # @!attribute [r] user
465
- # @macro client_cache
466
- # @return [Discorb::User] The user that is typing.
467
- # @!attribute [r] fired_by
468
- # @macro client_cache
469
- # @return [Discorb::Member, Discorb::User] The member or user that started typing.
470
-
471
- #
472
- # Initialize a new instance of the TypingStartEvent class.
473
- # @private
474
- #
475
- # @param [Discorb::Client] client The client that instantiated the object.
476
- # @param [Hash] data The data of the event.
477
- #
478
- def initialize(client, data)
479
- @client = client
480
- @data = data
481
- @channel_id = Snowflake.new(data[:channel_id])
482
- @guild_id = Snowflake.new(data[:guild_id]) if data.key?(:guild_id)
483
- @user_id = Snowflake.new(data[:user_id])
484
- @timestamp = Time.at(data[:timestamp])
485
- @member = guild.members[@user_id] || Member.new(@client, @guild_id, @client.users[@user_id].instance_variable_get(:@data), data[:member]) if guild
486
- end
487
-
488
- def user
489
- @client.users[@user_id]
490
- end
491
-
492
- def channel
493
- @client.channels[@channel_id]
494
- end
495
-
496
- def guild
497
- @client.guilds[@guild_id]
498
- end
499
-
500
- def fired_by
501
- @member || user
502
- end
503
-
504
- alias from fired_by
505
- end
506
-
507
- #
508
- # Represents a message pin event.
509
- #
510
- class MessagePinEvent < GatewayEvent
511
- # @return [Discorb::Message] The message that was pinned.
512
- attr_reader :message
513
- # @return [:pinned, :unpinned] The type of event.
514
- attr_reader :type
515
-
516
- # @!attribute [r] pinned?
517
- # @return [Boolean] Whether the message was pinned.
518
- # @!attribute [r] unpinned?
519
- # @return [Boolean] Whether the message was unpinned.
520
-
521
- def initialize(client, data, message)
522
- @client = client
523
- @data = data
524
- @message = message
525
- @type = if message.nil?
526
- :unknown
527
- elsif @message.pinned?
528
- :pinned
529
- else
530
- :unpinned
531
- end
532
- end
533
-
534
- def pinned?
535
- @type == :pinned
536
- end
537
-
538
- def unpinned?
539
- @type = :unpinned
540
- end
541
- end
542
-
543
- #
544
- # Represents a `WEBHOOKS_UPDATE` event.
545
- #
546
- class WebhooksUpdateEvent < GatewayEvent
547
- # @!attribute [r] channel
548
- # @macro client_cache
549
- # @return [Discorb::Channel] The channel where the webhook was updated.
550
- # @!attribute [r] guild
551
- # @macro client_cache
552
- # @return [Discorb::Guild] The guild where the webhook was updated.
553
-
554
- #
555
- # Initialize a new instance of the WebhooksUpdateEvent class.
556
- # @private
557
- #
558
- # @param [Discorb::Client] client The client that instantiated the object.
559
- # @param [Hash] data The data of the event.
560
- #
561
- def initialize(client, data)
562
- @client = client
563
- @data = data
564
- @guild_id = Snowflake.new(data[:guild_id])
565
- @channel_id = Snowflake.new(data[:channel_id])
566
- end
567
-
568
- def guild
569
- @client.guilds[@guild_id]
570
- end
571
-
572
- def channel
573
- @client.channels[@channel_id]
574
- end
575
- end
576
-
577
15
  #
578
16
  # A module to handle gateway events.
579
17
  #
580
18
  module Handler
19
+ # @type instance: Discorb::Client
20
+
581
21
  private
582
22
 
583
23
  def connect_gateway(reconnect)
@@ -594,7 +34,11 @@ module Discorb
594
34
  _, gateway_response = @http.request(Route.new("/gateway", "//gateway", :get)).wait
595
35
  gateway_url = gateway_response[:url]
596
36
  gateway_version = if @intents.to_h[:message_content].nil?
597
- warn "message_content intent not set, using gateway version 9. You should specify `message_content` intent for preventing unexpected changes in the future."
37
+ unless @message_content_intent_warned
38
+ warn "message_content intent not set, using gateway version 9. " \
39
+ "You should specify `message_content` intent for preventing unexpected changes in the future."
40
+ @message_content_intent_warned = true
41
+ end
598
42
  9
599
43
  else
600
44
  10
@@ -604,11 +48,16 @@ module Discorb
604
48
  alpn_protocols: Async::HTTP::Protocol::HTTP11.names,
605
49
  )
606
50
  begin
607
- self.connection = Async::WebSocket::Client.connect(endpoint, headers: [["User-Agent", Discorb::USER_AGENT]], handler: RawConnection)
51
+ self.connection = Async::WebSocket::Client.connect(
52
+ endpoint,
53
+ headers: [["User-Agent", Discorb::USER_AGENT]],
54
+ handler: RawConnection,
55
+ )
56
+ con = self.connection
608
57
  zlib_stream = Zlib::Inflate.new(Zlib::MAX_WBITS)
609
58
  buffer = +""
610
59
  begin
611
- while (message = connection.read)
60
+ while (message = con.read)
612
61
  buffer << message
613
62
  if message.end_with?((+"\x00\x00\xff\xff").force_encoding("ASCII-8BIT"))
614
63
  begin
@@ -632,8 +81,9 @@ module Discorb
632
81
  Errno::ECONNRESET,
633
82
  IOError => e
634
83
  next if @status == :closed
84
+
635
85
  logger.error "Gateway connection closed accidentally: #{e.class}: #{e.message}"
636
- connection.force_close
86
+ con.force_close
637
87
  connect_gateway(true)
638
88
  next
639
89
  end
@@ -644,7 +94,7 @@ module Discorb
644
94
  raise ClientError.new("Authentication failed"), cause: nil
645
95
  when 4009
646
96
  logger.info "Session timed out, reconnecting."
647
- connection.force_close
97
+ con.force_close
648
98
  connect_gateway(true)
649
99
  next
650
100
  when 4014
@@ -659,19 +109,19 @@ module Discorb
659
109
  ERROR
660
110
  when 1001
661
111
  logger.info "Gateway closed with code 1001, reconnecting."
662
- connection.force_close
112
+ con.force_close
663
113
  connect_gateway(true)
664
114
  next
665
115
  else
666
116
  logger.error "Discord WebSocket closed with code #{e.code}."
667
117
  logger.debug "#{e.message}"
668
- connection.force_close
118
+ con.force_close
669
119
  connect_gateway(false)
670
120
  next
671
121
  end
672
122
  rescue StandardError => e
673
123
  logger.error "Discord WebSocket error: #{e.full_message}"
674
- connection.force_close
124
+ con.force_close
675
125
  connect_gateway(false)
676
126
  next
677
127
  end
@@ -688,7 +138,8 @@ module Discorb
688
138
  con.write({ op: opcode, d: value }.to_json)
689
139
  con.flush
690
140
  end
691
- logger.debug "Sent message to fd #{connection.io.fileno}: #{{ op: opcode, d: value }.to_json.gsub(@token, "[Token]")}"
141
+ logger.debug "Sent message to fd #{connection.io.fileno}: #{{ op: opcode, d: value }.to_json.gsub(@token,
142
+ "[Token]")}"
692
143
  end
693
144
 
694
145
  def handle_gateway(payload, reconnect)
@@ -762,7 +213,11 @@ module Discorb
762
213
  end
763
214
 
764
215
  def handle_event(event_name, data)
765
- return logger.debug "Client isn't ready; event #{event_name} wasn't handled" if @wait_until_ready && !@ready && !%w[READY GUILD_CREATE].include?(event_name)
216
+ return logger.debug "Client isn't ready; event #{event_name} wasn't handled" if @wait_until_ready &&
217
+ !@ready &&
218
+ !%w[
219
+ READY GUILD_CREATE
220
+ ].include?(event_name)
766
221
 
767
222
  dispatch(:event_receive, event_name, data)
768
223
  logger.debug "Handling event #{event_name}"
@@ -829,7 +284,9 @@ module Discorb
829
284
  dispatch(:role_update, before, current)
830
285
  when "GUILD_ROLE_DELETE"
831
286
  return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
832
- return logger.warn "Unknown role id #{data[:role_id]}, ignoring" unless (role = guild.roles.delete(data[:role_id]))
287
+ unless (role = guild.roles.delete(data[:role_id]))
288
+ return logger.warn "Unknown role id #{data[:role_id]}, ignoring"
289
+ end
833
290
 
834
291
  dispatch(:role_delete, role)
835
292
  when "CHANNEL_CREATE"
@@ -874,18 +331,20 @@ module Discorb
874
331
  dispatch(:thread_delete, thread)
875
332
  when "THREAD_LIST_SYNC"
876
333
  data[:threads].each do |raw_thread|
877
- thread = Channel.make_channel(self, raw_thread.merge({ member: raw_thread[:members].find { |m| m[:id] == raw_thread[:id] } }))
334
+ thread = Channel.make_channel(self, raw_thread.merge({ member: raw_thread[:members].find do |m|
335
+ m[:id] == raw_thread[:id]
336
+ end }))
878
337
  @channels[thread.id] = thread
879
338
  end
880
339
  when "THREAD_MEMBER_UPDATE"
881
340
  return logger.warn "Unknown thread id #{data[:id]}, ignoring" unless (thread = @channels[data[:id]])
882
341
 
883
342
  if (member = thread.members[data[:id]])
884
- old = ThreadChannel::Member.new(self, member.instance_variable_get(:@data))
343
+ old = ThreadChannel::Member.new(self, member.instance_variable_get(:@data), data[:guild_id])
885
344
  member.send(:_set_data, data)
886
345
  else
887
346
  old = nil
888
- member = ThreadChannel::Member.new(self, data)
347
+ member = ThreadChannel::Member.new(self, data, data[:guild_id])
889
348
  thread.members[data[:user_id]] = member
890
349
  end
891
350
  dispatch(:thread_member_update, thread, old, member)
@@ -895,7 +354,7 @@ module Discorb
895
354
  thread.instance_variable_set(:@member_count, data[:member_count])
896
355
  members = []
897
356
  (data[:added_members] || []).each do |raw_member|
898
- member = ThreadChannel::Member.new(self, raw_member)
357
+ member = ThreadChannel::Member.new(self, raw_member, data[:guild_id])
899
358
  thread.members[member.id] = member
900
359
  members << member
901
360
  end
@@ -908,15 +367,23 @@ module Discorb
908
367
  instance = StageInstance.new(self, data)
909
368
  dispatch(:stage_instance_create, instance)
910
369
  when "STAGE_INSTANCE_UPDATE"
911
- return logger.warn "Unknown channel id #{data[:channel_id]} , ignoring" unless (channel = @channels[data[:channel_id]])
912
- return logger.warn "Unknown stage instance id #{data[:id]}, ignoring" unless (instance = channel.stage_instances[data[:id]])
370
+ unless (channel = @channels[data[:channel_id]])
371
+ return logger.warn "Unknown channel id #{data[:channel_id]} , ignoring"
372
+ end
373
+ unless (instance = channel.stage_instances[data[:id]])
374
+ return logger.warn "Unknown stage instance id #{data[:id]}, ignoring"
375
+ end
913
376
 
914
377
  old = StageInstance.new(self, instance.instance_variable_get(:@data), no_cache: true)
915
378
  current.send(:_set_data, data)
916
379
  dispatch(:stage_instance_update, old, current)
917
380
  when "STAGE_INSTANCE_DELETE"
918
- return logger.warn "Unknown channel id #{data[:channel_id]} , ignoring" unless (channel = @channels[data[:channel_id]])
919
- return logger.warn "Unknown stage instance id #{data[:id]}, ignoring" unless (instance = channel.stage_instances.delete(data[:id]))
381
+ unless (channel = @channels[data[:channel_id]])
382
+ return logger.warn "Unknown channel id #{data[:channel_id]} , ignoring"
383
+ end
384
+ unless (instance = channel.stage_instances.delete(data[:id]))
385
+ return logger.warn "Unknown stage instance id #{data[:id]}, ignoring"
386
+ end
920
387
 
921
388
  dispatch(:stage_instance_delete, instance)
922
389
  when "GUILD_MEMBER_ADD"
@@ -927,14 +394,18 @@ module Discorb
927
394
  dispatch(:member_add, nm)
928
395
  when "GUILD_MEMBER_UPDATE"
929
396
  return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
930
- return logger.warn "Unknown member id #{data[:user][:id]}, ignoring" unless (nm = guild.members[data[:user][:id]])
397
+ unless (nm = guild.members[data[:user][:id]])
398
+ return logger.warn "Unknown member id #{data[:user][:id]}, ignoring"
399
+ end
931
400
 
932
401
  old = Member.new(self, data[:guild_id], data[:user], data.update({ no_cache: true }))
933
402
  nm.send(:_set_data, data[:user], data)
934
403
  dispatch(:member_update, old, nm)
935
404
  when "GUILD_MEMBER_REMOVE"
936
405
  return logger.warn "Unknown guild id #{data[:guild_id]}, ignoring" unless (guild = @guilds[data[:guild_id]])
937
- return logger.warn "Unknown member id #{data[:user][:id]}, ignoring" unless (member = guild.members.delete(data[:user][:id]))
406
+ unless (member = guild.members.delete(data[:user][:id]))
407
+ return logger.warn "Unknown member id #{data[:user][:id]}, ignoring"
408
+ end
938
409
 
939
410
  dispatch(:member_remove, member)
940
411
  when "GUILD_BAN_ADD"
@@ -1111,7 +582,8 @@ module Discorb
1111
582
  when "MESSAGE_DELETE"
1112
583
  message.instance_variable_set(:@deleted, true) if (message = @messages[data[:id]])
1113
584
 
1114
- dispatch(:message_delete_id, Snowflake.new(data[:id]), channels[data[:channel_id]], data[:guild_id] && guilds[data[:guild_id]])
585
+ dispatch(:message_delete_id, Snowflake.new(data[:id]), channels[data[:channel_id]],
586
+ data[:guild_id] && guilds[data[:guild_id]])
1115
587
  dispatch(:message_delete, message, channels[data[:channel_id]], data[:guild_id] && guilds[data[:guild_id]])
1116
588
  when "MESSAGE_DELETE_BULK"
1117
589
  messages = []
@@ -1132,7 +604,7 @@ module Discorb
1132
604
  target_reaction.instance_variable_set(:@count, target_reaction.count + 1)
1133
605
  else
1134
606
  target_message.reactions << Reaction.new(
1135
- self,
607
+ target_message,
1136
608
  {
1137
609
  count: 1,
1138
610
  me: @user.id == data[:user_id],
@@ -1158,7 +630,9 @@ module Discorb
1158
630
  dispatch(:reaction_remove_all, ReactionRemoveAllEvent.new(self, data))
1159
631
  when "MESSAGE_REACTION_REMOVE_EMOJI"
1160
632
  if (target_message = @messages[data[:message_id]]) &&
1161
- (target_reaction = target_message.reactions.find { |r| data[:emoji][:id].nil? ? r.name == data[:emoji][:name] : r.id == data[:emoji][:id] })
633
+ (target_reaction = target_message.reactions.find do |r|
634
+ data[:emoji][:id].nil? ? r.name == data[:emoji][:name] : r.id == data[:emoji][:id]
635
+ end)
1162
636
  target_message.reactions.delete(target_reaction)
1163
637
  end
1164
638
  dispatch(:reaction_remove_emoji, ReactionRemoveEmojiEvent.new(self, data))
@@ -1184,7 +658,9 @@ module Discorb
1184
658
  dispatch(:scheduled_event_create, event)
1185
659
  when "GUILD_SCHEDULED_EVENT_UPDATE"
1186
660
  logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1187
- logger.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
661
+ unless (event = guild.scheduled_events[data[:id]])
662
+ logger.warn("Unknown scheduled event id #{data[:id]}, ignoring")
663
+ end
1188
664
  old = event.dup
1189
665
  event.send(:_set_data, data)
1190
666
  dispatch(:scheduled_event_update, old, event)
@@ -1200,7 +676,9 @@ module Discorb
1200
676
  end
1201
677
  when "GUILD_SCHEDULED_EVENT_DELETE"
1202
678
  logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1203
- logger.warn("Unknown scheduled event id #{data[:id]}, ignoring") unless (event = guild.scheduled_events[data[:id]])
679
+ unless (event = guild.scheduled_events[data[:id]])
680
+ logger.warn("Unknown scheduled event id #{data[:id]}, ignoring")
681
+ end
1204
682
  guild.scheduled_events.remove(data[:id])
1205
683
  dispatch(:scheduled_event_delete, event)
1206
684
  dispatch(:scheduled_event_cancel, event)
@@ -1210,6 +688,14 @@ module Discorb
1210
688
  when "GUILD_SCHEDULED_EVENT_USER_REMOVE"
1211
689
  logger.warn("Unknown guild id #{data[:guild_id]}, ignoring") unless (guild = @guilds[data[:guild_id]])
1212
690
  dispatch(:scheduled_event_user_remove, ScheduledEventUserEvent.new(self, data))
691
+ when "AUTO_MODERATION_ACTION_EXECUTION"
692
+ dispatch(:auto_moderation_action_execution, AutoModerationActionExecutionEvent.new(self, data))
693
+ when "AUTO_MODERATION_RULE_CREATE"
694
+ dispatch(:auto_moderation_rule_create, AutoModRule.new(self, data))
695
+ when "AUTO_MODERATION_RULE_UPDATE"
696
+ dispatch(:auto_moderation_rule_update, AutoModRule.new(self, data))
697
+ when "AUTO_MODERATION_RULE_DELETE"
698
+ dispatch(:auto_moderation_rule_delete, AutoModRule.new(self, data))
1213
699
  else
1214
700
  if respond_to?("event_" + event_name.downcase)
1215
701
  __send__("event_" + event_name.downcase, data)
@@ -1287,7 +773,11 @@ module Discorb
1287
773
  end
1288
774
 
1289
775
  def io
1290
- @framer.instance_variable_get(:@stream).instance_variable_get(:@io).instance_variable_get(:@io).instance_variable_get(:@io)
776
+ @framer
777
+ .instance_variable_get(:@stream)
778
+ .instance_variable_get(:@io)
779
+ .instance_variable_get(:@io)
780
+ .instance_variable_get(:@io)
1291
781
  end
1292
782
 
1293
783
  def parse(buffer)