discorb 0.19.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
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