discordrb 3.4.3 → 3.5.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.
- 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
|