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.
Files changed (88) hide show
  1. checksums.yaml +7 -0
  2. data/lib/rubycord/allowed_mentions.rb +34 -0
  3. data/lib/rubycord/api/application.rb +200 -0
  4. data/lib/rubycord/api/channel.rb +597 -0
  5. data/lib/rubycord/api/interaction.rb +52 -0
  6. data/lib/rubycord/api/invite.rb +42 -0
  7. data/lib/rubycord/api/server.rb +557 -0
  8. data/lib/rubycord/api/user.rb +153 -0
  9. data/lib/rubycord/api/webhook.rb +138 -0
  10. data/lib/rubycord/api.rb +356 -0
  11. data/lib/rubycord/await.rb +49 -0
  12. data/lib/rubycord/bot.rb +1757 -0
  13. data/lib/rubycord/cache.rb +259 -0
  14. data/lib/rubycord/colour_rgb.rb +41 -0
  15. data/lib/rubycord/commands/command_bot.rb +519 -0
  16. data/lib/rubycord/commands/container.rb +110 -0
  17. data/lib/rubycord/commands/events.rb +9 -0
  18. data/lib/rubycord/commands/parser.rb +325 -0
  19. data/lib/rubycord/commands/rate_limiter.rb +142 -0
  20. data/lib/rubycord/container.rb +753 -0
  21. data/lib/rubycord/data/activity.rb +269 -0
  22. data/lib/rubycord/data/application.rb +48 -0
  23. data/lib/rubycord/data/attachment.rb +109 -0
  24. data/lib/rubycord/data/audit_logs.rb +343 -0
  25. data/lib/rubycord/data/channel.rb +996 -0
  26. data/lib/rubycord/data/component.rb +227 -0
  27. data/lib/rubycord/data/embed.rb +249 -0
  28. data/lib/rubycord/data/emoji.rb +80 -0
  29. data/lib/rubycord/data/integration.rb +120 -0
  30. data/lib/rubycord/data/interaction.rb +798 -0
  31. data/lib/rubycord/data/invite.rb +135 -0
  32. data/lib/rubycord/data/member.rb +370 -0
  33. data/lib/rubycord/data/message.rb +412 -0
  34. data/lib/rubycord/data/overwrite.rb +106 -0
  35. data/lib/rubycord/data/profile.rb +89 -0
  36. data/lib/rubycord/data/reaction.rb +31 -0
  37. data/lib/rubycord/data/recipient.rb +32 -0
  38. data/lib/rubycord/data/role.rb +246 -0
  39. data/lib/rubycord/data/server.rb +1002 -0
  40. data/lib/rubycord/data/user.rb +261 -0
  41. data/lib/rubycord/data/voice_region.rb +43 -0
  42. data/lib/rubycord/data/voice_state.rb +39 -0
  43. data/lib/rubycord/data/webhook.rb +232 -0
  44. data/lib/rubycord/data.rb +40 -0
  45. data/lib/rubycord/errors.rb +737 -0
  46. data/lib/rubycord/events/await.rb +46 -0
  47. data/lib/rubycord/events/bans.rb +58 -0
  48. data/lib/rubycord/events/channels.rb +186 -0
  49. data/lib/rubycord/events/generic.rb +126 -0
  50. data/lib/rubycord/events/guilds.rb +191 -0
  51. data/lib/rubycord/events/interactions.rb +480 -0
  52. data/lib/rubycord/events/invites.rb +123 -0
  53. data/lib/rubycord/events/lifetime.rb +29 -0
  54. data/lib/rubycord/events/members.rb +91 -0
  55. data/lib/rubycord/events/message.rb +337 -0
  56. data/lib/rubycord/events/presence.rb +127 -0
  57. data/lib/rubycord/events/raw.rb +45 -0
  58. data/lib/rubycord/events/reactions.rb +156 -0
  59. data/lib/rubycord/events/roles.rb +86 -0
  60. data/lib/rubycord/events/threads.rb +94 -0
  61. data/lib/rubycord/events/typing.rb +70 -0
  62. data/lib/rubycord/events/voice_server_update.rb +45 -0
  63. data/lib/rubycord/events/voice_state_update.rb +103 -0
  64. data/lib/rubycord/events/webhooks.rb +62 -0
  65. data/lib/rubycord/gateway.rb +867 -0
  66. data/lib/rubycord/id_object.rb +37 -0
  67. data/lib/rubycord/light/data.rb +60 -0
  68. data/lib/rubycord/light/integrations.rb +71 -0
  69. data/lib/rubycord/light/light_bot.rb +56 -0
  70. data/lib/rubycord/light.rb +6 -0
  71. data/lib/rubycord/logger.rb +118 -0
  72. data/lib/rubycord/paginator.rb +55 -0
  73. data/lib/rubycord/permissions.rb +251 -0
  74. data/lib/rubycord/version.rb +5 -0
  75. data/lib/rubycord/voice/encoder.rb +113 -0
  76. data/lib/rubycord/voice/network.rb +366 -0
  77. data/lib/rubycord/voice/sodium.rb +96 -0
  78. data/lib/rubycord/voice/voice_bot.rb +408 -0
  79. data/lib/rubycord/webhooks/builder.rb +100 -0
  80. data/lib/rubycord/webhooks/client.rb +132 -0
  81. data/lib/rubycord/webhooks/embeds.rb +248 -0
  82. data/lib/rubycord/webhooks/modal.rb +78 -0
  83. data/lib/rubycord/webhooks/version.rb +7 -0
  84. data/lib/rubycord/webhooks/view.rb +192 -0
  85. data/lib/rubycord/webhooks.rb +12 -0
  86. data/lib/rubycord/websocket.rb +70 -0
  87. data/lib/rubycord.rb +140 -0
  88. 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