rubycord 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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,261 @@
1
+ module Rubycord
2
+ # Mixin for the attributes users should have
3
+ module UserAttributes
4
+ # Types of user's account flags mapped to their API value.
5
+ FLAGS = {
6
+ staff: 1 << 0,
7
+ partner: 1 << 1,
8
+ hypesquad: 1 << 2,
9
+ bug_hunter_level_1: 1 << 3,
10
+ hypesquad_online_house_1: 1 << 6,
11
+ hypesquad_online_house_2: 1 << 7,
12
+ hypesquad_online_house_3: 1 << 8,
13
+ premium_early_supporter: 1 << 9,
14
+ team_pseudo_user: 1 << 10,
15
+ bug_hunter_level_2: 1 << 14,
16
+ verified_bot: 1 << 16,
17
+ verified_developer: 1 << 17,
18
+ certified_moderator: 1 << 18,
19
+ bot_http_interactions: 1 << 19,
20
+ active_developer: 1 << 22
21
+ }.freeze
22
+
23
+ # @return [String] this user's username
24
+ attr_reader :username
25
+ alias_method :name, :username
26
+
27
+ # @return [String, nil] this user's global name
28
+ attr_reader :global_name
29
+
30
+ # @return [String] this user's discriminator which is used internally to identify users with identical usernames.
31
+ attr_reader :discriminator
32
+ alias_method :discrim, :discriminator
33
+ alias_method :tag, :discriminator
34
+ alias_method :discord_tag, :discriminator
35
+
36
+ # @return [true, false] whether this user is a Discord bot account
37
+ attr_reader :bot_account
38
+ alias_method :bot_account?, :bot_account
39
+
40
+ # @return [true, false] whether this is fake user for a webhook message
41
+ attr_reader :webhook_account
42
+ alias_method :webhook_account?, :webhook_account
43
+ alias_method :webhook?, :webhook_account
44
+
45
+ # @return [String] the ID of this user's current avatar, can be used to generate an avatar URL.
46
+ # @see #avatar_url
47
+ attr_accessor :avatar_id
48
+
49
+ # Utility function to get Discord's display name of a user not in server
50
+ # @return [String] the name the user displays as (global_name if they have one, username otherwise)
51
+ def display_name
52
+ global_name || username
53
+ end
54
+
55
+ # Utility function to mention users in messages
56
+ # @return [String] the mention code in the form of <@id>
57
+ def mention
58
+ "<@#{@id}>"
59
+ end
60
+
61
+ # Utility function to get Discord's distinct representation of a user, i.e. username + discriminator
62
+ # @return [String] distinct representation of user
63
+ # TODO: Maybe change this method again after discriminator removal ?
64
+ def distinct
65
+ if @discriminator && @discriminator != "0"
66
+ "#{@username}##{@discriminator}"
67
+ else
68
+ @username.to_s
69
+ end
70
+ end
71
+
72
+ # Utility function to get a user's avatar URL.
73
+ # @param format [String, nil] If `nil`, the URL will default to `webp` for static avatars, and will detect if the user has a `gif` avatar. You can otherwise specify one of `webp`, `jpg`, `png`, or `gif` to override this. Will always be PNG for default avatars.
74
+ # @return [String] the URL to the avatar image.
75
+ # TODO: Maybe change this method again after discriminator removal ?
76
+ def avatar_url(format = nil)
77
+ unless @avatar_id
78
+ return API::User.default_avatar(@discriminator, legacy: true) if @discriminator && @discriminator != "0"
79
+
80
+ return API::User.default_avatar(@id)
81
+ end
82
+
83
+ API::User.avatar_url(@id, @avatar_id, format)
84
+ end
85
+
86
+ # @return [Integer] the public flags on a user's account
87
+ attr_reader :public_flags
88
+
89
+ FLAGS.each do |name, value|
90
+ define_method(:"#{name}?") do
91
+ (@public_flags & value).positive?
92
+ end
93
+ end
94
+ end
95
+
96
+ # User on Discord, including internal data like discriminators
97
+ class User
98
+ include IDObject
99
+ include UserAttributes
100
+
101
+ # @return [Symbol] the current online status of the user (`:online`, `:offline` or `:idle`)
102
+ attr_reader :status
103
+
104
+ # @return [ActivitySet] the activities of the user
105
+ attr_reader :activities
106
+
107
+ # @return [Hash<Symbol, Symbol>] the current online status (`:online`, `:idle` or `:dnd`) of the user
108
+ # on various device types (`:desktop`, `:mobile`, or `:web`). The value will be `nil` if the user is offline or invisible.
109
+ attr_reader :client_status
110
+
111
+ # @!visibility private
112
+ def initialize(data, bot)
113
+ @bot = bot
114
+
115
+ @username = data["username"]
116
+ @global_name = data["global_name"]
117
+ @id = data["id"].to_i
118
+ @discriminator = data["discriminator"]
119
+ @avatar_id = data["avatar"]
120
+ @roles = {}
121
+ @activities = Rubycord::ActivitySet.new
122
+ @public_flags = data["public_flags"] || 0
123
+
124
+ @bot_account = false
125
+ @bot_account = true if data["bot"]
126
+
127
+ @webhook_account = false
128
+ @webhook_account = true if data["_webhook"]
129
+
130
+ @status = :offline
131
+ @client_status = process_client_status(data["client_status"])
132
+ end
133
+
134
+ # Get a user's PM channel or send them a PM
135
+ # @overload pm
136
+ # Creates a private message channel for this user or returns an existing one if it already exists
137
+ # @return [Channel] the PM channel to this user.
138
+ # @overload pm(content)
139
+ # Sends a private to this user.
140
+ # @param content [String] The content to send.
141
+ # @return [Message] the message sent to this user.
142
+ def pm(content = nil)
143
+ if content
144
+ # Recursively call pm to get the channel, then send a message to it
145
+ channel = pm
146
+ channel.send_message(content)
147
+ else
148
+ # If no message was specified, return the PM channel
149
+ @bot.pm_channel(@id)
150
+ end
151
+ end
152
+
153
+ alias_method :dm, :pm
154
+
155
+ # Send the user a file.
156
+ # @param file [File] The file to send to the user
157
+ # @param caption [String] The caption of the file being sent
158
+ # @param filename [String] Overrides the filename of the uploaded file
159
+ # @param spoiler [true, false] Whether or not this file should appear as a spoiler.
160
+ # @return [Message] the message sent to this user.
161
+ # @example Send a file from disk
162
+ # user.send_file(File.open('rubytaco.png', 'r'))
163
+ def send_file(file, caption = nil, filename: nil, spoiler: nil)
164
+ pm.send_file(file, caption: caption, filename: filename, spoiler: spoiler)
165
+ end
166
+
167
+ # Set the user's username
168
+ # @note for internal use only
169
+ # @!visibility private
170
+ def update_username(username)
171
+ @username = username
172
+ end
173
+
174
+ # Set the user's global_name
175
+ # @note For internal use only.
176
+ # @!visibility private
177
+ def update_global_name(global_name)
178
+ @global_name = global_name
179
+ end
180
+
181
+ # Set the user's presence data
182
+ # @note for internal use only
183
+ # @!visibility private
184
+ def update_presence(data)
185
+ @status = data["status"].to_sym
186
+ @client_status = process_client_status(data["client_status"])
187
+
188
+ @activities = Rubycord::ActivitySet.new(data["activities"].map { |act| Activity.new(act, @bot) })
189
+ end
190
+
191
+ # Add an await for a message from this user. Specifically, this adds a global await for a MessageEvent with this
192
+ # user's ID as a :from attribute.
193
+ # @see Bot#add_await
194
+ def await(key, attributes = {}, &)
195
+ @bot.add_await(key, Rubycord::Events::MessageEvent, {from: @id}.merge(attributes), &)
196
+ end
197
+
198
+ # Add a blocking await for a message from this user. Specifically, this adds a global await for a MessageEvent with this
199
+ # user's ID as a :from attribute.
200
+ # @see Bot#add_await!
201
+ def await!(attributes = {}, &)
202
+ @bot.add_await!(Rubycord::Events::MessageEvent, {from: @id}.merge(attributes), &)
203
+ end
204
+
205
+ # Gets the member this user is on a server
206
+ # @param server [Server] The server to get the member for
207
+ # @return [Member] this user as a member on a particular server
208
+ def on(server)
209
+ id = server.resolve_id
210
+ @bot.server(id).member(@id)
211
+ end
212
+
213
+ # Is the user the bot?
214
+ # @return [true, false] whether this user is the bot
215
+ def current_bot?
216
+ @bot.profile.id == @id
217
+ end
218
+
219
+ # @!visibility private
220
+ def process_client_status(client_status)
221
+ (client_status || {}).to_h { |k, v| [k.to_sym, v.to_sym] }
222
+ end
223
+
224
+ # @!method offline?
225
+ # @return [true, false] whether this user is offline.
226
+ # @!method idle?
227
+ # @return [true, false] whether this user is idle.
228
+ # @!method online?
229
+ # @return [true, false] whether this user is online.
230
+ # @!method dnd?
231
+ # @return [true, false] whether this user is set to do not disturb.
232
+ %i[offline idle online dnd].each do |e|
233
+ define_method(:"#{e}?") do
234
+ @status.to_sym == e
235
+ end
236
+ end
237
+
238
+ # @return [String, nil] the game the user is currently playing, or `nil` if nothing is being played.
239
+ # @deprecated Please use {ActivitySet#games} for information about the user's game activity
240
+ def game
241
+ @activities.games.first&.name
242
+ end
243
+
244
+ # @return [Integer] returns 1 for twitch streams, or 0 for no stream.
245
+ # @deprecated Please use {ActivitySet#streaming} for information about the user's stream activity
246
+ def stream_type
247
+ @activities.streaming ? 1 : 0
248
+ end
249
+
250
+ # @return [String, nil] the URL to the stream, if the user is currently streaming something
251
+ # @deprecated Please use {ActivitySet#streaming} for information about the user's stream activity
252
+ def stream_url
253
+ @activities.streaming.first&.url
254
+ end
255
+
256
+ # The inspect method is overwritten to give more useful output
257
+ def inspect
258
+ "<User username=#{@username} id=#{@id} discriminator=#{@discriminator}>"
259
+ end
260
+ end
261
+ end
@@ -0,0 +1,43 @@
1
+ module Rubycord
2
+ # Voice regions are the locations of servers that handle voice communication in Discord
3
+ class VoiceRegion
4
+ # @return [String] unique ID for the region
5
+ attr_reader :id
6
+ alias_method :to_s, :id
7
+
8
+ # @return [String] name of the region
9
+ attr_reader :name
10
+
11
+ # @return [String] an example hostname for the region
12
+ attr_reader :sample_hostname
13
+
14
+ # @return [Integer] an example port for the region
15
+ attr_reader :sample_port
16
+
17
+ # @return [true, false] if this is a VIP-only server
18
+ attr_reader :vip
19
+
20
+ # @return [true, false] if this voice server is the closest to the client
21
+ attr_reader :optimal
22
+
23
+ # @return [true, false] whether this is a deprecated voice region (avoid switching to these)
24
+ attr_reader :deprecated
25
+
26
+ # @return [true, false] whether this is a custom voice region (used for events/etc)
27
+ attr_reader :custom
28
+
29
+ def initialize(data)
30
+ @id = data["id"]
31
+
32
+ @name = data["name"]
33
+
34
+ @sample_hostname = data["sample_hostname"]
35
+ @sample_port = data["sample_port"]
36
+
37
+ @vip = data["vip"]
38
+ @optimal = data["optimal"]
39
+ @deprecated = data["deprecated"]
40
+ @custom = data["custom"]
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,39 @@
1
+ module Rubycord
2
+ # A voice state represents the state of a member's connection to a voice channel. It includes data like the voice
3
+ # channel the member is connected to and mute/deaf flags.
4
+ class VoiceState
5
+ # @return [Integer] the ID of the user whose voice state is represented by this object.
6
+ attr_reader :user_id
7
+
8
+ # @return [true, false] whether this voice state's member is muted server-wide.
9
+ attr_reader :mute
10
+
11
+ # @return [true, false] whether this voice state's member is deafened server-wide.
12
+ attr_reader :deaf
13
+
14
+ # @return [true, false] whether this voice state's member has muted themselves.
15
+ attr_reader :self_mute
16
+
17
+ # @return [true, false] whether this voice state's member has deafened themselves.
18
+ attr_reader :self_deaf
19
+
20
+ # @return [Channel] the voice channel this voice state's member is in.
21
+ attr_reader :voice_channel
22
+
23
+ # @!visibility private
24
+ def initialize(user_id)
25
+ @user_id = user_id
26
+ end
27
+
28
+ # Update this voice state with new data from Discord
29
+ # @note For internal use only.
30
+ # @!visibility private
31
+ def update(channel, mute, deaf, self_mute, self_deaf)
32
+ @voice_channel = channel
33
+ @mute = mute
34
+ @deaf = deaf
35
+ @self_mute = self_mute
36
+ @self_deaf = self_deaf
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,232 @@
1
+ require "rubycord/webhooks/builder"
2
+ require "rubycord/webhooks/view"
3
+
4
+ module Rubycord
5
+ # A webhook on a server channel
6
+ class Webhook
7
+ include IDObject
8
+
9
+ # @return [String] the webhook name.
10
+ attr_reader :name
11
+
12
+ # @return [Channel] the channel that the webhook is currently connected to.
13
+ attr_reader :channel
14
+
15
+ # @return [Server] the server that the webhook is currently connected to.
16
+ attr_reader :server
17
+
18
+ # @return [String, nil] the webhook's token, if this is an Incoming Webhook.
19
+ attr_reader :token
20
+
21
+ # @return [String] the webhook's avatar id.
22
+ attr_reader :avatar
23
+
24
+ # @return [Integer] the webhook's type (1: Incoming, 2: Channel Follower)
25
+ attr_reader :type
26
+
27
+ # Gets the user object of the creator of the webhook. May be limited to username, discriminator,
28
+ # ID and avatar if the bot cannot reach the owner
29
+ # @return [Member, User, nil] the user object of the owner or nil if the webhook was requested using the token.
30
+ attr_reader :owner
31
+
32
+ def initialize(data, bot)
33
+ @bot = bot
34
+
35
+ @name = data["name"]
36
+ @id = data["id"].to_i
37
+ @channel = bot.channel(data["channel_id"])
38
+ @server = @channel.server
39
+ @token = data["token"]
40
+ @avatar = data["avatar"]
41
+ @type = data["type"]
42
+
43
+ # Will not exist if the data was requested through a webhook token
44
+ return unless data["user"]
45
+
46
+ @owner = @server.member(data["user"]["id"].to_i)
47
+ return if @owner
48
+
49
+ Rubycord::LOGGER.debug("Member with ID #{data["user"]["id"]} not cached (possibly left the server).")
50
+ @owner = @bot.ensure_user(data["user"])
51
+ end
52
+
53
+ # Sets the webhook's avatar.
54
+ # @param avatar [String, #read] The new avatar, in base64-encoded JPG format.
55
+ def avatar=(avatar)
56
+ update_webhook(avatar: avatarise(avatar))
57
+ end
58
+
59
+ # Deletes the webhook's avatar.
60
+ def delete_avatar
61
+ update_webhook(avatar: nil)
62
+ end
63
+
64
+ # Sets the webhook's channel
65
+ # @param channel [Channel, String, Integer] The channel the webhook should use.
66
+ def channel=(channel)
67
+ update_webhook(channel_id: channel.resolve_id)
68
+ end
69
+
70
+ # Sets the webhook's name.
71
+ # @param name [String] The webhook's new name.
72
+ def name=(name)
73
+ update_webhook(name: name)
74
+ end
75
+
76
+ # Updates the webhook if you need to edit more than 1 attribute.
77
+ # @param data [Hash] the data to update.
78
+ # @option data [String, #read, nil] :avatar The new avatar, in base64-encoded JPG format, or nil to delete the avatar.
79
+ # @option data [Channel, String, Integer] :channel The channel the webhook should use.
80
+ # @option data [String] :name The webhook's new name.
81
+ # @option data [String] :reason The reason for the webhook changes.
82
+ def update(data)
83
+ # Only pass a value for avatar if the key is defined as sending nil will delete the
84
+ data[:avatar] = avatarise(data[:avatar]) if data.key?(:avatar)
85
+ data[:channel_id] = data[:channel]&.resolve_id
86
+ data.delete(:channel)
87
+ update_webhook(data)
88
+ end
89
+
90
+ # Deletes the webhook.
91
+ # @param reason [String] The reason the webhook is being deleted.
92
+ def delete(reason = nil)
93
+ if token?
94
+ API::Webhook.token_delete_webhook(@token, @id, reason)
95
+ else
96
+ API::Webhook.delete_webhook(@bot.token, @id, reason)
97
+ end
98
+ end
99
+
100
+ # Execute a webhook.
101
+ # @param content [String] The content of the message. May be 2000 characters long at most.
102
+ # @param username [String] The username the webhook will display as. If this is not set, the default username set in the webhook's settings.
103
+ # @param avatar_url [String] The URL of an image file to be used as an avatar. If this is not set, the default avatar from the webhook's
104
+ # @param tts [true, false] Whether this message should use TTS or not. By default, it doesn't.
105
+ # @param file [File] File to be sent together with the message. Mutually exclusive with embeds; a webhook message can contain
106
+ # either a file to be sent or embeds.
107
+ # @param embeds [Array<Webhooks::Embed, Hash>] Embeds to attach to this message.
108
+ # @param allowed_mentions [AllowedMentions, Hash] Mentions that are allowed to ping in the `content`.
109
+ # @param wait [true, false] Whether Discord should wait for the message to be successfully received by clients, or
110
+ # whether it should return immediately after sending the message. If `true` a {Message} object will be returned.
111
+ # @yield [builder] Gives the builder to the block to add additional steps, or to do the entire building process.
112
+ # @yieldparam builder [Builder] The builder given as a parameter which is used as the initial step to start from.
113
+ # @example Execute the webhook with kwargs
114
+ # client.execute(
115
+ # content: 'Testing',
116
+ # username: 'rubycord',
117
+ # embeds: [
118
+ # { timestamp: Time.now.iso8601, title: 'testing', image: { url: 'https://i.imgur.com/PcMltU7.jpg' } }
119
+ # ])
120
+ # @example Execute the webhook with an already existing builder
121
+ # builder = Rubycord::Webhooks::Builder.new # ...
122
+ # client.execute(builder)
123
+ # @example Execute the webhook by building a new message
124
+ # client.execute do |builder|
125
+ # builder.content = 'Testing'
126
+ # builder.username = 'rubycord'
127
+ # builder.add_embed do |embed|
128
+ # embed.timestamp = Time.now
129
+ # embed.title = 'Testing'
130
+ # embed.image = Rubycord::Webhooks::EmbedImage.new(url: 'https://i.imgur.com/PcMltU7.jpg')
131
+ # end
132
+ # end
133
+ # @return [Message, nil] If `wait` is `true`, a {Message} will be returned. Otherwise this method will return `nil`.
134
+ # @note This is only available to webhooks with publically exposed tokens. This excludes channel follow webhooks and webhooks retrieved
135
+ # via the audit log.
136
+ def execute(content: nil, username: nil, avatar_url: nil, tts: nil, file: nil, embeds: nil, allowed_mentions: nil, wait: true, builder: nil, components: nil)
137
+ raise Rubycord::Errors::UnauthorizedWebhook unless @token
138
+
139
+ params = {content: content, username: username, avatar_url: avatar_url, tts: tts, file: file, embeds: embeds, allowed_mentions: allowed_mentions}
140
+
141
+ builder ||= Webhooks::Builder.new
142
+ view = Webhooks::View.new
143
+
144
+ yield(builder, view) if block_given?
145
+
146
+ data = builder.to_json_hash.merge(params.compact)
147
+ components ||= view
148
+
149
+ resp = API::Webhook.token_execute_webhook(@token, @id, wait, data[:content], data[:username], data[:avatar_url], data[:tts], data[:file], data[:embeds], data[:allowed_mentions], nil, components.to_a)
150
+
151
+ Message.new(JSON.parse(resp), @bot) if wait
152
+ end
153
+
154
+ # Delete a message created by this webhook.
155
+ # @param message [Message, String, Integer] The ID of the message to delete.
156
+ def delete_message(message)
157
+ raise Rubycord::Errors::UnauthorizedWebhook unless @token
158
+
159
+ API::Webhook.token_delete_message(@token, @id, message.resolve_id)
160
+ end
161
+
162
+ # Edit a message created by this webhook.
163
+ # @param message [Message, String, Integer] The ID of the message to edit.
164
+ # @param content [String] The content of the message. May be 2000 characters long at most.
165
+ # @param embeds [Array<Webhooks::Embed, Hash>] Embeds to be attached to the message.
166
+ # @param allowed_mentions [AllowedMentions, Hash] Mentions that are allowed to ping in the `content`.
167
+ # @param builder [Builder, nil] The builder to start out with, or nil if one should be created anew.
168
+ # @yield [builder] Gives the builder to the block to add additional steps, or to do the entire building process.
169
+ # @yieldparam builder [Webhooks::Builder] The builder given as a parameter which is used as the initial step to start from.
170
+ # @return [Message] The updated message.
171
+ # @param components [View, Array<Hash>] Interaction components to associate with this message.
172
+ # @note When editing `allowed_mentions`, it will update visually in the client but not alert the user with a notification.
173
+ def edit_message(message, content: nil, embeds: nil, allowed_mentions: nil, builder: nil, components: nil)
174
+ raise Rubycord::Errors::UnauthorizedWebhook unless @token
175
+
176
+ params = {content: content, embeds: embeds, allowed_mentions: allowed_mentions}.compact
177
+
178
+ builder ||= Webhooks::Builder.new
179
+ view ||= Webhooks::View.new
180
+
181
+ yield(builder, view) if block_given?
182
+
183
+ data = builder.to_json_hash.merge(params.compact)
184
+ components ||= view
185
+
186
+ resp = API::Webhook.token_edit_message(@token, @id, message.resolve_id, data[:content], data[:embeds], data[:allowed_mentions], components.to_a)
187
+ Message.new(JSON.parse(resp), @bot)
188
+ end
189
+
190
+ # Utility function to get a webhook's avatar URL.
191
+ # @return [String] the URL to the avatar image
192
+ def avatar_url
193
+ return API::User.default_avatar(@id) unless @avatar
194
+
195
+ API::User.avatar_url(@id, @avatar)
196
+ end
197
+
198
+ # The `inspect` method is overwritten to give more useful output.
199
+ def inspect
200
+ "<Webhook name=#{@name} id=#{@id}>"
201
+ end
202
+
203
+ # Utility function to know if the webhook was requested through a webhook token, rather than auth.
204
+ # @return [true, false] whether the webhook was requested by token or not.
205
+ def token?
206
+ @owner.nil?
207
+ end
208
+
209
+ private
210
+
211
+ def avatarise(avatar)
212
+ if avatar.respond_to? :read
213
+ "data:image/jpg;base64,#{Base64.strict_encode64(avatar.read)}"
214
+ else
215
+ avatar
216
+ end
217
+ end
218
+
219
+ def update_internal(data)
220
+ @name = data["name"]
221
+ @avatar_id = data["avatar"]
222
+ @channel = @bot.channel(data["channel_id"])
223
+ end
224
+
225
+ def update_webhook(new_data)
226
+ reason = new_data.delete(:reason)
227
+ data = JSON.parse(token? ? API::Webhook.token_update_webhook(@token, @id, new_data, reason) : API::Webhook.update_webhook(@bot.token, @id, new_data, reason))
228
+ # Only update cache if API call worked
229
+ update_internal(data) if data["name"]
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,40 @@
1
+ require "rubycord/allowed_mentions"
2
+ require "rubycord/permissions"
3
+ require "rubycord/id_object"
4
+ require "rubycord/colour_rgb"
5
+ require "rubycord/errors"
6
+ require "rubycord/api"
7
+ require "rubycord/api/channel"
8
+ require "rubycord/api/server"
9
+ require "rubycord/api/invite"
10
+ require "rubycord/api/user"
11
+ require "rubycord/api/webhook"
12
+ require "rubycord/webhooks/embeds"
13
+ require "rubycord/webhooks/view"
14
+ require "rubycord/paginator"
15
+ require "time"
16
+ require "base64"
17
+
18
+ require "rubycord/data/activity"
19
+ require "rubycord/data/application"
20
+ require "rubycord/data/user"
21
+ require "rubycord/data/voice_state"
22
+ require "rubycord/data/voice_region"
23
+ require "rubycord/data/member"
24
+ require "rubycord/data/recipient"
25
+ require "rubycord/data/profile"
26
+ require "rubycord/data/role"
27
+ require "rubycord/data/invite"
28
+ require "rubycord/data/overwrite"
29
+ require "rubycord/data/channel"
30
+ require "rubycord/data/embed"
31
+ require "rubycord/data/attachment"
32
+ require "rubycord/data/message"
33
+ require "rubycord/data/reaction"
34
+ require "rubycord/data/emoji"
35
+ require "rubycord/data/integration"
36
+ require "rubycord/data/server"
37
+ require "rubycord/data/webhook"
38
+ require "rubycord/data/audit_logs"
39
+ require "rubycord/data/interaction"
40
+ require "rubycord/data/component"