discorb 0.19.0 → 0.20.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +2 -2
  3. data/.rubocop.yml +12 -75
  4. data/Changelog.md +10 -0
  5. data/Rakefile +482 -454
  6. data/lib/discorb/allowed_mentions.rb +68 -72
  7. data/lib/discorb/app_command/command.rb +466 -398
  8. data/lib/discorb/app_command/common.rb +65 -25
  9. data/lib/discorb/app_command/handler.rb +304 -266
  10. data/lib/discorb/app_command.rb +5 -5
  11. data/lib/discorb/application.rb +198 -197
  12. data/lib/discorb/asset.rb +101 -101
  13. data/lib/discorb/attachment.rb +134 -119
  14. data/lib/discorb/audit_logs.rb +412 -385
  15. data/lib/discorb/automod.rb +279 -269
  16. data/lib/discorb/channel/base.rb +107 -108
  17. data/lib/discorb/channel/category.rb +32 -32
  18. data/lib/discorb/channel/container.rb +44 -44
  19. data/lib/discorb/channel/dm.rb +26 -28
  20. data/lib/discorb/channel/guild.rb +311 -246
  21. data/lib/discorb/channel/stage.rb +156 -140
  22. data/lib/discorb/channel/text.rb +430 -336
  23. data/lib/discorb/channel/thread.rb +374 -325
  24. data/lib/discorb/channel/voice.rb +85 -79
  25. data/lib/discorb/channel.rb +5 -5
  26. data/lib/discorb/client.rb +635 -621
  27. data/lib/discorb/color.rb +178 -182
  28. data/lib/discorb/common.rb +168 -164
  29. data/lib/discorb/components/button.rb +107 -106
  30. data/lib/discorb/components/select_menu.rb +157 -145
  31. data/lib/discorb/components/text_input.rb +103 -106
  32. data/lib/discorb/components.rb +68 -66
  33. data/lib/discorb/dictionary.rb +135 -135
  34. data/lib/discorb/embed.rb +404 -398
  35. data/lib/discorb/emoji.rb +309 -302
  36. data/lib/discorb/emoji_table.rb +16099 -8857
  37. data/lib/discorb/error.rb +131 -131
  38. data/lib/discorb/event.rb +360 -314
  39. data/lib/discorb/event_handler.rb +39 -39
  40. data/lib/discorb/exe/about.rb +17 -17
  41. data/lib/discorb/exe/irb.rb +72 -67
  42. data/lib/discorb/exe/new.rb +323 -315
  43. data/lib/discorb/exe/run.rb +69 -68
  44. data/lib/discorb/exe/setup.rb +57 -55
  45. data/lib/discorb/exe/show.rb +12 -12
  46. data/lib/discorb/extend.rb +25 -45
  47. data/lib/discorb/extension.rb +89 -83
  48. data/lib/discorb/flag.rb +126 -128
  49. data/lib/discorb/gateway.rb +984 -804
  50. data/lib/discorb/gateway_events.rb +670 -638
  51. data/lib/discorb/gateway_requests.rb +45 -48
  52. data/lib/discorb/guild.rb +2115 -1626
  53. data/lib/discorb/guild_template.rb +280 -241
  54. data/lib/discorb/http.rb +247 -232
  55. data/lib/discorb/image.rb +42 -42
  56. data/lib/discorb/integration.rb +169 -161
  57. data/lib/discorb/intents.rb +161 -163
  58. data/lib/discorb/interaction/autocomplete.rb +76 -62
  59. data/lib/discorb/interaction/command.rb +279 -224
  60. data/lib/discorb/interaction/components.rb +114 -104
  61. data/lib/discorb/interaction/modal.rb +36 -32
  62. data/lib/discorb/interaction/response.rb +379 -336
  63. data/lib/discorb/interaction/root.rb +271 -257
  64. data/lib/discorb/interaction.rb +5 -5
  65. data/lib/discorb/invite.rb +154 -153
  66. data/lib/discorb/member.rb +344 -311
  67. data/lib/discorb/message.rb +615 -544
  68. data/lib/discorb/message_meta.rb +197 -186
  69. data/lib/discorb/modules.rb +371 -290
  70. data/lib/discorb/permission.rb +305 -291
  71. data/lib/discorb/presence.rb +352 -346
  72. data/lib/discorb/rate_limit.rb +81 -76
  73. data/lib/discorb/reaction.rb +55 -54
  74. data/lib/discorb/role.rb +272 -240
  75. data/lib/discorb/shard.rb +76 -74
  76. data/lib/discorb/sticker.rb +193 -171
  77. data/lib/discorb/user.rb +205 -188
  78. data/lib/discorb/utils/colored_puts.rb +16 -16
  79. data/lib/discorb/utils.rb +12 -16
  80. data/lib/discorb/voice_state.rb +305 -281
  81. data/lib/discorb/webhook.rb +537 -507
  82. data/lib/discorb.rb +62 -56
  83. data/sig/discorb/application.rbs +2 -0
  84. data/sig/discorb/automod.rbs +10 -1
  85. data/sig/discorb/guild.rbs +2 -0
  86. data/sig/discorb/message.rbs +2 -0
  87. data/sig/discorb/user.rbs +22 -20
  88. metadata +2 -2
@@ -1,62 +1,76 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents auto complete interaction.
6
- #
7
- class AutoComplete < Interaction
8
- @interaction_type = 4
9
- @interaction_name = :auto_complete
10
-
11
- private
12
-
13
- def _set_data(data)
14
- super
15
- Sync do
16
- name, options = Discorb::CommandInteraction::ChatInputCommand.get_command_data(data)
17
-
18
- unless (command = @client.callable_commands.find { |c| c.to_s == name && c.type_raw == 1 })
19
- @client.logger.warn "Unknown command name #{name}, ignoring"
20
- next
21
- end
22
-
23
- option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
24
- Discorb::CommandInteraction::ChatInputCommand.modify_option_map(option_map, options, guild, {}, {})
25
- focused_index = options.find_index { |o| o[:focused] }
26
- val = command.options.values.filter do |option|
27
- option[:type] != :attachment
28
- end[focused_index][:autocomplete]&.call(self, *command.options.map do |k, _v|
29
- option_map[k.to_s]
30
- end)
31
- send_complete_result(val)
32
- end
33
- end
34
-
35
- def send_complete_result(val)
36
- @client.http.request(
37
- Route.new(
38
- "/interactions/#{@id}/#{@token}/callback",
39
- "//interactions/:interaction_id/:token/callback",
40
- :post
41
- ), {
42
- type: 8,
43
- data: {
44
- choices: val.map do |vk, vv|
45
- {
46
- name: vk,
47
- value: vv,
48
- }
49
- end,
50
- },
51
- }
52
- ).wait
53
- rescue Discorb::NotFoundError
54
- @client.logger.warn "Failed to send auto complete result, " \
55
- "This may be caused by the suggestion is taking too long (over 3 seconds) to respond"
56
- end
57
-
58
- class << self
59
- alias make_interaction new
60
- end
61
- end
62
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents auto complete interaction.
6
+ #
7
+ class AutoComplete < Interaction
8
+ @interaction_type = 4
9
+ @interaction_name = :auto_complete
10
+
11
+ private
12
+
13
+ def _set_data(data)
14
+ super
15
+ Sync do
16
+ name, options =
17
+ Discorb::CommandInteraction::ChatInputCommand.get_command_data(data)
18
+
19
+ unless (
20
+ command =
21
+ @client.callable_commands.find do |c|
22
+ c.to_s == name && c.type_raw == 1
23
+ end
24
+ )
25
+ @client.logger.warn "Unknown command name #{name}, ignoring"
26
+ next
27
+ end
28
+
29
+ option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
30
+ Discorb::CommandInteraction::ChatInputCommand.modify_option_map(
31
+ option_map,
32
+ options,
33
+ guild,
34
+ {},
35
+ {}
36
+ )
37
+ focused_index = options.find_index { |o| o[:focused] }
38
+ val =
39
+ command.options.values.filter do |option|
40
+ option[:type] != :attachment
41
+ end[
42
+ focused_index
43
+ ][
44
+ :autocomplete
45
+ ]&.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
46
+ send_complete_result(val)
47
+ end
48
+ end
49
+
50
+ def send_complete_result(val)
51
+ @client
52
+ .http
53
+ .request(
54
+ Route.new(
55
+ "/interactions/#{@id}/#{@token}/callback",
56
+ "//interactions/:interaction_id/:token/callback",
57
+ :post
58
+ ),
59
+ {
60
+ type: 8,
61
+ data: {
62
+ choices: val.map { |vk, vv| { name: vk, value: vv } }
63
+ }
64
+ }
65
+ )
66
+ .wait
67
+ rescue Discorb::NotFoundError
68
+ @client.logger.warn "Failed to send auto complete result, " \
69
+ "This may be caused by the suggestion is taking too long (over 3 seconds) to respond"
70
+ end
71
+
72
+ class << self
73
+ alias make_interaction new
74
+ end
75
+ end
76
+ end
@@ -1,224 +1,279 @@
1
- # frozen_string_literal: true
2
-
3
- module Discorb
4
- #
5
- # Represents a command interaction.
6
- #
7
- class CommandInteraction < Interaction
8
- @interaction_type = 2
9
- @interaction_name = :application_command
10
- include Interaction::SourceResponder
11
- include Interaction::ModalResponder
12
-
13
- #
14
- # Represents a slash command interaction.
15
- #
16
- class ChatInputCommand < CommandInteraction
17
- @command_type = 1
18
- @event_name = :slash_command
19
-
20
- private
21
-
22
- def _set_data(data)
23
- super
24
-
25
- name, options = ChatInputCommand.get_command_data(data)
26
-
27
- unless (command = @client.callable_commands.find { |c| c.to_s == name && c.type_raw == 1 })
28
- @client.logger.warn "Unknown command name #{name}, ignoring"
29
- return
30
- end
31
-
32
- option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
33
- ChatInputCommand.modify_option_map(option_map, options, guild, @members, @attachments)
34
-
35
- command.block.call(self, *command.options.map { |k, _v| option_map[k.to_s] })
36
- end
37
-
38
- class << self
39
- #
40
- # Get command data from the given data.
41
- # @private
42
- #
43
- # @param [Hash] data The data of the command.
44
- #
45
- def get_command_data(data)
46
- name = data[:name]
47
- options = nil
48
- return name, options unless (option = data[:options]&.first)
49
-
50
- case option[:type]
51
- when 1
52
- name += " #{option[:name]}"
53
- options = option[:options]
54
- when 2
55
- name += " #{option[:name]}"
56
- unless option[:options]&.first&.[](:type) == 1
57
- options = option[:options]
58
- return name, options
59
- end
60
- option_sub = option[:options]&.first
61
- name += " #{option_sub[:name]}"
62
- options = option_sub[:options]
63
- else
64
- options = data[:options]
65
- end
66
-
67
- [name, options]
68
- end
69
-
70
- #
71
- # Modify the option map with the given options.
72
- # @private
73
- #
74
- # @param [Hash] option_map The option map to modify.
75
- # @param [Array<Hash>] options The options for modifying.
76
- # @param [Discorb::Guild] guild The guild where the command is executed.
77
- # @param [{Discorb::Snowflake => Discorb::Member}] members The cached members of the guild.
78
- # @param [{Integer => Discorb::Attachment}] attachments The cached attachments of the message.
79
- def modify_option_map(option_map, options, guild, members, attachments)
80
- options ||= []
81
- options.each do |option|
82
- val = case option[:type]
83
- when 3, 4, 5, 10
84
- option[:value]
85
- when 6
86
- members[option[:value]] || guild && (guild.members[option[:value]] ||
87
- guild.fetch_member(option[:value]).wait)
88
- when 7
89
- if guild
90
- guild.channels[option[:value]] || guild.fetch_channels.wait.find do |channel|
91
- channel.id == option[:value]
92
- end
93
- end
94
- when 8
95
- guild && (guild.roles[option[:value]] ||
96
- guild.fetch_roles.wait.find { |role| role.id == option[:value] })
97
- when 9
98
- members[option[:value]] ||
99
- guild && (guild.members[option[:value]] ||
100
- guild.roles[option[:value]] ||
101
- guild.fetch_member(option[:value]).wait ||
102
- guild.fetch_roles.wait.find do |role|
103
- role.id == option[:value]
104
- end)
105
- when 11
106
- attachments[option[:value]]
107
- end
108
- option_map[option[:name]] = val
109
- end
110
- end
111
- end
112
- end
113
-
114
- #
115
- # Represents a user context menu interaction.
116
- #
117
- class UserMenuCommand < CommandInteraction
118
- @command_type = 2
119
- @event_name = :user_command
120
-
121
- # @return [Discorb::Member, Discorb::User] The target user.
122
- attr_reader :target
123
-
124
- private
125
-
126
- def _set_data(data)
127
- super
128
- @target = guild.members[data[:target_id]] || Discorb::Member.new(
129
- @client, @guild_id,
130
- data[:resolved][:users][data[:target_id].to_sym],
131
- data[:resolved][:members][data[:target_id].to_sym]
132
- )
133
- command = @client.commands.find { |c| c.name["default"] == data[:name] && c.type_raw == 2 }
134
- if command
135
- command.block.call(self, @target)
136
- else
137
- @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
138
- end
139
- end
140
- end
141
-
142
- #
143
- # Represents a message context menu interaction.
144
- #
145
- class MessageMenuCommand < CommandInteraction
146
- @command_type = 3
147
- @event_name = :message_command
148
-
149
- # @return [Discorb::Message] The target message.
150
- attr_reader :target
151
-
152
- private
153
-
154
- def _set_data(data)
155
- super
156
- @target = @messages[data[:target_id]]
157
- command = @client.commands.find { |c| c.name["default"] == data[:name] && c.type_raw == 3 }
158
- if command
159
- command.block.call(self, @target)
160
- else
161
- @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
162
- end
163
- end
164
- end
165
-
166
- private
167
-
168
- def _set_data(data)
169
- super
170
- @name = data[:name]
171
- @messages, @attachments, @members = {}, {}, {}
172
-
173
- if data[:resolved]
174
- data[:resolved][:users]&.each do |id, user|
175
- @client.users[id] = Discorb::User.new(@client, user)
176
- end
177
- data[:resolved][:members]&.each do |id, member|
178
- @members[id] = Discorb::Member.new(
179
- @client, @guild_id, data[:resolved][:users][id], member
180
- )
181
- end
182
-
183
- data[:resolved][:messages]&.each do |id, message|
184
- @messages[id.to_s] = Message.new(@client, message.merge(guild_id: @guild_id.to_s))
185
- end
186
- data[:resolved][:attachments]&.each do |id, attachment|
187
- @attachments[id.to_s] = Attachment.new(attachment)
188
- end
189
- end
190
- end
191
-
192
- class << self
193
- # @private
194
- attr_reader :command_type, :event_name
195
-
196
- #
197
- # Creates a new CommandInteraction instance for the given data.
198
- # @private
199
- #
200
- # @param [Discorb::Client] client The client.
201
- # @param [Hash] data The data for the command.
202
- #
203
- def make_interaction(client, data)
204
- nested_classes.each do |klass|
205
- if !klass.command_type.nil? && klass.command_type == data[:data][:type]
206
- interaction = klass.new(client, data)
207
- client.dispatch(klass.event_name, interaction)
208
- return interaction
209
- end
210
- end
211
- client.logger.warn("Unknown command type #{data[:type]}, initialized CommandInteraction")
212
- CommandInteraction.new(client, data)
213
- end
214
-
215
- #
216
- # Returns the classes under this class.
217
- # @private
218
- #
219
- def nested_classes
220
- constants.select { |c| const_get(c).is_a? Class }.map { |c| const_get(c) }
221
- end
222
- end
223
- end
224
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a command interaction.
6
+ #
7
+ class CommandInteraction < Interaction
8
+ @interaction_type = 2
9
+ @interaction_name = :application_command
10
+ include Interaction::SourceResponder
11
+ include Interaction::ModalResponder
12
+
13
+ #
14
+ # Represents a slash command interaction.
15
+ #
16
+ class ChatInputCommand < CommandInteraction
17
+ @command_type = 1
18
+ @event_name = :slash_command
19
+
20
+ private
21
+
22
+ def _set_data(data)
23
+ super
24
+
25
+ name, options = ChatInputCommand.get_command_data(data)
26
+
27
+ unless (
28
+ command =
29
+ @client.callable_commands.find do |c|
30
+ c.to_s == name && c.type_raw == 1
31
+ end
32
+ )
33
+ @client.logger.warn "Unknown command name #{name}, ignoring"
34
+ return
35
+ end
36
+
37
+ option_map = command.options.to_h { |k, v| [k.to_s, v[:default]] }
38
+ ChatInputCommand.modify_option_map(
39
+ option_map,
40
+ options,
41
+ guild,
42
+ @members,
43
+ @attachments
44
+ )
45
+
46
+ command.block.call(
47
+ self,
48
+ *command.options.map { |k, _v| option_map[k.to_s] }
49
+ )
50
+ end
51
+
52
+ class << self
53
+ #
54
+ # Get command data from the given data.
55
+ # @private
56
+ #
57
+ # @param [Hash] data The data of the command.
58
+ #
59
+ def get_command_data(data)
60
+ name = data[:name]
61
+ options = nil
62
+ return name, options unless (option = data[:options]&.first)
63
+
64
+ case option[:type]
65
+ when 1
66
+ name += " #{option[:name]}"
67
+ options = option[:options]
68
+ when 2
69
+ name += " #{option[:name]}"
70
+ unless option[:options]&.first&.[](:type) == 1
71
+ options = option[:options]
72
+ return name, options
73
+ end
74
+ option_sub = option[:options]&.first
75
+ name += " #{option_sub[:name]}"
76
+ options = option_sub[:options]
77
+ else
78
+ options = data[:options]
79
+ end
80
+
81
+ [name, options]
82
+ end
83
+
84
+ #
85
+ # Modify the option map with the given options.
86
+ # @private
87
+ #
88
+ # @param [Hash] option_map The option map to modify.
89
+ # @param [Array<Hash>] options The options for modifying.
90
+ # @param [Discorb::Guild] guild The guild where the command is executed.
91
+ # @param [{Discorb::Snowflake => Discorb::Member}] members The cached members of the guild.
92
+ # @param [{Integer => Discorb::Attachment}] attachments The cached attachments of the message.
93
+ def modify_option_map(option_map, options, guild, members, attachments)
94
+ options ||= []
95
+ options.each do |option|
96
+ val =
97
+ case option[:type]
98
+ when 3, 4, 5, 10
99
+ option[:value]
100
+ when 6
101
+ members[option[:value]] ||
102
+ (
103
+ guild &&
104
+ (
105
+ guild.members[option[:value]] ||
106
+ guild.fetch_member(option[:value]).wait
107
+ )
108
+ )
109
+ when 7
110
+ if guild
111
+ guild.channels[option[:value]] ||
112
+ guild.fetch_channels.wait.find do |channel|
113
+ channel.id == option[:value]
114
+ end
115
+ end
116
+ when 8
117
+ guild &&
118
+ (
119
+ guild.roles[option[:value]] ||
120
+ guild.fetch_roles.wait.find do |role|
121
+ role.id == option[:value]
122
+ end
123
+ )
124
+ when 9
125
+ members[option[:value]] ||
126
+ (
127
+ guild &&
128
+ (
129
+ guild.members[option[:value]] ||
130
+ guild.roles[option[:value]] ||
131
+ guild.fetch_member(option[:value]).wait ||
132
+ guild.fetch_roles.wait.find do |role|
133
+ role.id == option[:value]
134
+ end
135
+ )
136
+ )
137
+ when 11
138
+ attachments[option[:value]]
139
+ end
140
+ option_map[option[:name]] = val
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ #
147
+ # Represents a user context menu interaction.
148
+ #
149
+ class UserMenuCommand < CommandInteraction
150
+ @command_type = 2
151
+ @event_name = :user_command
152
+
153
+ # @return [Discorb::Member, Discorb::User] The target user.
154
+ attr_reader :target
155
+
156
+ private
157
+
158
+ def _set_data(data)
159
+ super
160
+ @target =
161
+ guild.members[data[:target_id]] ||
162
+ Discorb::Member.new(
163
+ @client,
164
+ @guild_id,
165
+ data[:resolved][:users][data[:target_id].to_sym],
166
+ data[:resolved][:members][data[:target_id].to_sym]
167
+ )
168
+ command =
169
+ @client.commands.find do |c|
170
+ c.name["default"] == data[:name] && c.type_raw == 2
171
+ end
172
+ if command
173
+ command.block.call(self, @target)
174
+ else
175
+ @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
176
+ end
177
+ end
178
+ end
179
+
180
+ #
181
+ # Represents a message context menu interaction.
182
+ #
183
+ class MessageMenuCommand < CommandInteraction
184
+ @command_type = 3
185
+ @event_name = :message_command
186
+
187
+ # @return [Discorb::Message] The target message.
188
+ attr_reader :target
189
+
190
+ private
191
+
192
+ def _set_data(data)
193
+ super
194
+ @target = @messages[data[:target_id]]
195
+ command =
196
+ @client.commands.find do |c|
197
+ c.name["default"] == data[:name] && c.type_raw == 3
198
+ end
199
+ if command
200
+ command.block.call(self, @target)
201
+ else
202
+ @client.logger.warn "Unknown command name #{data[:name]}, ignoring"
203
+ end
204
+ end
205
+ end
206
+
207
+ private
208
+
209
+ def _set_data(data)
210
+ super
211
+ @name = data[:name]
212
+ @messages = {}
213
+ @attachments = {}
214
+ @members = {}
215
+
216
+ if data[:resolved]
217
+ data[:resolved][:users]&.each do |id, user|
218
+ @client.users[id] = Discorb::User.new(@client, user)
219
+ end
220
+ data[:resolved][:members]&.each do |id, member|
221
+ @members[id] = Discorb::Member.new(
222
+ @client,
223
+ @guild_id,
224
+ data[:resolved][:users][id],
225
+ member
226
+ )
227
+ end
228
+
229
+ data[:resolved][:messages]&.each do |id, message|
230
+ @messages[id.to_s] = Message.new(
231
+ @client,
232
+ message.merge(guild_id: @guild_id.to_s)
233
+ )
234
+ end
235
+ data[:resolved][:attachments]&.each do |id, attachment|
236
+ @attachments[id.to_s] = Attachment.new(attachment)
237
+ end
238
+ end
239
+ end
240
+
241
+ class << self
242
+ # @private
243
+ attr_reader :command_type, :event_name
244
+
245
+ #
246
+ # Creates a new CommandInteraction instance for the given data.
247
+ # @private
248
+ #
249
+ # @param [Discorb::Client] client The client.
250
+ # @param [Hash] data The data for the command.
251
+ #
252
+ def make_interaction(client, data)
253
+ nested_classes.each do |klass|
254
+ unless !klass.command_type.nil? &&
255
+ klass.command_type == data[:data][:type]
256
+ next
257
+ end
258
+ interaction = klass.new(client, data)
259
+ client.dispatch(klass.event_name, interaction)
260
+ return interaction
261
+ end
262
+ client.logger.warn(
263
+ "Unknown command type #{data[:type]}, initialized CommandInteraction"
264
+ )
265
+ CommandInteraction.new(client, data)
266
+ end
267
+
268
+ #
269
+ # Returns the classes under this class.
270
+ # @private
271
+ #
272
+ def nested_classes
273
+ constants
274
+ .select { |c| const_get(c).is_a? Class }
275
+ .map { |c| const_get(c) }
276
+ end
277
+ end
278
+ end
279
+ end