discorb 0.14.0 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build_version.yml +1 -1
- data/.github/workflows/lint-push.yml +4 -2
- data/.rubocop.yml +6 -2
- data/Changelog.md +27 -0
- data/Rakefile +6 -0
- data/docs/events.md +71 -5
- data/docs/faq.md +8 -8
- data/examples/simple/rolepanel.rb +1 -1
- data/examples/simple/shard.rb +17 -0
- data/lib/discorb/allowed_mentions.rb +7 -0
- data/lib/discorb/app_command/command.rb +64 -2
- data/lib/discorb/app_command/handler.rb +1 -1
- data/lib/discorb/application.rb +16 -7
- data/lib/discorb/asset.rb +9 -0
- data/lib/discorb/{file.rb → attachment.rb} +55 -33
- data/lib/discorb/audit_logs.rb +42 -4
- data/lib/discorb/channel.rb +47 -12
- data/lib/discorb/client.rb +135 -51
- data/lib/discorb/common.rb +18 -4
- data/lib/discorb/components/button.rb +5 -6
- data/lib/discorb/components/select_menu.rb +2 -16
- data/lib/discorb/dictionary.rb +2 -0
- data/lib/discorb/embed.rb +71 -38
- data/lib/discorb/emoji.rb +29 -2
- data/lib/discorb/emoji_table.rb +1 -1
- data/lib/discorb/error.rb +7 -1
- data/lib/discorb/event.rb +27 -17
- data/lib/discorb/exe/new.rb +5 -5
- data/lib/discorb/exe/run.rb +1 -15
- data/lib/discorb/gateway.rb +262 -161
- data/lib/discorb/gateway_requests.rb +4 -7
- data/lib/discorb/guild.rb +67 -33
- data/lib/discorb/guild_template.rb +24 -3
- data/lib/discorb/http.rb +25 -3
- data/lib/discorb/integration.rb +23 -8
- data/lib/discorb/intents.rb +15 -10
- data/lib/discorb/interaction/autocomplete.rb +4 -4
- data/lib/discorb/interaction/command.rb +34 -5
- data/lib/discorb/interaction/components.rb +15 -2
- data/lib/discorb/interaction/response.rb +12 -0
- data/lib/discorb/interaction/root.rb +16 -1
- data/lib/discorb/invite.rb +11 -7
- data/lib/discorb/member.rb +21 -0
- data/lib/discorb/message.rb +59 -3
- data/lib/discorb/message_meta.rb +36 -55
- data/lib/discorb/modules.rb +38 -14
- data/lib/discorb/permission.rb +14 -5
- data/lib/discorb/presence.rb +41 -8
- data/lib/discorb/rate_limit.rb +7 -2
- data/lib/discorb/reaction.rb +6 -0
- data/lib/discorb/role.rb +12 -0
- data/lib/discorb/shard.rb +74 -0
- data/lib/discorb/sticker.rb +22 -14
- data/lib/discorb/user.rb +11 -0
- data/lib/discorb/voice_state.rb +20 -2
- data/lib/discorb/webhook.rb +53 -2
- data/lib/discorb.rb +5 -3
- data/sig/discorb.rbs +7234 -6714
- metadata +5 -4
- data/lib/discorb/log.rb +0 -81
@@ -5,7 +5,9 @@ module Discorb
|
|
5
5
|
# Represents an activity for Gateway Command.
|
6
6
|
#
|
7
7
|
class Activity
|
8
|
-
@
|
8
|
+
# @private
|
9
|
+
# @return [{Symbol => Integer}] The mapping of activity types.
|
10
|
+
TYPES = {
|
9
11
|
playing: 0,
|
10
12
|
streaming: 1,
|
11
13
|
listening: 2,
|
@@ -22,7 +24,7 @@ module Discorb
|
|
22
24
|
#
|
23
25
|
def initialize(name, type = :playing, url = nil)
|
24
26
|
@name = name
|
25
|
-
@type =
|
27
|
+
@type = TYPES[type] or raise ArgumentError, "Invalid activity type: #{type}"
|
26
28
|
@url = url
|
27
29
|
end
|
28
30
|
|
@@ -42,10 +44,5 @@ module Discorb
|
|
42
44
|
def inspect
|
43
45
|
"#<#{self.class} @type=#{@type}>"
|
44
46
|
end
|
45
|
-
|
46
|
-
class << self
|
47
|
-
# @private
|
48
|
-
attr_reader :types
|
49
|
-
end
|
50
47
|
end
|
51
48
|
end
|
data/lib/discorb/guild.rb
CHANGED
@@ -115,27 +115,36 @@ module Discorb
|
|
115
115
|
# @!attribute [r] me
|
116
116
|
# @return [Discorb::Member] The client's member in the guild.
|
117
117
|
|
118
|
-
@
|
119
|
-
@
|
120
|
-
|
121
|
-
@
|
122
|
-
@
|
118
|
+
# @private
|
119
|
+
# @return [Array<Symbol>] The mapping of mfa_level.
|
120
|
+
MFA_LEVELS = %i[none elevated].freeze
|
121
|
+
# @private
|
122
|
+
# @return [Array<Symbol>] The mapping of nsfw_level.
|
123
|
+
NSFW_LEVELS = %i[default explicit safe age_restricted].freeze
|
124
|
+
# @private
|
125
|
+
# @return [Array<Symbol>] The mapping of verification_level.
|
126
|
+
VERIFICATION_LEVELS = %i[none low medium high very_high].freeze
|
127
|
+
# @private
|
128
|
+
# @return [Array<Symbol>] The mapping of default_message_notifications.
|
129
|
+
DEFAULT_MESSAGE_NOTIFICATIONS = %i[all_messages only_mentions].freeze
|
130
|
+
# @private
|
131
|
+
# @return [Array<Symbol>] The mapping of explicit_content_filter.
|
132
|
+
EXPLICIT_CONTENT_FILTER = %i[disabled_in_text members_without_roles all_members].freeze
|
123
133
|
|
134
|
+
#
|
135
|
+
# Creates a new guild object.
|
124
136
|
# @private
|
137
|
+
#
|
138
|
+
# @param [Discorb::Client] client The client that owns this guild.
|
139
|
+
# @param [Hash] data The data of the guild.
|
140
|
+
# @param [Boolean] is_create_event Whether the guild is created by a `GUILD_CREATE` event.
|
141
|
+
#
|
125
142
|
def initialize(client, data, is_create_event)
|
126
143
|
@client = client
|
127
144
|
@data = {}
|
128
145
|
_set_data(data, is_create_event)
|
129
146
|
end
|
130
147
|
|
131
|
-
# @private
|
132
|
-
def update!
|
133
|
-
Async do
|
134
|
-
_, data = @client.get("/guilds/#{@id}").wait
|
135
|
-
_set_data(data, false)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
148
|
def afk_channel
|
140
149
|
@client.channels[@afk_channel_id]
|
141
150
|
end
|
@@ -242,9 +251,9 @@ module Discorb
|
|
242
251
|
description: description,
|
243
252
|
scheduled_start_time: start_time.iso8601,
|
244
253
|
scheduled_end_time: end_time&.iso8601,
|
245
|
-
privacy_level: Discorb::ScheduledEvent.
|
254
|
+
privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
|
246
255
|
channel_id: channel&.id,
|
247
|
-
entity_type: Discorb::ScheduledEvent.
|
256
|
+
entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:stage_instance),
|
248
257
|
}
|
249
258
|
when :voice
|
250
259
|
raise ArgumentError, "channel must be provided for voice events" unless channel
|
@@ -253,9 +262,9 @@ module Discorb
|
|
253
262
|
description: description,
|
254
263
|
scheduled_start_time: start_time.iso8601,
|
255
264
|
scheduled_end_time: end_time&.iso8601,
|
256
|
-
privacy_level: Discorb::ScheduledEvent.
|
265
|
+
privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
|
257
266
|
channel_id: channel&.id,
|
258
|
-
entity_type: Discorb::ScheduledEvent.
|
267
|
+
entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:voice),
|
259
268
|
}
|
260
269
|
when :external
|
261
270
|
raise ArgumentError, "location must be provided for external events" unless location
|
@@ -265,8 +274,8 @@ module Discorb
|
|
265
274
|
description: description,
|
266
275
|
scheduled_start_time: start_time.iso8601,
|
267
276
|
scheduled_end_time: end_time.iso8601,
|
268
|
-
privacy_level: Discorb::ScheduledEvent.
|
269
|
-
entity_type: Discorb::ScheduledEvent.
|
277
|
+
privacy_level: Discorb::ScheduledEvent::PRIVACY_LEVEL.key(privacy_level),
|
278
|
+
entity_type: Discorb::ScheduledEvent::ENTITY_TYPE.key(:external),
|
270
279
|
entity_metadata: {
|
271
280
|
location: location,
|
272
281
|
},
|
@@ -858,7 +867,7 @@ module Discorb
|
|
858
867
|
def fetch_voice_regions
|
859
868
|
Async do
|
860
869
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/voice", "//guilds/:guild_id/voice", :get)).wait
|
861
|
-
data.map { |d| VoiceRegion.new(
|
870
|
+
data.map { |d| VoiceRegion.new(d) }
|
862
871
|
end
|
863
872
|
end
|
864
873
|
|
@@ -871,7 +880,7 @@ module Discorb
|
|
871
880
|
def fetch_invites
|
872
881
|
Async do
|
873
882
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/invites", "//guilds/:guild_id/invites", :get)).wait
|
874
|
-
data.map { |d| Invite.new(@client, d) }
|
883
|
+
data.map { |d| Invite.new(@client, d, false) }
|
875
884
|
end
|
876
885
|
end
|
877
886
|
|
@@ -884,7 +893,7 @@ module Discorb
|
|
884
893
|
def fetch_integrations
|
885
894
|
Async do
|
886
895
|
_resp, data = @client.http.request(Route.new("/guilds/#{@id}/integrations", "//guilds/:guild_id/integrations", :get)).wait
|
887
|
-
data.map { |d| Integration.new(@client, d) }
|
896
|
+
data.map { |d| Integration.new(@client, d, @id) }
|
888
897
|
end
|
889
898
|
end
|
890
899
|
|
@@ -1012,7 +1021,14 @@ module Discorb
|
|
1012
1021
|
# @!attribute [r] url
|
1013
1022
|
# @return [String] The vanity URL.
|
1014
1023
|
|
1024
|
+
#
|
1025
|
+
# Initialize a new instance of the {VanityInvite} class.
|
1015
1026
|
# @private
|
1027
|
+
#
|
1028
|
+
# @param [Discorb::Client] client The client.
|
1029
|
+
# @param [Discorb::Guild] guild The guild.
|
1030
|
+
# @param [Hash] data The data of the invite.
|
1031
|
+
#
|
1016
1032
|
def initialize(client, guild, data)
|
1017
1033
|
@client = client
|
1018
1034
|
@guild = guild
|
@@ -1047,7 +1063,14 @@ module Discorb
|
|
1047
1063
|
# @!attribute [r] json_url
|
1048
1064
|
# @return [String] The JSON URL.
|
1049
1065
|
|
1066
|
+
#
|
1067
|
+
# Initialize a new instance of the {Widget} class.
|
1050
1068
|
# @private
|
1069
|
+
#
|
1070
|
+
# @param [Discorb::Client] client The client.
|
1071
|
+
# @param [Discorb::Snowflake] guild_id The guild ID.
|
1072
|
+
# @param [Hash] data The data from Discord.
|
1073
|
+
#
|
1051
1074
|
def initialize(client, guild_id, data)
|
1052
1075
|
@client = client
|
1053
1076
|
@enabled = data[:enabled]
|
@@ -1097,7 +1120,7 @@ module Discorb
|
|
1097
1120
|
def iframe(theme: "dark", width: 350, height: 500)
|
1098
1121
|
[
|
1099
1122
|
%(<iframe src="https://canary.discord.com/widget?id=#{@guild_id}&theme=#{theme}" width="#{width}" height="#{height}"),
|
1100
|
-
%(allowtransparency="true" frameborder="0" sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"></iframe>)
|
1123
|
+
%(allowtransparency="true" frameborder="0" sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"></iframe>),
|
1101
1124
|
].join
|
1102
1125
|
end
|
1103
1126
|
end
|
@@ -1111,7 +1134,14 @@ module Discorb
|
|
1111
1134
|
# @return [String] The reason for the ban.
|
1112
1135
|
attr_reader :reason
|
1113
1136
|
|
1137
|
+
#
|
1138
|
+
# Initialize a new instance of the {Ban} class.
|
1114
1139
|
# @private
|
1140
|
+
#
|
1141
|
+
# @param [Discorb::Client] client The client.
|
1142
|
+
# @param [Discorb::Guild] guild The guild.
|
1143
|
+
# @param [Hash] data The data from Discord.
|
1144
|
+
#
|
1115
1145
|
def initialize(client, guild, data)
|
1116
1146
|
@client = client
|
1117
1147
|
@guild = guild
|
@@ -1121,9 +1151,6 @@ module Discorb
|
|
1121
1151
|
end
|
1122
1152
|
|
1123
1153
|
class << self
|
1124
|
-
# @private
|
1125
|
-
attr_reader :nsfw_levels, :mfa_levels, :verification_levels, :default_message_notifications, :explicit_content_filter
|
1126
|
-
|
1127
1154
|
#
|
1128
1155
|
# Returns a banner url from the guild's ID.
|
1129
1156
|
#
|
@@ -1151,8 +1178,8 @@ module Discorb
|
|
1151
1178
|
@name = data[:name]
|
1152
1179
|
@members = Discorb::Dictionary.new
|
1153
1180
|
data[:members]&.each do |m|
|
1154
|
-
|
1155
|
-
|
1181
|
+
Member.new(@client, @id, m[:user], m)
|
1182
|
+
end
|
1156
1183
|
@splash = data[:splash] && Asset.new(self, data[:splash], path: "splashes/#{@id}")
|
1157
1184
|
@discovery_splash = data[:discovery_splash] && Asset.new(self, data[:discovery_splash], path: "discovery-splashes/#{@id}")
|
1158
1185
|
@owner_id = data[:owner_id]
|
@@ -1170,10 +1197,10 @@ module Discorb
|
|
1170
1197
|
@emojis[e[:id]] = CustomEmoji.new(@client, self, e)
|
1171
1198
|
end
|
1172
1199
|
@features = data[:features].map { |f| f.downcase.to_sym }
|
1173
|
-
@mfa_level =
|
1174
|
-
@verification_level =
|
1175
|
-
@default_message_notifications =
|
1176
|
-
@explicit_content_filter =
|
1200
|
+
@mfa_level = MFA_LEVELS[data[:mfa_level]]
|
1201
|
+
@verification_level = VERIFICATION_LEVELS[data[:verification_level]]
|
1202
|
+
@default_message_notifications = DEFAULT_MESSAGE_NOTIFICATIONS[data[:default_message_notifications]]
|
1203
|
+
@explicit_content_filter = EXPLICIT_CONTENT_FILTER[data[:explicit_content_filter]]
|
1177
1204
|
@system_channel_id = data[:system_channel_id]
|
1178
1205
|
@system_channel_flag = SystemChannelFlag.new(0b111 - data[:system_channel_flags])
|
1179
1206
|
@rules_channel_id = data[:rules_channel_id]
|
@@ -1188,7 +1215,7 @@ module Discorb
|
|
1188
1215
|
@approximate_member_count = data[:approximate_member_count]
|
1189
1216
|
@approximate_presence_count = data[:approximate_presence_count]
|
1190
1217
|
@welcome_screen = data[:welcome_screen].nil? ? nil : WelcomeScreen.new(@client, self, data[:welcome_screen])
|
1191
|
-
@nsfw_level =
|
1218
|
+
@nsfw_level = NSFW_LEVELS[data[:nsfw_level]]
|
1192
1219
|
return unless is_create_event
|
1193
1220
|
|
1194
1221
|
@stickers = data[:stickers].nil? ? [] : data[:stickers].map { |s| Sticker::GuildSticker.new(self, s) }
|
@@ -1239,7 +1266,14 @@ module Discorb
|
|
1239
1266
|
# @return [Discorb::Guild] The guild the welcome screen belongs to.
|
1240
1267
|
attr_reader :guild
|
1241
1268
|
|
1269
|
+
#
|
1270
|
+
# Initializes the welcome screen.
|
1242
1271
|
# @private
|
1272
|
+
#
|
1273
|
+
# @param [Discorb::Client] client The client.
|
1274
|
+
# @param [Discorb::Guild] guild The guild the welcome screen belongs to.
|
1275
|
+
# @param [Hash] data The data of the welcome screen.
|
1276
|
+
#
|
1243
1277
|
def initialize(client, guild, data)
|
1244
1278
|
@client = client
|
1245
1279
|
@description = data[:description]
|
@@ -33,7 +33,13 @@ module Discorb
|
|
33
33
|
# @return [Discorb::Guild] The guild this template is based on.
|
34
34
|
# @return [nil] Client wasn't able to find the guild this template is based on.
|
35
35
|
|
36
|
+
#
|
37
|
+
# Initialize a new template.
|
36
38
|
# @private
|
39
|
+
#
|
40
|
+
# @param [Discorb::Client] client The client.
|
41
|
+
# @param [Hash] data The data from Discord.
|
42
|
+
#
|
37
43
|
def initialize(client, data)
|
38
44
|
@client = client
|
39
45
|
_set_data(data)
|
@@ -120,14 +126,19 @@ module Discorb
|
|
120
126
|
attr_reader :widget_enabled
|
121
127
|
alias widget_enabled? widget_enabled
|
122
128
|
|
129
|
+
#
|
130
|
+
# Initialize a new guild in guild template.
|
123
131
|
# @private
|
132
|
+
#
|
133
|
+
# @param [Hash] data The data from Discord.
|
134
|
+
#
|
124
135
|
def initialize(data)
|
125
136
|
@name = data[:name]
|
126
137
|
@description = data[:description]
|
127
138
|
@region = data[:region]
|
128
|
-
@verification_level = Discorb::Guild
|
129
|
-
@default_message_notifications = Discorb::Guild
|
130
|
-
@explicit_content_filter = Discorb::Guild
|
139
|
+
@verification_level = Discorb::Guild::MFA_LEVELS[data[:verification_level]]
|
140
|
+
@default_message_notifications = Discorb::Guild::NOTIFICATION_LEVELS[data[:default_message_notifications]]
|
141
|
+
@explicit_content_filter = Discorb::Guild::EXPLICIT_CONTENT_FILTERS[data[:explicit_content_filter]]
|
131
142
|
@preferred_locale = data[:preferred_locale]
|
132
143
|
@afk_timeout = data[:afk_timeout]
|
133
144
|
@roles = data[:roles].map { |r| Role.new(r) }
|
@@ -146,7 +157,12 @@ module Discorb
|
|
146
157
|
# @return [Discorb::Color] The color of the role.
|
147
158
|
attr_reader :color
|
148
159
|
|
160
|
+
#
|
161
|
+
# Initialize a new role in guild template.
|
149
162
|
# @private
|
163
|
+
#
|
164
|
+
# @param [Hash] data The data from Discord.
|
165
|
+
#
|
150
166
|
def initialize(data)
|
151
167
|
@name = data[:name]
|
152
168
|
@permissions = Permission.new(data[:permissions])
|
@@ -177,7 +193,12 @@ module Discorb
|
|
177
193
|
# @return [Class] The class of the channel.
|
178
194
|
attr_reader :type
|
179
195
|
|
196
|
+
#
|
197
|
+
# Initialize a new channel in guild template.
|
180
198
|
# @private
|
199
|
+
#
|
200
|
+
# @param [Hash] data The data from Discord.
|
201
|
+
#
|
181
202
|
def initialize(data)
|
182
203
|
@name = data[:name]
|
183
204
|
@position = data[:position]
|
data/lib/discorb/http.rb
CHANGED
@@ -10,7 +10,12 @@ module Discorb
|
|
10
10
|
class HTTP
|
11
11
|
@nil_body = nil
|
12
12
|
|
13
|
+
#
|
14
|
+
# Initializes the http client.
|
13
15
|
# @private
|
16
|
+
#
|
17
|
+
# @param [Discorb::Client] client The client.
|
18
|
+
#
|
14
19
|
def initialize(client)
|
15
20
|
@client = client
|
16
21
|
@ratelimit_handler = RatelimitHandler.new(client)
|
@@ -66,16 +71,27 @@ module Discorb
|
|
66
71
|
@ratelimit_handler.wait(path)
|
67
72
|
req = Net::HTTP.const_get(path.method.to_s.capitalize).new(get_path(path), get_headers(headers, body, audit_log_reason), **kwargs)
|
68
73
|
data = [
|
69
|
-
["payload_json", get_body(body)]
|
74
|
+
["payload_json", get_body(body)],
|
70
75
|
]
|
71
76
|
files&.each_with_index do |file, i|
|
72
77
|
next if file.nil?
|
73
|
-
|
78
|
+
if file.created_by == :discord
|
79
|
+
request_io = StringIO.new(
|
80
|
+
cdn_http.get(URI.parse(file.url).path, {
|
81
|
+
"Content-Type" => nil,
|
82
|
+
"User-Agent" => Discorb::USER_AGENT,
|
83
|
+
}).body
|
84
|
+
)
|
85
|
+
data << ["files[#{i}]", request_io, { filename: file.filename, content_type: file.content_type }]
|
86
|
+
else
|
87
|
+
data << ["files[#{i}]", file.io, { filename: file.filename, content_type: file.content_type }]
|
88
|
+
end
|
74
89
|
end
|
75
90
|
req.set_form(data, "multipart/form-data")
|
76
91
|
session = Net::HTTP.new("discord.com", 443)
|
77
92
|
session.use_ssl = true
|
78
93
|
resp = session.request(req)
|
94
|
+
files&.then { _1.filter(&:will_close).each { |f| f.io.close } }
|
79
95
|
data = get_response_data(resp)
|
80
96
|
@ratelimit_handler.save(path, resp)
|
81
97
|
handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
|
@@ -91,7 +107,7 @@ module Discorb
|
|
91
107
|
def handle_response(resp, data, path, body, headers, audit_log_reason, kwargs)
|
92
108
|
case resp.code
|
93
109
|
when "429"
|
94
|
-
@client.
|
110
|
+
@client.logger.info("Rate limit exceeded for #{path.method} #{path.url}, waiting #{data[:retry_after]} seconds")
|
95
111
|
sleep(data[:retry_after])
|
96
112
|
request(path, body, headers: headers, audit_log_reason: audit_log_reason, **kwargs).wait
|
97
113
|
when "400"
|
@@ -159,6 +175,12 @@ module Discorb
|
|
159
175
|
https
|
160
176
|
end
|
161
177
|
|
178
|
+
def cdn_http
|
179
|
+
https = Net::HTTP.new("cdn.discordapp.com", 443)
|
180
|
+
https.use_ssl = true
|
181
|
+
https
|
182
|
+
end
|
183
|
+
|
162
184
|
def recr_utf8(data)
|
163
185
|
case data
|
164
186
|
when Hash
|
data/lib/discorb/integration.rb
CHANGED
@@ -38,12 +38,21 @@ module Discorb
|
|
38
38
|
# @macro client_cache
|
39
39
|
# @return [Discorb::Guild] The guild this integration is in.
|
40
40
|
|
41
|
-
@
|
41
|
+
# @private
|
42
|
+
# @return [{Integer => String}] The map of the expire behavior.
|
43
|
+
EXPIRE_BEHAVIOR = {
|
42
44
|
0 => :remove_role,
|
43
45
|
1 => :kick,
|
44
|
-
}
|
46
|
+
}.freeze
|
45
47
|
|
48
|
+
#
|
49
|
+
# Initialize a new integration.
|
46
50
|
# @private
|
51
|
+
#
|
52
|
+
# @param [Discorb::Client] client The client.
|
53
|
+
# @param [Hash] data The data of the welcome screen.
|
54
|
+
# @param [Discorb::Guild] guild The guild this integration is in.
|
55
|
+
#
|
47
56
|
def initialize(client, data, guild_id)
|
48
57
|
@client = client
|
49
58
|
@data = data
|
@@ -80,7 +89,7 @@ module Discorb
|
|
80
89
|
@syncing = data[:syncing]
|
81
90
|
@role_id = Snowflake.new(data[:role_id])
|
82
91
|
@enable_emoticons = data[:enable_emoticons]
|
83
|
-
@expire_behavior =
|
92
|
+
@expire_behavior = EXPIRE_BEHAVIOR[data[:expire_behavior]]
|
84
93
|
@expire_grace_period = data[:expire_grace_period]
|
85
94
|
@user = @client.users[data[:user][:id]] or Discorb::User.new(@client, data[:user])
|
86
95
|
@account = Account.new(data[:account])
|
@@ -89,11 +98,6 @@ module Discorb
|
|
89
98
|
@application = data[:application] and Application.new(@client, data[:application])
|
90
99
|
end
|
91
100
|
|
92
|
-
class << self
|
93
|
-
# @private
|
94
|
-
attr_reader :expire_behavior
|
95
|
-
end
|
96
|
-
|
97
101
|
#
|
98
102
|
# Represents an account for an integration.
|
99
103
|
#
|
@@ -103,7 +107,12 @@ module Discorb
|
|
103
107
|
# @return [String] The name of the account.
|
104
108
|
attr_reader :name
|
105
109
|
|
110
|
+
#
|
111
|
+
# Initialize a new account.
|
106
112
|
# @private
|
113
|
+
#
|
114
|
+
# @param [Hash] data The data from Discord.
|
115
|
+
#
|
107
116
|
def initialize(data)
|
108
117
|
@id = data[:id]
|
109
118
|
@name = data[:name]
|
@@ -129,7 +138,13 @@ module Discorb
|
|
129
138
|
# @return [nil] If the application has no bot user.
|
130
139
|
attr_reader :bot
|
131
140
|
|
141
|
+
#
|
142
|
+
# Initialize a new application.
|
132
143
|
# @private
|
144
|
+
#
|
145
|
+
# @param [Discorb::Client] client The client.
|
146
|
+
# @param [Hash] data The data from Discord.
|
147
|
+
#
|
133
148
|
def initialize(client, data)
|
134
149
|
@id = Snowflake.new(data[:id])
|
135
150
|
@name = data[:name]
|
data/lib/discorb/intents.rb
CHANGED
@@ -3,7 +3,9 @@
|
|
3
3
|
module Discorb
|
4
4
|
# Represents intents.
|
5
5
|
class Intents
|
6
|
-
@
|
6
|
+
# @private
|
7
|
+
# @return [{Symbol => Integer}] The mapping of intent names to bit values.
|
8
|
+
INTENT_BITS = {
|
7
9
|
guilds: 1 << 0,
|
8
10
|
members: 1 << 1,
|
9
11
|
bans: 1 << 2,
|
@@ -19,6 +21,7 @@ module Discorb
|
|
19
21
|
dm_messages: 1 << 12,
|
20
22
|
dm_reactions: 1 << 13,
|
21
23
|
dm_typing: 1 << 14,
|
24
|
+
message_content: 1 << 15,
|
22
25
|
scheduled_events: 1 << 16,
|
23
26
|
}.freeze
|
24
27
|
|
@@ -39,9 +42,13 @@ module Discorb
|
|
39
42
|
# @param dm_messages [Boolean] Whether dm messages related events are enabled.
|
40
43
|
# @param dm_reactions [Boolean] Whether dm reactions related events are enabled.
|
41
44
|
# @param dm_typing [Boolean] Whether dm typing related events are enabled.
|
45
|
+
# @param message_content [Boolean] Whether message content will be sent with events.
|
42
46
|
# @param scheduled_events [Boolean] Whether events related scheduled events are enabled.
|
43
47
|
#
|
44
48
|
# @note You must enable privileged intents to use `members` and/or `presences` intents.
|
49
|
+
# @note Message Content Intent is not required to use `message_content` intents for now,
|
50
|
+
# this will be required in April 30, 2022. [Learn More](https://support-dev.discord.com/hc/en-us/articles/4404772028055).
|
51
|
+
# You should specify `message_content` intent for preventing unexpected changes in the future.
|
45
52
|
#
|
46
53
|
def initialize(guilds: true,
|
47
54
|
members: false,
|
@@ -58,6 +65,7 @@ module Discorb
|
|
58
65
|
dm_messages: true,
|
59
66
|
dm_reactions: true,
|
60
67
|
dm_typing: true,
|
68
|
+
message_content: nil,
|
61
69
|
scheduled_events: true)
|
62
70
|
@raw_value = {
|
63
71
|
guilds: guilds,
|
@@ -75,6 +83,7 @@ module Discorb
|
|
75
83
|
dm_messages: dm_messages,
|
76
84
|
dm_reactions: dm_reactions,
|
77
85
|
dm_typing: dm_typing,
|
86
|
+
message_content: message_content,
|
78
87
|
scheduled_events: scheduled_events,
|
79
88
|
}
|
80
89
|
end
|
@@ -94,7 +103,7 @@ module Discorb
|
|
94
103
|
end
|
95
104
|
end
|
96
105
|
|
97
|
-
def respond_to_missing?(
|
106
|
+
def respond_to_missing?(name, include_private)
|
98
107
|
@raw_value.key?(name) ? true : super
|
99
108
|
end
|
100
109
|
|
@@ -102,7 +111,7 @@ module Discorb
|
|
102
111
|
# @return [Integer] The value of the intent.
|
103
112
|
def value
|
104
113
|
res = 0
|
105
|
-
|
114
|
+
INTENT_BITS.each do |intent, bit|
|
106
115
|
res += bit if @raw_value[intent]
|
107
116
|
end
|
108
117
|
res
|
@@ -121,7 +130,7 @@ module Discorb
|
|
121
130
|
# @param value [Integer] The value of the intent.
|
122
131
|
def from_value(value)
|
123
132
|
raw_value = {}
|
124
|
-
|
133
|
+
INTENT_BITS.each do |intent, bit|
|
125
134
|
raw_value[intent] = value & bit != 0
|
126
135
|
end
|
127
136
|
new(**raw_value)
|
@@ -129,21 +138,17 @@ module Discorb
|
|
129
138
|
|
130
139
|
# Create new intent object with default values.
|
131
140
|
# This will return intents without members and presence.
|
132
|
-
|
133
|
-
from_value(@intent_bits.values.reduce(:+) - @intent_bits[:members] - @intent_bits[:presences])
|
134
|
-
end
|
141
|
+
alias default new
|
135
142
|
|
136
143
|
# Create new intent object with all intents.
|
137
144
|
def all
|
138
|
-
from_value(
|
145
|
+
from_value(INTENT_BITS.values.reduce(:+))
|
139
146
|
end
|
140
147
|
|
141
148
|
# Create new intent object with no intents.
|
142
149
|
def none
|
143
150
|
from_value(0)
|
144
151
|
end
|
145
|
-
|
146
|
-
attr_reader :intent_bits
|
147
152
|
end
|
148
153
|
end
|
149
154
|
end
|
@@ -7,14 +7,15 @@ module Discorb
|
|
7
7
|
@interaction_type = 4
|
8
8
|
@interaction_name = :auto_complete
|
9
9
|
|
10
|
-
|
10
|
+
private
|
11
|
+
|
11
12
|
def _set_data(data)
|
12
13
|
super
|
13
14
|
Sync do
|
14
15
|
name, options = Discorb::CommandInteraction::SlashCommand.get_command_data(data)
|
15
16
|
|
16
17
|
unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
|
17
|
-
@client.
|
18
|
+
@client.logger.warn "Unknown command name #{name}, ignoring"
|
18
19
|
next
|
19
20
|
end
|
20
21
|
|
@@ -26,7 +27,6 @@ module Discorb
|
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
# @private
|
30
30
|
def send_complete_result(val)
|
31
31
|
@client.http.request(Route.new("/interactions/#{@id}/#{@token}/callback", "//interactions/:interaction_id/:token/callback", :post), {
|
32
32
|
type: 8,
|
@@ -40,7 +40,7 @@ module Discorb
|
|
40
40
|
},
|
41
41
|
}).wait
|
42
42
|
rescue Discorb::NotFoundError
|
43
|
-
@client.
|
43
|
+
@client.logger.warn "Failed to send auto complete result, This may be caused by the suggestion is taking too long (over 3 seconds) to respond", fallback: $stderr
|
44
44
|
end
|
45
45
|
|
46
46
|
class << self
|
@@ -14,6 +14,7 @@ module Discorb
|
|
14
14
|
#
|
15
15
|
class SlashCommand < CommandInteraction
|
16
16
|
@command_type = 1
|
17
|
+
@event_name = :slash_command
|
17
18
|
|
18
19
|
private
|
19
20
|
|
@@ -23,7 +24,7 @@ module Discorb
|
|
23
24
|
name, options = SlashCommand.get_command_data(data)
|
24
25
|
|
25
26
|
unless (command = @client.bottom_commands.find { |c| c.to_s == name && c.type_raw == 1 })
|
26
|
-
@client.
|
27
|
+
@client.logger.warn "Unknown command name #{name}, ignoring"
|
27
28
|
return
|
28
29
|
end
|
29
30
|
|
@@ -34,7 +35,12 @@ module Discorb
|
|
34
35
|
end
|
35
36
|
|
36
37
|
class << self
|
38
|
+
#
|
39
|
+
# Get command data from the given data.
|
37
40
|
# @private
|
41
|
+
#
|
42
|
+
# @param [Hash] data The data of the command.
|
43
|
+
#
|
38
44
|
def get_command_data(data)
|
39
45
|
name = data[:name]
|
40
46
|
options = nil
|
@@ -60,7 +66,15 @@ module Discorb
|
|
60
66
|
[name, options]
|
61
67
|
end
|
62
68
|
|
69
|
+
#
|
70
|
+
# Modify the option map with the given options.
|
63
71
|
# @private
|
72
|
+
#
|
73
|
+
# @param [Hash] option_map The option map to modify.
|
74
|
+
# @param [Array<Hash>] options The options for modifying.
|
75
|
+
# @param [Discorb::Guild] guild The guild where the command is executed.
|
76
|
+
# @param [{Discorb::Snowflake => Discorb::Member}] members The cached members of the guild.
|
77
|
+
# @param [{Integer => Discorb::Attachment}] attachments The cached attachments of the message.
|
64
78
|
def modify_option_map(option_map, options, guild, members, attachments)
|
65
79
|
options ||= []
|
66
80
|
options.each do |option|
|
@@ -68,7 +82,7 @@ module Discorb
|
|
68
82
|
when 3, 4, 5, 10
|
69
83
|
option[:value]
|
70
84
|
when 6
|
71
|
-
guild.members[option[:value]] || guild.fetch_member(option[:value]).wait
|
85
|
+
members[option[:value]] || guild.members[option[:value]] || guild.fetch_member(option[:value]).wait
|
72
86
|
when 7
|
73
87
|
guild.channels[option[:value]] || guild.fetch_channels.wait.find { |channel| channel.id == option[:value] }
|
74
88
|
when 8
|
@@ -89,6 +103,7 @@ module Discorb
|
|
89
103
|
#
|
90
104
|
class UserMenuCommand < CommandInteraction
|
91
105
|
@command_type = 2
|
106
|
+
@event_name = :user_command
|
92
107
|
|
93
108
|
# @return [Discorb::Member, Discorb::User] The target user.
|
94
109
|
attr_reader :target
|
@@ -107,6 +122,7 @@ module Discorb
|
|
107
122
|
#
|
108
123
|
class MessageMenuCommand < CommandInteraction
|
109
124
|
@command_type = 3
|
125
|
+
@event_name = :message_command
|
110
126
|
|
111
127
|
# @return [Discorb::Message] The target message.
|
112
128
|
attr_reader :target
|
@@ -147,18 +163,31 @@ module Discorb
|
|
147
163
|
|
148
164
|
class << self
|
149
165
|
# @private
|
150
|
-
attr_reader :command_type
|
166
|
+
attr_reader :command_type, :event_name
|
151
167
|
|
168
|
+
#
|
169
|
+
# Creates a new CommandInteraction instance for the given data.
|
152
170
|
# @private
|
171
|
+
#
|
172
|
+
# @param [Discorb::Client] client The client.
|
173
|
+
# @param [Hash] data The data for the command.
|
174
|
+
#
|
153
175
|
def make_interaction(client, data)
|
154
176
|
nested_classes.each do |klass|
|
155
|
-
|
177
|
+
if !klass.command_type.nil? && klass.command_type == data[:data][:type]
|
178
|
+
interaction = klass.new(client, data)
|
179
|
+
client.dispatch(klass.event_name, interaction)
|
180
|
+
return interaction
|
181
|
+
end
|
156
182
|
end
|
157
|
-
client.
|
183
|
+
client.logger.warn("Unknown command type #{data[:type]}, initialized CommandInteraction")
|
158
184
|
CommandInteraction.new(client, data)
|
159
185
|
end
|
160
186
|
|
187
|
+
#
|
188
|
+
# Returns the classes under this class.
|
161
189
|
# @private
|
190
|
+
#
|
162
191
|
def nested_classes
|
163
192
|
constants.select { |c| const_get(c).is_a? Class }.map { |c| const_get(c) }
|
164
193
|
end
|