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