rubycord 1.0.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 +7 -0
- data/lib/rubycord/allowed_mentions.rb +34 -0
- data/lib/rubycord/api/application.rb +200 -0
- data/lib/rubycord/api/channel.rb +597 -0
- data/lib/rubycord/api/interaction.rb +52 -0
- data/lib/rubycord/api/invite.rb +42 -0
- data/lib/rubycord/api/server.rb +557 -0
- data/lib/rubycord/api/user.rb +153 -0
- data/lib/rubycord/api/webhook.rb +138 -0
- data/lib/rubycord/api.rb +356 -0
- data/lib/rubycord/await.rb +49 -0
- data/lib/rubycord/bot.rb +1757 -0
- data/lib/rubycord/cache.rb +259 -0
- data/lib/rubycord/colour_rgb.rb +41 -0
- data/lib/rubycord/commands/command_bot.rb +519 -0
- data/lib/rubycord/commands/container.rb +110 -0
- data/lib/rubycord/commands/events.rb +9 -0
- data/lib/rubycord/commands/parser.rb +325 -0
- data/lib/rubycord/commands/rate_limiter.rb +142 -0
- data/lib/rubycord/container.rb +753 -0
- data/lib/rubycord/data/activity.rb +269 -0
- data/lib/rubycord/data/application.rb +48 -0
- data/lib/rubycord/data/attachment.rb +109 -0
- data/lib/rubycord/data/audit_logs.rb +343 -0
- data/lib/rubycord/data/channel.rb +996 -0
- data/lib/rubycord/data/component.rb +227 -0
- data/lib/rubycord/data/embed.rb +249 -0
- data/lib/rubycord/data/emoji.rb +80 -0
- data/lib/rubycord/data/integration.rb +120 -0
- data/lib/rubycord/data/interaction.rb +798 -0
- data/lib/rubycord/data/invite.rb +135 -0
- data/lib/rubycord/data/member.rb +370 -0
- data/lib/rubycord/data/message.rb +412 -0
- data/lib/rubycord/data/overwrite.rb +106 -0
- data/lib/rubycord/data/profile.rb +89 -0
- data/lib/rubycord/data/reaction.rb +31 -0
- data/lib/rubycord/data/recipient.rb +32 -0
- data/lib/rubycord/data/role.rb +246 -0
- data/lib/rubycord/data/server.rb +1002 -0
- data/lib/rubycord/data/user.rb +261 -0
- data/lib/rubycord/data/voice_region.rb +43 -0
- data/lib/rubycord/data/voice_state.rb +39 -0
- data/lib/rubycord/data/webhook.rb +232 -0
- data/lib/rubycord/data.rb +40 -0
- data/lib/rubycord/errors.rb +737 -0
- data/lib/rubycord/events/await.rb +46 -0
- data/lib/rubycord/events/bans.rb +58 -0
- data/lib/rubycord/events/channels.rb +186 -0
- data/lib/rubycord/events/generic.rb +126 -0
- data/lib/rubycord/events/guilds.rb +191 -0
- data/lib/rubycord/events/interactions.rb +480 -0
- data/lib/rubycord/events/invites.rb +123 -0
- data/lib/rubycord/events/lifetime.rb +29 -0
- data/lib/rubycord/events/members.rb +91 -0
- data/lib/rubycord/events/message.rb +337 -0
- data/lib/rubycord/events/presence.rb +127 -0
- data/lib/rubycord/events/raw.rb +45 -0
- data/lib/rubycord/events/reactions.rb +156 -0
- data/lib/rubycord/events/roles.rb +86 -0
- data/lib/rubycord/events/threads.rb +94 -0
- data/lib/rubycord/events/typing.rb +70 -0
- data/lib/rubycord/events/voice_server_update.rb +45 -0
- data/lib/rubycord/events/voice_state_update.rb +103 -0
- data/lib/rubycord/events/webhooks.rb +62 -0
- data/lib/rubycord/gateway.rb +867 -0
- data/lib/rubycord/id_object.rb +37 -0
- data/lib/rubycord/light/data.rb +60 -0
- data/lib/rubycord/light/integrations.rb +71 -0
- data/lib/rubycord/light/light_bot.rb +56 -0
- data/lib/rubycord/light.rb +6 -0
- data/lib/rubycord/logger.rb +118 -0
- data/lib/rubycord/paginator.rb +55 -0
- data/lib/rubycord/permissions.rb +251 -0
- data/lib/rubycord/version.rb +5 -0
- data/lib/rubycord/voice/encoder.rb +113 -0
- data/lib/rubycord/voice/network.rb +366 -0
- data/lib/rubycord/voice/sodium.rb +96 -0
- data/lib/rubycord/voice/voice_bot.rb +408 -0
- data/lib/rubycord/webhooks/builder.rb +100 -0
- data/lib/rubycord/webhooks/client.rb +132 -0
- data/lib/rubycord/webhooks/embeds.rb +248 -0
- data/lib/rubycord/webhooks/modal.rb +78 -0
- data/lib/rubycord/webhooks/version.rb +7 -0
- data/lib/rubycord/webhooks/view.rb +192 -0
- data/lib/rubycord/webhooks.rb +12 -0
- data/lib/rubycord/websocket.rb +70 -0
- data/lib/rubycord.rb +140 -0
- metadata +231 -0
@@ -0,0 +1,259 @@
|
|
1
|
+
require "rubycord/api"
|
2
|
+
require "rubycord/api/server"
|
3
|
+
require "rubycord/api/invite"
|
4
|
+
require "rubycord/api/user"
|
5
|
+
require "rubycord/data"
|
6
|
+
|
7
|
+
module Rubycord
|
8
|
+
# This mixin module does caching stuff for the library. It conveniently separates the logic behind
|
9
|
+
# the caching (like, storing the user hashes or making API calls to retrieve things) from the Bot that
|
10
|
+
# actually uses it.
|
11
|
+
module Cache
|
12
|
+
# Initializes this cache
|
13
|
+
def init_cache
|
14
|
+
@users = {}
|
15
|
+
|
16
|
+
@voice_regions = {}
|
17
|
+
|
18
|
+
@servers = {}
|
19
|
+
|
20
|
+
@channels = {}
|
21
|
+
@pm_channels = {}
|
22
|
+
@thread_members = {}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns or caches the available voice regions
|
26
|
+
def voice_regions
|
27
|
+
return @voice_regions unless @voice_regions.empty?
|
28
|
+
|
29
|
+
regions = JSON.parse API.voice_regions(token)
|
30
|
+
regions.each do |data|
|
31
|
+
@voice_regions[data["id"]] = VoiceRegion.new(data)
|
32
|
+
end
|
33
|
+
|
34
|
+
@voice_regions
|
35
|
+
end
|
36
|
+
|
37
|
+
# Gets a channel given its ID. This queries the internal channel cache, and if the channel doesn't
|
38
|
+
# exist in there, it will get the data from Discord.
|
39
|
+
# @param id [Integer] The channel ID for which to search for.
|
40
|
+
# @param server [Server] The server for which to search the channel for. If this isn't specified, it will be
|
41
|
+
# inferred using the API
|
42
|
+
# @return [Channel, nil] The channel identified by the ID.
|
43
|
+
# @raise Rubycord::Errors::NoPermission
|
44
|
+
def channel(id, server = nil)
|
45
|
+
id = id.resolve_id
|
46
|
+
|
47
|
+
debug("Obtaining data for channel with id #{id}")
|
48
|
+
return @channels[id] if @channels[id]
|
49
|
+
|
50
|
+
begin
|
51
|
+
response = API::Channel.resolve(token, id)
|
52
|
+
rescue Rubycord::Errors::UnknownChannel
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
channel = Channel.new(JSON.parse(response), self, server)
|
56
|
+
@channels[id] = channel
|
57
|
+
end
|
58
|
+
|
59
|
+
alias_method :group_channel, :channel
|
60
|
+
|
61
|
+
# Gets a user by its ID.
|
62
|
+
# @note This can only resolve users known by the bot (i.e. that share a server with the bot).
|
63
|
+
# @param id [Integer] The user ID that should be resolved.
|
64
|
+
# @return [User, nil] The user identified by the ID, or `nil` if it couldn't be found.
|
65
|
+
def user(id)
|
66
|
+
id = id.resolve_id
|
67
|
+
return @users[id] if @users[id]
|
68
|
+
|
69
|
+
LOGGER.out("Resolving user #{id}")
|
70
|
+
begin
|
71
|
+
response = API::User.resolve(token, id)
|
72
|
+
rescue Rubycord::Errors::UnknownUser
|
73
|
+
return nil
|
74
|
+
end
|
75
|
+
user = User.new(JSON.parse(response), self)
|
76
|
+
@users[id] = user
|
77
|
+
end
|
78
|
+
|
79
|
+
# Gets a server by its ID.
|
80
|
+
# @note This can only resolve servers the bot is currently in.
|
81
|
+
# @param id [Integer] The server ID that should be resolved.
|
82
|
+
# @return [Server, nil] The server identified by the ID, or `nil` if it couldn't be found.
|
83
|
+
def server(id)
|
84
|
+
id = id.resolve_id
|
85
|
+
return @servers[id] if @servers[id]
|
86
|
+
|
87
|
+
LOGGER.out("Resolving server #{id}")
|
88
|
+
begin
|
89
|
+
response = API::Server.resolve(token, id)
|
90
|
+
rescue Rubycord::Errors::NoPermission
|
91
|
+
return nil
|
92
|
+
end
|
93
|
+
server = Server.new(JSON.parse(response), self)
|
94
|
+
@servers[id] = server
|
95
|
+
end
|
96
|
+
|
97
|
+
# Gets a member by both IDs, or `Server` and user ID.
|
98
|
+
# @param server_or_id [Server, Integer] The `Server` or server ID for which a member should be resolved
|
99
|
+
# @param user_id [Integer] The ID of the user that should be resolved
|
100
|
+
# @return [Member, nil] The member identified by the IDs, or `nil` if none could be found
|
101
|
+
def member(server_or_id, user_id)
|
102
|
+
server_id = server_or_id.resolve_id
|
103
|
+
user_id = user_id.resolve_id
|
104
|
+
server = server_or_id.is_a?(Server) ? server_or_id : self.server(server_id)
|
105
|
+
|
106
|
+
return server.member(user_id) if server.member_cached?(user_id)
|
107
|
+
|
108
|
+
LOGGER.out("Resolving member #{server_id} on server #{user_id}")
|
109
|
+
begin
|
110
|
+
response = API::Server.resolve_member(token, server_id, user_id)
|
111
|
+
rescue Rubycord::Errors::UnknownUser, Rubycord::Errors::UnknownMember
|
112
|
+
return nil
|
113
|
+
end
|
114
|
+
member = Member.new(JSON.parse(response), server, self)
|
115
|
+
server.cache_member(member)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Creates a PM channel for the given user ID, or if one exists already, returns that one.
|
119
|
+
# It is recommended that you use {User#pm} instead, as this is mainly for internal use. However,
|
120
|
+
# usage of this method may be unavoidable if only the user ID is known.
|
121
|
+
# @param id [Integer] The user ID to generate a private channel for.
|
122
|
+
# @return [Channel] A private channel for that user.
|
123
|
+
def pm_channel(id)
|
124
|
+
id = id.resolve_id
|
125
|
+
return @pm_channels[id] if @pm_channels[id]
|
126
|
+
|
127
|
+
debug("Creating pm channel with user id #{id}")
|
128
|
+
response = API::User.create_pm(token, id)
|
129
|
+
channel = Channel.new(JSON.parse(response), self)
|
130
|
+
@pm_channels[id] = channel
|
131
|
+
end
|
132
|
+
|
133
|
+
alias_method :private_channel, :pm_channel
|
134
|
+
|
135
|
+
# Ensures a given user object is cached and if not, cache it from the given data hash.
|
136
|
+
# @param data [Hash] A data hash representing a user.
|
137
|
+
# @return [User] the user represented by the data hash.
|
138
|
+
def ensure_user(data)
|
139
|
+
if @users.include?(data["id"].to_i)
|
140
|
+
@users[data["id"].to_i]
|
141
|
+
else
|
142
|
+
@users[data["id"].to_i] = User.new(data, self)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Ensures a given server object is cached and if not, cache it from the given data hash.
|
147
|
+
# @param data [Hash] A data hash representing a server.
|
148
|
+
# @param force_cache [true, false] Whether the object in cache should be updated with the given
|
149
|
+
# data if it already exists.
|
150
|
+
# @return [Server] the server represented by the data hash.
|
151
|
+
def ensure_server(data, force_cache = false)
|
152
|
+
if @servers.include?(data["id"].to_i)
|
153
|
+
server = @servers[data["id"].to_i]
|
154
|
+
server.update_data(data) if force_cache
|
155
|
+
server
|
156
|
+
else
|
157
|
+
@servers[data["id"].to_i] = Server.new(data, self)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# Ensures a given channel object is cached and if not, cache it from the given data hash.
|
162
|
+
# @param data [Hash] A data hash representing a channel.
|
163
|
+
# @param server [Server, nil] The server the channel is on, if known.
|
164
|
+
# @return [Channel] the channel represented by the data hash.
|
165
|
+
def ensure_channel(data, server = nil)
|
166
|
+
if @channels.include?(data["id"].to_i)
|
167
|
+
@channels[data["id"].to_i]
|
168
|
+
else
|
169
|
+
@channels[data["id"].to_i] = Channel.new(data, self, server)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Ensures a given thread member object is cached.
|
174
|
+
# @param data [Hash] Thread member data.
|
175
|
+
def ensure_thread_member(data)
|
176
|
+
thread_id = data["id"].to_i
|
177
|
+
user_id = data["user_id"].to_i
|
178
|
+
|
179
|
+
@thread_members[thread_id] ||= {}
|
180
|
+
@thread_members[thread_id][user_id] = data.slice("join_timestamp", "flags")
|
181
|
+
end
|
182
|
+
|
183
|
+
# Requests member chunks for a given server ID.
|
184
|
+
# @param id [Integer] The server ID to request chunks for.
|
185
|
+
def request_chunks(id)
|
186
|
+
@gateway.send_request_members(id, "", 0)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Gets the code for an invite.
|
190
|
+
# @param invite [String, Invite] The invite to get the code for. Possible formats are:
|
191
|
+
#
|
192
|
+
# * An {Invite} object
|
193
|
+
# * The code for an invite
|
194
|
+
# * A fully qualified invite URL (e.g. `https://discord.com/invite/0A37aN7fasF7n83q`)
|
195
|
+
# * A short invite URL with protocol (e.g. `https://discord.gg/0A37aN7fasF7n83q`)
|
196
|
+
# * A short invite URL without protocol (e.g. `discord.gg/0A37aN7fasF7n83q`)
|
197
|
+
# @return [String] Only the code for the invite.
|
198
|
+
def resolve_invite_code(invite)
|
199
|
+
invite = invite.code if invite.is_a? Rubycord::Invite
|
200
|
+
invite = invite[invite.rindex("/") + 1..] if invite.start_with?("http", "discord.gg")
|
201
|
+
invite
|
202
|
+
end
|
203
|
+
|
204
|
+
# Gets information about an invite.
|
205
|
+
# @param invite [String, Invite] The invite to join. For possible formats see {#resolve_invite_code}.
|
206
|
+
# @return [Invite] The invite with information about the given invite URL.
|
207
|
+
def invite(invite)
|
208
|
+
code = resolve_invite_code(invite)
|
209
|
+
Invite.new(JSON.parse(API::Invite.resolve(token, code)), self)
|
210
|
+
end
|
211
|
+
|
212
|
+
# Finds a channel given its name and optionally the name of the server it is in.
|
213
|
+
# @param channel_name [String] The channel to search for.
|
214
|
+
# @param server_name [String] The server to search for, or `nil` if only the channel should be searched for.
|
215
|
+
# @param type [Integer, nil] The type of channel to search for (0: text, 1: private, 2: voice, 3: group), or `nil` if any type of
|
216
|
+
# channel should be searched for
|
217
|
+
# @return [Array<Channel>] The array of channels that were found. May be empty if none were found.
|
218
|
+
def find_channel(channel_name, server_name = nil, type: nil)
|
219
|
+
results = []
|
220
|
+
|
221
|
+
if /<#(?<id>\d+)>?/ =~ channel_name
|
222
|
+
# Check for channel mentions separately
|
223
|
+
return [channel(id)]
|
224
|
+
end
|
225
|
+
|
226
|
+
@servers.each_value do |server|
|
227
|
+
server.channels.each do |channel|
|
228
|
+
results << channel if channel.name == channel_name && (server_name || server.name) == server.name && (!type || (channel.type == type))
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
results
|
233
|
+
end
|
234
|
+
|
235
|
+
# Finds a user given its username or username & discriminator.
|
236
|
+
# @overload find_user(username)
|
237
|
+
# Find all cached users with a certain username.
|
238
|
+
# @param username [String] The username to look for.
|
239
|
+
# @return [Array<User>] The array of users that were found. May be empty if none were found.
|
240
|
+
# @overload find_user(username, discrim)
|
241
|
+
# Find a cached user with a certain username and discriminator.
|
242
|
+
# Find a user by name and discriminator
|
243
|
+
# @param username [String] The username to look for.
|
244
|
+
# @param discrim [String] The user's discriminator
|
245
|
+
# @return [User, nil] The user that was found, or `nil` if none was found
|
246
|
+
# @note This method only searches through users that have been cached. Users that have not yet been cached
|
247
|
+
# by the bot but still share a connection with the user (mutual server) will not be found.
|
248
|
+
# @example Find users by name
|
249
|
+
# bot.find_user('z64') #=> Array<User>
|
250
|
+
# @example Find a user by name and discriminator
|
251
|
+
# bot.find_user('z64', '2639') #=> User
|
252
|
+
def find_user(username, discrim = nil)
|
253
|
+
users = @users.values.find_all { |e| e.username == username }
|
254
|
+
return users.find { |u| u.discrim == discrim } if discrim
|
255
|
+
|
256
|
+
users
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Rubycord
|
2
|
+
# A colour (red, green and blue values). Used for role colours. If you prefer the American spelling, the alias
|
3
|
+
# {ColorRGB} is also available.
|
4
|
+
class ColourRGB
|
5
|
+
# @return [Integer] the red part of this colour (0-255).
|
6
|
+
attr_reader :red
|
7
|
+
|
8
|
+
# @return [Integer] the green part of this colour (0-255).
|
9
|
+
attr_reader :green
|
10
|
+
|
11
|
+
# @return [Integer] the blue part of this colour (0-255).
|
12
|
+
attr_reader :blue
|
13
|
+
|
14
|
+
# @return [Integer] the colour's RGB values combined into one integer.
|
15
|
+
attr_reader :combined
|
16
|
+
alias_method :to_i, :combined
|
17
|
+
|
18
|
+
# Make a new colour from the combined value.
|
19
|
+
# @param combined [String, Integer] The colour's RGB values combined into one integer or a hexadecimal string
|
20
|
+
# @example Initialize a with a base 10 integer
|
21
|
+
# ColourRGB.new(7506394) #=> ColourRGB
|
22
|
+
# ColourRGB.new(0x7289da) #=> ColourRGB
|
23
|
+
# @example Initialize a with a hexadecimal string
|
24
|
+
# ColourRGB.new('7289da') #=> ColourRGB
|
25
|
+
def initialize(combined)
|
26
|
+
@combined = combined.is_a?(String) ? combined.to_i(16) : combined
|
27
|
+
@red = (@combined >> 16) & 0xFF
|
28
|
+
@green = (@combined >> 8) & 0xFF
|
29
|
+
@blue = @combined & 0xFF
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [String] the colour as a hexadecimal.
|
33
|
+
def hex
|
34
|
+
@combined.to_s(16)
|
35
|
+
end
|
36
|
+
alias_method :hexadecimal, :hex
|
37
|
+
end
|
38
|
+
|
39
|
+
# Alias for the class {ColourRGB}
|
40
|
+
ColorRGB = ColourRGB
|
41
|
+
end
|