discordrb 3.4.3 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +44 -18
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -1
- data/.github/ISSUE_TEMPLATE/feature_request.md +0 -1
- data/.github/workflows/codeql.yml +65 -0
- data/.markdownlint.json +4 -0
- data/.rubocop.yml +8 -2
- data/CHANGELOG.md +390 -225
- data/LICENSE.txt +1 -1
- data/README.md +37 -25
- data/discordrb-webhooks.gemspec +4 -1
- data/discordrb.gemspec +9 -6
- data/lib/discordrb/api/application.rb +202 -0
- data/lib/discordrb/api/channel.rb +177 -11
- data/lib/discordrb/api/interaction.rb +54 -0
- data/lib/discordrb/api/invite.rb +2 -2
- data/lib/discordrb/api/server.rb +40 -19
- data/lib/discordrb/api/user.rb +8 -3
- data/lib/discordrb/api/webhook.rb +57 -0
- data/lib/discordrb/api.rb +19 -5
- data/lib/discordrb/bot.rb +317 -32
- data/lib/discordrb/cache.rb +27 -22
- data/lib/discordrb/commands/command_bot.rb +6 -4
- data/lib/discordrb/commands/container.rb +1 -1
- data/lib/discordrb/commands/parser.rb +2 -2
- data/lib/discordrb/commands/rate_limiter.rb +1 -1
- data/lib/discordrb/container.rb +132 -3
- data/lib/discordrb/data/attachment.rb +15 -0
- data/lib/discordrb/data/audit_logs.rb +3 -3
- data/lib/discordrb/data/channel.rb +167 -23
- data/lib/discordrb/data/component.rb +229 -0
- data/lib/discordrb/data/integration.rb +42 -3
- data/lib/discordrb/data/interaction.rb +800 -0
- data/lib/discordrb/data/invite.rb +1 -1
- data/lib/discordrb/data/member.rb +108 -33
- data/lib/discordrb/data/message.rb +99 -19
- data/lib/discordrb/data/overwrite.rb +13 -7
- data/lib/discordrb/data/role.rb +58 -1
- data/lib/discordrb/data/server.rb +82 -80
- data/lib/discordrb/data/user.rb +69 -9
- data/lib/discordrb/data/webhook.rb +97 -4
- data/lib/discordrb/data.rb +3 -0
- data/lib/discordrb/errors.rb +44 -3
- data/lib/discordrb/events/channels.rb +1 -1
- data/lib/discordrb/events/interactions.rb +482 -0
- data/lib/discordrb/events/message.rb +9 -6
- data/lib/discordrb/events/presence.rb +21 -14
- data/lib/discordrb/events/reactions.rb +0 -1
- data/lib/discordrb/events/threads.rb +96 -0
- data/lib/discordrb/gateway.rb +30 -17
- data/lib/discordrb/permissions.rb +59 -34
- data/lib/discordrb/version.rb +1 -1
- data/lib/discordrb/voice/encoder.rb +2 -2
- data/lib/discordrb/voice/network.rb +18 -7
- data/lib/discordrb/voice/sodium.rb +3 -1
- data/lib/discordrb/voice/voice_bot.rb +3 -3
- data/lib/discordrb/webhooks.rb +2 -0
- data/lib/discordrb.rb +37 -4
- metadata +48 -14
- data/.codeclimate.yml +0 -16
- data/.travis.yml +0 -32
- data/bin/travis_build_docs.sh +0 -17
data/lib/discordrb/gateway.rb
CHANGED
@@ -134,7 +134,7 @@ module Discordrb
|
|
134
134
|
LARGE_THRESHOLD = 100
|
135
135
|
|
136
136
|
# The version of the gateway that's supposed to be used.
|
137
|
-
GATEWAY_VERSION =
|
137
|
+
GATEWAY_VERSION = 9
|
138
138
|
|
139
139
|
# Heartbeat ACKs are Discord's way of verifying on the client side whether the connection is still alive. If this is
|
140
140
|
# set to true (default value) the gateway client will use that functionality to detect zombie connections and
|
@@ -143,7 +143,10 @@ module Discordrb
|
|
143
143
|
# @return [true, false] whether or not this gateway should check for heartbeat ACKs.
|
144
144
|
attr_accessor :check_heartbeat_acks
|
145
145
|
|
146
|
-
|
146
|
+
# @return [Integer] the intent parameter sent to the gateway server.
|
147
|
+
attr_reader :intents
|
148
|
+
|
149
|
+
def initialize(bot, token, shard_key = nil, compress_mode = :stream, intents = ALL_INTENTS)
|
147
150
|
@token = token
|
148
151
|
@bot = bot
|
149
152
|
|
@@ -277,12 +280,12 @@ module Discordrb
|
|
277
280
|
def identify
|
278
281
|
compress = @compress_mode == :large
|
279
282
|
send_identify(@token, {
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
}, compress,
|
283
|
+
os: RUBY_PLATFORM,
|
284
|
+
browser: 'discordrb',
|
285
|
+
device: 'discordrb',
|
286
|
+
referrer: '',
|
287
|
+
referring_domain: ''
|
288
|
+
}, compress, LARGE_THRESHOLD, @shard_key, @intents)
|
286
289
|
end
|
287
290
|
|
288
291
|
# Sends an identify packet (op 2). This starts a new session on the current connection and tells Discord who we are.
|
@@ -292,26 +295,26 @@ module Discordrb
|
|
292
295
|
# @param properties [Hash<Symbol => String>] A list of properties for Discord to use in analytics. The following
|
293
296
|
# keys are recognised:
|
294
297
|
#
|
295
|
-
# - "
|
296
|
-
# - "
|
297
|
-
# - "
|
298
|
-
# - "
|
299
|
-
# - "
|
298
|
+
# - "os" (recommended value: the operating system the bot is running on)
|
299
|
+
# - "browser" (recommended value: library name)
|
300
|
+
# - "device" (recommended value: library name)
|
301
|
+
# - "referrer" (recommended value: empty)
|
302
|
+
# - "referring_domain" (recommended value: empty)
|
300
303
|
#
|
301
304
|
# @param compress [true, false] Whether certain large packets should be compressed using zlib.
|
302
305
|
# @param large_threshold [Integer] The member threshold after which a server counts as large and will have to have
|
303
306
|
# its member list chunked.
|
304
307
|
# @param shard_key [Array(Integer, Integer), nil] The shard key to use for sharding, represented as
|
305
308
|
# [shard_id, num_shards], or nil if the bot should not be sharded.
|
306
|
-
def send_identify(token, properties, compress, large_threshold, shard_key = nil)
|
309
|
+
def send_identify(token, properties, compress, large_threshold, shard_key = nil, intents = ALL_INTENTS)
|
307
310
|
data = {
|
308
311
|
# Don't send a v anymore as it's entirely determined by the URL now
|
309
312
|
token: token,
|
310
313
|
properties: properties,
|
311
314
|
compress: compress,
|
312
|
-
large_threshold: large_threshold
|
315
|
+
large_threshold: large_threshold,
|
316
|
+
intents: intents
|
313
317
|
}
|
314
|
-
data[:intents] = @intents unless @intents.nil?
|
315
318
|
|
316
319
|
# Don't include the shard key at all if it is nil as Discord checks for its mere existence
|
317
320
|
data[:shard] = shard_key if shard_key
|
@@ -790,7 +793,8 @@ module Discordrb
|
|
790
793
|
# - 4003: Not authenticated. How did this happen?
|
791
794
|
# - 4004: Authentication failed. Token was wrong, nothing we can do.
|
792
795
|
# - 4011: Sharding required. Currently requires developer intervention.
|
793
|
-
|
796
|
+
# - 4014: Use of disabled privileged intents.
|
797
|
+
FATAL_CLOSE_CODES = [4003, 4004, 4011, 4014].freeze
|
794
798
|
|
795
799
|
def handle_close(e)
|
796
800
|
@bot.__send__(:raise_event, Events::DisconnectEvent.new(@bot))
|
@@ -800,6 +804,15 @@ module Discordrb
|
|
800
804
|
LOGGER.error('Websocket close frame received!')
|
801
805
|
LOGGER.error("Code: #{e.code}")
|
802
806
|
LOGGER.error("Message: #{e.data}")
|
807
|
+
|
808
|
+
if e.code == 4014
|
809
|
+
LOGGER.error(<<~ERROR)
|
810
|
+
You attempted to identify with privileged intents that your bot is not authorized to use
|
811
|
+
Please enable the privileged intents on the bot page of your application on the discord developer page.
|
812
|
+
Read more here https://discord.com/developers/docs/topics/gateway#privileged-intents
|
813
|
+
ERROR
|
814
|
+
end
|
815
|
+
|
803
816
|
@should_reconnect = false if FATAL_CLOSE_CODES.include?(e.code)
|
804
817
|
elsif e.is_a? Exception
|
805
818
|
# Log the exception
|
@@ -6,37 +6,47 @@ module Discordrb
|
|
6
6
|
# This hash maps bit positions to logical permissions.
|
7
7
|
FLAGS = {
|
8
8
|
# Bit => Permission # Value
|
9
|
-
0 => :create_instant_invite,
|
10
|
-
1 => :kick_members,
|
11
|
-
2 => :ban_members,
|
12
|
-
3 => :administrator,
|
13
|
-
4 => :manage_channels,
|
14
|
-
5 => :manage_server,
|
15
|
-
6 => :add_reactions,
|
16
|
-
7 => :view_audit_log,
|
17
|
-
8 => :priority_speaker,
|
18
|
-
9 => :stream,
|
19
|
-
10 => :read_messages,
|
20
|
-
11 => :send_messages,
|
21
|
-
12 => :send_tts_messages,
|
22
|
-
13 => :manage_messages,
|
23
|
-
14 => :embed_links,
|
24
|
-
15 => :attach_files,
|
25
|
-
16 => :read_message_history,
|
26
|
-
17 => :mention_everyone,
|
27
|
-
18 => :use_external_emoji,
|
28
|
-
19 => :view_server_insights,
|
29
|
-
20 => :connect,
|
30
|
-
21 => :speak,
|
31
|
-
22 => :mute_members,
|
32
|
-
23 => :deafen_members,
|
33
|
-
24 => :move_members,
|
34
|
-
25 => :use_voice_activity,
|
35
|
-
26 => :change_nickname,
|
36
|
-
27 => :manage_nicknames,
|
37
|
-
28 => :manage_roles,
|
38
|
-
29 => :manage_webhooks,
|
39
|
-
30 => :manage_emojis
|
9
|
+
0 => :create_instant_invite, # 1
|
10
|
+
1 => :kick_members, # 2
|
11
|
+
2 => :ban_members, # 4
|
12
|
+
3 => :administrator, # 8
|
13
|
+
4 => :manage_channels, # 16
|
14
|
+
5 => :manage_server, # 32
|
15
|
+
6 => :add_reactions, # 64
|
16
|
+
7 => :view_audit_log, # 128
|
17
|
+
8 => :priority_speaker, # 256
|
18
|
+
9 => :stream, # 512
|
19
|
+
10 => :read_messages, # 1024
|
20
|
+
11 => :send_messages, # 2048
|
21
|
+
12 => :send_tts_messages, # 4096
|
22
|
+
13 => :manage_messages, # 8192
|
23
|
+
14 => :embed_links, # 16384
|
24
|
+
15 => :attach_files, # 32768
|
25
|
+
16 => :read_message_history, # 65536
|
26
|
+
17 => :mention_everyone, # 131072
|
27
|
+
18 => :use_external_emoji, # 262144
|
28
|
+
19 => :view_server_insights, # 524288
|
29
|
+
20 => :connect, # 1048576
|
30
|
+
21 => :speak, # 2097152
|
31
|
+
22 => :mute_members, # 4194304
|
32
|
+
23 => :deafen_members, # 8388608
|
33
|
+
24 => :move_members, # 16777216
|
34
|
+
25 => :use_voice_activity, # 33554432
|
35
|
+
26 => :change_nickname, # 67108864
|
36
|
+
27 => :manage_nicknames, # 134217728
|
37
|
+
28 => :manage_roles, # 268435456, also Manage Permissions
|
38
|
+
29 => :manage_webhooks, # 536870912
|
39
|
+
30 => :manage_emojis, # 1073741824, also Manage Stickers
|
40
|
+
31 => :use_slash_commands, # 2147483648
|
41
|
+
32 => :request_to_speak, # 4294967296
|
42
|
+
33 => :manage_events, # 8589934592
|
43
|
+
34 => :manage_threads, # 17179869184
|
44
|
+
35 => :use_public_threads, # 34359738368
|
45
|
+
36 => :use_private_threads, # 68719476736
|
46
|
+
37 => :use_external_stickers, # 137438953472
|
47
|
+
38 => :send_messages_in_threads, # 274877906944
|
48
|
+
39 => :use_embedded_activities, # 549755813888
|
49
|
+
40 => :moderate_members # 1099511627776
|
40
50
|
}.freeze
|
41
51
|
|
42
52
|
FLAGS.each do |position, flag|
|
@@ -101,7 +111,7 @@ module Discordrb
|
|
101
111
|
# permission.can_speak = true
|
102
112
|
# @example Create a permissions object that could allow/deny read messages, connect, and speak by an array of symbols
|
103
113
|
# Permissions.new [:read_messages, :connect, :speak]
|
104
|
-
# @param bits [Integer, Array<Symbol>] The permission bits that should be set from the beginning, or an array of permission flag symbols
|
114
|
+
# @param bits [String, Integer, Array<Symbol>] The permission bits that should be set from the beginning, or an array of permission flag symbols
|
105
115
|
# @param writer [RoleWriter] The writer that should be used to update data when a permission is set.
|
106
116
|
def initialize(bits = 0, writer = nil)
|
107
117
|
@writer = writer
|
@@ -109,12 +119,21 @@ module Discordrb
|
|
109
119
|
@bits = if bits.is_a? Array
|
110
120
|
self.class.bits(bits)
|
111
121
|
else
|
112
|
-
bits
|
122
|
+
bits.to_i
|
113
123
|
end
|
114
124
|
|
115
125
|
init_vars
|
116
126
|
end
|
117
127
|
|
128
|
+
# Return an array of permission flag symbols for this class's permissions
|
129
|
+
# @example Get the permissions for the bits "9"
|
130
|
+
# permissions = Permissions.new(9)
|
131
|
+
# permissions.defined_permissions #=> [:create_instant_invite, :administrator]
|
132
|
+
# @return [Array<Symbol>] the permissions
|
133
|
+
def defined_permissions
|
134
|
+
FLAGS.filter_map { |value, name| (@bits & (1 << value)).positive? ? name : nil }
|
135
|
+
end
|
136
|
+
|
118
137
|
# Comparison based on permission bits
|
119
138
|
def ==(other)
|
120
139
|
false unless other.is_a? Discordrb::Permissions
|
@@ -154,6 +173,12 @@ module Discordrb
|
|
154
173
|
# has_manage_channels = member.defined_permission?(:manage_channels)
|
155
174
|
# @return [true, false] whether or not this user has the permission defined.
|
156
175
|
def defined_permission?(action, channel = nil)
|
176
|
+
# For slash commands we may not have access to the server or role
|
177
|
+
# permissions. In this case we use the permissions given to us by the
|
178
|
+
# interaction. If attempting to check against a specific channel the check
|
179
|
+
# is skipped.
|
180
|
+
return @permissions.__send__(action) if @permissions && channel.nil?
|
181
|
+
|
157
182
|
# Get the permission the user's roles have
|
158
183
|
role_permission = defined_role_permission?(action, channel)
|
159
184
|
|
@@ -179,7 +204,7 @@ module Discordrb
|
|
179
204
|
private
|
180
205
|
|
181
206
|
def defined_role_permission?(action, channel)
|
182
|
-
roles_to_check = [@server.everyone_role] +
|
207
|
+
roles_to_check = [@server.everyone_role] + roles
|
183
208
|
|
184
209
|
# For each role, check if
|
185
210
|
# (1) the channel explicitly allows or permits an action for the role and
|
data/lib/discordrb/version.rb
CHANGED
@@ -102,8 +102,8 @@ module Discordrb::Voice
|
|
102
102
|
'-ar', '48000',
|
103
103
|
'-ac', '2',
|
104
104
|
'pipe:1',
|
105
|
-
filter_volume_argument
|
106
|
-
].concat(options.split).reject {|segment| segment.nil? || segment == '' }
|
105
|
+
filter_volume_argument
|
106
|
+
].concat(options.split).reject { |segment| segment.nil? || segment == '' }
|
107
107
|
end
|
108
108
|
|
109
109
|
def filter_volume_argument
|
@@ -42,10 +42,10 @@ module Discordrb::Voice
|
|
42
42
|
attr_writer :secret_key
|
43
43
|
|
44
44
|
# The UDP encryption mode
|
45
|
-
attr_reader :mode
|
45
|
+
attr_reader :mode
|
46
46
|
|
47
47
|
# @!visibility private
|
48
|
-
attr_writer :mode
|
48
|
+
attr_writer :mode
|
49
49
|
|
50
50
|
# Creates a new UDP connection. Only creates a socket as the discovery reply may come before the data is
|
51
51
|
# initialized.
|
@@ -69,9 +69,9 @@ module Discordrb::Voice
|
|
69
69
|
# @return [Array(String, Integer)] the IP and port received from the discovery reply.
|
70
70
|
def receive_discovery_reply
|
71
71
|
# Wait for a UDP message
|
72
|
-
message = @socket.recv(
|
73
|
-
ip = message[
|
74
|
-
port = message[-2
|
72
|
+
message = @socket.recv(74)
|
73
|
+
ip = message[8..-3].delete("\0")
|
74
|
+
port = message[-2..].unpack1('n')
|
75
75
|
[ip, port]
|
76
76
|
end
|
77
77
|
|
@@ -98,10 +98,21 @@ module Discordrb::Voice
|
|
98
98
|
# Sends the UDP discovery packet with the internally stored SSRC. Discord will send a reply afterwards which can
|
99
99
|
# be received using {#receive_discovery_reply}
|
100
100
|
def send_discovery
|
101
|
-
|
101
|
+
# Create empty packet
|
102
|
+
discovery_packet = ''
|
102
103
|
|
103
|
-
# Add
|
104
|
+
# Add Type request (0x1 = request, 0x2 = response)
|
105
|
+
discovery_packet += [0x1].pack('n')
|
106
|
+
|
107
|
+
# Add Length (excluding Type and itself = 70)
|
108
|
+
discovery_packet += [70].pack('n')
|
109
|
+
|
110
|
+
# Add SSRC
|
111
|
+
discovery_packet += [@ssrc].pack('N')
|
112
|
+
|
113
|
+
# Add 66 zeroes so the packet is 74 bytes long
|
104
114
|
discovery_packet += "\0" * 66
|
115
|
+
|
105
116
|
send_packet(discovery_packet)
|
106
117
|
end
|
107
118
|
|
@@ -22,10 +22,10 @@ module Discordrb::Voice
|
|
22
22
|
# {VoiceBot#adjust_offset}, and {VoiceBot#adjust_average}.
|
23
23
|
class VoiceBot
|
24
24
|
# @return [Channel] the current voice channel
|
25
|
-
attr_reader :channel
|
25
|
+
attr_reader :channel
|
26
26
|
|
27
27
|
# @!visibility private
|
28
|
-
attr_writer :channel
|
28
|
+
attr_writer :channel
|
29
29
|
|
30
30
|
# @return [Integer, nil] the amount of time the stream has been playing, or `nil` if nothing has been played yet.
|
31
31
|
attr_reader :stream_time
|
@@ -149,7 +149,7 @@ module Discordrb::Voice
|
|
149
149
|
|
150
150
|
# Sets whether or not the bot is speaking (green circle around user).
|
151
151
|
# @param value [true, false, Integer] whether or not the bot should be speaking, or a bitmask denoting the audio type
|
152
|
-
# @note https://
|
152
|
+
# @note https://discord.com/developers/docs/topics/voice-connections#speaking for information on the speaking bitmask
|
153
153
|
def speaking=(value)
|
154
154
|
@playing = value
|
155
155
|
@ws.send_speaking(value)
|
data/lib/discordrb/webhooks.rb
CHANGED
data/lib/discordrb.rb
CHANGED
@@ -10,13 +10,13 @@ module Discordrb
|
|
10
10
|
Thread.current[:discordrb_name] = 'main'
|
11
11
|
|
12
12
|
# The default debug logger used by discordrb.
|
13
|
-
LOGGER = Logger.new(ENV
|
13
|
+
LOGGER = Logger.new(ENV.fetch('DISCORDRB_FANCY_LOG', false))
|
14
14
|
|
15
15
|
# The Unix timestamp Discord IDs are based on
|
16
16
|
DISCORD_EPOCH = 1_420_070_400_000
|
17
17
|
|
18
18
|
# Used to declare what events you wish to recieve from Discord.
|
19
|
-
# @see https://
|
19
|
+
# @see https://discord.com/developers/docs/topics/gateway#gateway-intents
|
20
20
|
INTENTS = {
|
21
21
|
servers: 1 << 0,
|
22
22
|
server_members: 1 << 1,
|
@@ -35,9 +35,16 @@ module Discordrb
|
|
35
35
|
direct_message_typing: 1 << 14
|
36
36
|
}.freeze
|
37
37
|
|
38
|
-
#
|
38
|
+
# All available intents
|
39
39
|
ALL_INTENTS = INTENTS.values.reduce(&:|)
|
40
40
|
|
41
|
+
# All unprivileged intents
|
42
|
+
# @see https://discord.com/developers/docs/topics/gateway#privileged-intents
|
43
|
+
UNPRIVILEGED_INTENTS = ALL_INTENTS & ~(INTENTS[:server_members] | INTENTS[:server_presences])
|
44
|
+
|
45
|
+
# No intents
|
46
|
+
NO_INTENTS = 0
|
47
|
+
|
41
48
|
# Compares two objects based on IDs - either the objects' IDs are equal, or one object is equal to the other's ID.
|
42
49
|
def self.id_compare(one_id, other)
|
43
50
|
other.respond_to?(:resolve_id) ? (one_id.resolve_id == other.resolve_id) : (one_id == other)
|
@@ -46,6 +53,18 @@ module Discordrb
|
|
46
53
|
# The maximum length a Discord message can have
|
47
54
|
CHARACTER_LIMIT = 2000
|
48
55
|
|
56
|
+
# For creating timestamps with {timestamp}
|
57
|
+
# @see https://discord.com/developers/docs/reference#message-formatting-timestamp-styles
|
58
|
+
TIMESTAMP_STYLES = {
|
59
|
+
short_time: 't', # 16:20
|
60
|
+
long_time: 'T', # 16:20:30
|
61
|
+
short_date: 'd', # 20/04/2021
|
62
|
+
long_date: 'D', # 20 April 2021
|
63
|
+
short_datetime: 'f', # 20 April 2021 16:20
|
64
|
+
long_datetime: 'F', # Tuesday, 20 April 2021 16:20
|
65
|
+
relative: 'R' # 2 months ago
|
66
|
+
}.freeze
|
67
|
+
|
49
68
|
# Splits a message into chunks of 2000 characters. Attempts to split by lines if possible.
|
50
69
|
# @param msg [String] The message to split.
|
51
70
|
# @return [Array<String>] the message split into chunks
|
@@ -76,7 +95,7 @@ module Discordrb
|
|
76
95
|
ideal_ary = ideal.length > CHARACTER_LIMIT ? ideal.split(/(.{1,#{CHARACTER_LIMIT}}\b|.{1,#{CHARACTER_LIMIT}})/o).reject(&:empty?) : [ideal]
|
77
96
|
|
78
97
|
# Slice off the ideal part and strip newlines
|
79
|
-
rest = msg[ideal.length
|
98
|
+
rest = msg[ideal.length..].strip
|
80
99
|
|
81
100
|
# If none remains, return an empty array -> we're done
|
82
101
|
return [] unless rest
|
@@ -84,6 +103,20 @@ module Discordrb
|
|
84
103
|
# Otherwise, call the method recursively to split the rest of the string and add it onto the ideal array
|
85
104
|
ideal_ary + split_message(rest)
|
86
105
|
end
|
106
|
+
|
107
|
+
# @param time [Time, Integer] The time to create the timestamp from, or a unix timestamp integer.
|
108
|
+
# @param style [Symbol, String] One of the keys from {TIMESTAMP_STYLES} or a string with the style.
|
109
|
+
# @return [String]
|
110
|
+
# @example
|
111
|
+
# Discordrb.timestamp(Time.now, :short_time)
|
112
|
+
# # => "<t:1632146954:t>"
|
113
|
+
def self.timestamp(time, style = nil)
|
114
|
+
if style.nil?
|
115
|
+
"<t:#{time.to_i}>"
|
116
|
+
else
|
117
|
+
"<t:#{time.to_i}:#{TIMESTAMP_STYLES[style] || style}>"
|
118
|
+
end
|
119
|
+
end
|
87
120
|
end
|
88
121
|
|
89
122
|
# In discordrb, Integer and {String} are monkey-patched to allow for easy resolution of IDs
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: discordrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- meew0
|
@@ -73,14 +73,14 @@ dependencies:
|
|
73
73
|
requirements:
|
74
74
|
- - "~>"
|
75
75
|
- !ruby/object:Gem::Version
|
76
|
-
version: 3.
|
76
|
+
version: 3.5.0
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
81
|
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: 3.
|
83
|
+
version: 3.5.0
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
85
|
name: bundler
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -135,14 +135,28 @@ dependencies:
|
|
135
135
|
requirements:
|
136
136
|
- - "~>"
|
137
137
|
- !ruby/object:Gem::Version
|
138
|
-
version: 3.
|
138
|
+
version: 3.11.0
|
139
|
+
type: :development
|
140
|
+
prerelease: false
|
141
|
+
version_requirements: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 3.11.0
|
146
|
+
- !ruby/object:Gem::Dependency
|
147
|
+
name: rspec_junit_formatter
|
148
|
+
requirement: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.5.1
|
139
153
|
type: :development
|
140
154
|
prerelease: false
|
141
155
|
version_requirements: !ruby/object:Gem::Requirement
|
142
156
|
requirements:
|
143
157
|
- - "~>"
|
144
158
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
159
|
+
version: 0.5.1
|
146
160
|
- !ruby/object:Gem::Dependency
|
147
161
|
name: rspec-prof
|
148
162
|
requirement: !ruby/object:Gem::Requirement
|
@@ -163,14 +177,14 @@ dependencies:
|
|
163
177
|
requirements:
|
164
178
|
- - "~>"
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: 1.
|
180
|
+
version: 1.36.0
|
167
181
|
type: :development
|
168
182
|
prerelease: false
|
169
183
|
version_requirements: !ruby/object:Gem::Requirement
|
170
184
|
requirements:
|
171
185
|
- - "~>"
|
172
186
|
- !ruby/object:Gem::Version
|
173
|
-
version: 1.
|
187
|
+
version: 1.36.0
|
174
188
|
- !ruby/object:Gem::Dependency
|
175
189
|
name: rubocop-performance
|
176
190
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,20 +199,34 @@ dependencies:
|
|
185
199
|
- - "~>"
|
186
200
|
- !ruby/object:Gem::Version
|
187
201
|
version: '1.0'
|
202
|
+
- !ruby/object:Gem::Dependency
|
203
|
+
name: rubocop-rake
|
204
|
+
requirement: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: 0.6.0
|
209
|
+
type: :development
|
210
|
+
prerelease: false
|
211
|
+
version_requirements: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: 0.6.0
|
188
216
|
- !ruby/object:Gem::Dependency
|
189
217
|
name: simplecov
|
190
218
|
requirement: !ruby/object:Gem::Requirement
|
191
219
|
requirements:
|
192
220
|
- - "~>"
|
193
221
|
- !ruby/object:Gem::Version
|
194
|
-
version: 0.
|
222
|
+
version: 0.21.0
|
195
223
|
type: :development
|
196
224
|
prerelease: false
|
197
225
|
version_requirements: !ruby/object:Gem::Requirement
|
198
226
|
requirements:
|
199
227
|
- - "~>"
|
200
228
|
- !ruby/object:Gem::Version
|
201
|
-
version: 0.
|
229
|
+
version: 0.21.0
|
202
230
|
- !ruby/object:Gem::Dependency
|
203
231
|
name: yard
|
204
232
|
requirement: !ruby/object:Gem::Requirement
|
@@ -221,16 +249,16 @@ extensions: []
|
|
221
249
|
extra_rdoc_files: []
|
222
250
|
files:
|
223
251
|
- ".circleci/config.yml"
|
224
|
-
- ".codeclimate.yml"
|
225
252
|
- ".github/CONTRIBUTING.md"
|
226
253
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
227
254
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
228
255
|
- ".github/pull_request_template.md"
|
256
|
+
- ".github/workflows/codeql.yml"
|
229
257
|
- ".gitignore"
|
258
|
+
- ".markdownlint.json"
|
230
259
|
- ".overcommit.yml"
|
231
260
|
- ".rspec"
|
232
261
|
- ".rubocop.yml"
|
233
|
-
- ".travis.yml"
|
234
262
|
- ".yardopts"
|
235
263
|
- CHANGELOG.md
|
236
264
|
- Gemfile
|
@@ -239,13 +267,14 @@ files:
|
|
239
267
|
- Rakefile
|
240
268
|
- bin/console
|
241
269
|
- bin/setup
|
242
|
-
- bin/travis_build_docs.sh
|
243
270
|
- discordrb-webhooks.gemspec
|
244
271
|
- discordrb.gemspec
|
245
272
|
- lib/discordrb.rb
|
246
273
|
- lib/discordrb/allowed_mentions.rb
|
247
274
|
- lib/discordrb/api.rb
|
275
|
+
- lib/discordrb/api/application.rb
|
248
276
|
- lib/discordrb/api/channel.rb
|
277
|
+
- lib/discordrb/api/interaction.rb
|
249
278
|
- lib/discordrb/api/invite.rb
|
250
279
|
- lib/discordrb/api/server.rb
|
251
280
|
- lib/discordrb/api/user.rb
|
@@ -266,9 +295,11 @@ files:
|
|
266
295
|
- lib/discordrb/data/attachment.rb
|
267
296
|
- lib/discordrb/data/audit_logs.rb
|
268
297
|
- lib/discordrb/data/channel.rb
|
298
|
+
- lib/discordrb/data/component.rb
|
269
299
|
- lib/discordrb/data/embed.rb
|
270
300
|
- lib/discordrb/data/emoji.rb
|
271
301
|
- lib/discordrb/data/integration.rb
|
302
|
+
- lib/discordrb/data/interaction.rb
|
272
303
|
- lib/discordrb/data/invite.rb
|
273
304
|
- lib/discordrb/data/member.rb
|
274
305
|
- lib/discordrb/data/message.rb
|
@@ -288,6 +319,7 @@ files:
|
|
288
319
|
- lib/discordrb/events/channels.rb
|
289
320
|
- lib/discordrb/events/generic.rb
|
290
321
|
- lib/discordrb/events/guilds.rb
|
322
|
+
- lib/discordrb/events/interactions.rb
|
291
323
|
- lib/discordrb/events/invites.rb
|
292
324
|
- lib/discordrb/events/lifetime.rb
|
293
325
|
- lib/discordrb/events/members.rb
|
@@ -296,6 +328,7 @@ files:
|
|
296
328
|
- lib/discordrb/events/raw.rb
|
297
329
|
- lib/discordrb/events/reactions.rb
|
298
330
|
- lib/discordrb/events/roles.rb
|
331
|
+
- lib/discordrb/events/threads.rb
|
299
332
|
- lib/discordrb/events/typing.rb
|
300
333
|
- lib/discordrb/events/voice_server_update.rb
|
301
334
|
- lib/discordrb/events/voice_state_update.rb
|
@@ -320,7 +353,8 @@ homepage: https://github.com/shardlab/discordrb
|
|
320
353
|
licenses:
|
321
354
|
- MIT
|
322
355
|
metadata:
|
323
|
-
changelog_uri: https://github.com/shardlab/discordrb/blob/
|
356
|
+
changelog_uri: https://github.com/shardlab/discordrb/blob/main/CHANGELOG.md
|
357
|
+
rubygems_mfa_required: 'true'
|
324
358
|
post_install_message:
|
325
359
|
rdoc_options: []
|
326
360
|
require_paths:
|
@@ -329,7 +363,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
329
363
|
requirements:
|
330
364
|
- - ">="
|
331
365
|
- !ruby/object:Gem::Version
|
332
|
-
version: '2.
|
366
|
+
version: '2.7'
|
333
367
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
334
368
|
requirements:
|
335
369
|
- - ">="
|
data/.codeclimate.yml
DELETED
data/.travis.yml
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.5
|
4
|
-
- 2.6
|
5
|
-
before_script:
|
6
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 -o ./cc-test-reporter
|
7
|
-
- chmod +x ./cc-test-reporter
|
8
|
-
- ./cc-test-reporter before-build
|
9
|
-
- sudo apt-get install libsodium-dev
|
10
|
-
script:
|
11
|
-
- bundle exec rspec spec
|
12
|
-
- bundle exec rubocop -c .rubocop.yml
|
13
|
-
- bin/travis_build_docs.sh
|
14
|
-
after_script:
|
15
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
16
|
-
deploy:
|
17
|
-
- provider: pages
|
18
|
-
skip-cleanup: true
|
19
|
-
github-token: $GITHUB_TOKEN
|
20
|
-
keep-history: true
|
21
|
-
local-dir: docs
|
22
|
-
on:
|
23
|
-
branch: master
|
24
|
-
rvm: 2.6
|
25
|
-
- provider: pages
|
26
|
-
skip-cleanup: true
|
27
|
-
github-token: $GITHUB_TOKEN
|
28
|
-
keep-history: true
|
29
|
-
local-dir: docs
|
30
|
-
on:
|
31
|
-
tags: true
|
32
|
-
rvm: 2.6
|