discorb 0.16.0 → 0.18.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 (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)