djs-selfbot-v13 3.1.6 → 3.1.7

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 (148) hide show
  1. package/README.md +31 -16
  2. package/package.json +15 -8
  3. package/src/client/BaseClient.js +3 -2
  4. package/src/client/Client.js +539 -187
  5. package/src/client/actions/Action.js +13 -18
  6. package/src/client/actions/ActionsManager.js +1 -7
  7. package/src/client/actions/AutoModerationActionExecution.js +0 -1
  8. package/src/client/actions/AutoModerationRuleCreate.js +0 -1
  9. package/src/client/actions/AutoModerationRuleDelete.js +0 -1
  10. package/src/client/actions/AutoModerationRuleUpdate.js +0 -1
  11. package/src/client/actions/InteractionCreate.js +115 -0
  12. package/src/client/actions/MessageCreate.js +4 -0
  13. package/src/client/actions/PresenceUpdate.js +16 -17
  14. package/src/client/websocket/WebSocketManager.js +31 -11
  15. package/src/client/websocket/WebSocketShard.js +38 -39
  16. package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +23 -0
  17. package/src/client/websocket/handlers/CALL_CREATE.js +3 -3
  18. package/src/client/websocket/handlers/CALL_DELETE.js +2 -2
  19. package/src/client/websocket/handlers/CALL_UPDATE.js +2 -2
  20. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +13 -16
  21. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
  22. package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +11 -0
  23. package/src/client/websocket/handlers/GUILD_CREATE.js +0 -7
  24. package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +55 -0
  25. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
  26. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
  27. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
  28. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
  29. package/src/client/websocket/handlers/INTERACTION_CREATE.js +16 -0
  30. package/src/client/websocket/handlers/INTERACTION_FAILURE.js +18 -0
  31. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +0 -1
  32. package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +30 -0
  33. package/src/client/websocket/handlers/MESSAGE_ACK.js +16 -0
  34. package/src/client/websocket/handlers/READY.js +137 -47
  35. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +5 -7
  36. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +4 -6
  37. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +9 -32
  38. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
  39. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +8 -2
  40. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
  41. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +5 -1
  42. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
  43. package/src/client/websocket/handlers/index.js +20 -15
  44. package/src/errors/Messages.js +69 -24
  45. package/src/index.js +43 -12
  46. package/src/managers/ApplicationCommandManager.js +12 -9
  47. package/src/managers/ApplicationCommandPermissionsManager.js +11 -3
  48. package/src/managers/ChannelManager.js +4 -2
  49. package/src/managers/ClientUserSettingManager.js +279 -161
  50. package/src/managers/DeveloperPortalManager.js +104 -0
  51. package/src/managers/GuildApplicationCommandManager.js +28 -0
  52. package/src/managers/GuildBanManager.js +1 -1
  53. package/src/managers/GuildChannelManager.js +0 -2
  54. package/src/managers/GuildFolderManager.js +24 -0
  55. package/src/managers/GuildForumThreadManager.js +28 -22
  56. package/src/managers/GuildMemberManager.js +216 -40
  57. package/src/managers/GuildSettingManager.js +15 -22
  58. package/src/managers/MessageManager.js +44 -42
  59. package/src/managers/PermissionOverwriteManager.js +1 -1
  60. package/src/managers/ReactionUserManager.js +5 -5
  61. package/src/managers/RelationshipManager.js +74 -81
  62. package/src/managers/SessionManager.js +57 -0
  63. package/src/managers/ThreadManager.js +45 -12
  64. package/src/managers/ThreadMemberManager.js +1 -1
  65. package/src/managers/UserManager.js +10 -6
  66. package/src/rest/APIRequest.js +20 -42
  67. package/src/rest/CaptchaSolver.js +132 -0
  68. package/src/rest/DiscordAPIError.js +16 -17
  69. package/src/rest/RESTManager.js +21 -1
  70. package/src/rest/RequestHandler.js +21 -35
  71. package/src/structures/ApplicationCommand.js +456 -19
  72. package/src/structures/ApplicationRoleConnectionMetadata.js +0 -3
  73. package/src/structures/AutoModerationRule.js +5 -5
  74. package/src/structures/AutocompleteInteraction.js +0 -1
  75. package/src/structures/BaseGuildTextChannel.js +12 -10
  76. package/src/structures/BaseGuildVoiceChannel.js +18 -16
  77. package/src/structures/{CallState.js → Call.js} +12 -17
  78. package/src/structures/CategoryChannel.js +0 -2
  79. package/src/structures/Channel.js +3 -2
  80. package/src/structures/ClientApplication.js +204 -0
  81. package/src/structures/ClientPresence.js +8 -12
  82. package/src/structures/ClientUser.js +336 -117
  83. package/src/structures/ContextMenuInteraction.js +1 -1
  84. package/src/structures/DMChannel.js +92 -29
  85. package/src/structures/DeveloperPortalApplication.js +520 -0
  86. package/src/structures/ForumChannel.js +10 -0
  87. package/src/structures/Guild.js +271 -135
  88. package/src/structures/GuildAuditLogs.js +5 -0
  89. package/src/structures/GuildChannel.js +2 -16
  90. package/src/structures/GuildFolder.js +75 -0
  91. package/src/structures/GuildMember.js +145 -27
  92. package/src/structures/Interaction.js +62 -1
  93. package/src/structures/InteractionResponse.js +114 -0
  94. package/src/structures/Invite.js +52 -35
  95. package/src/structures/Message.js +202 -222
  96. package/src/structures/MessageAttachment.js +0 -11
  97. package/src/structures/MessageButton.js +67 -1
  98. package/src/structures/MessageEmbed.js +1 -1
  99. package/src/structures/MessageMentions.js +2 -3
  100. package/src/structures/MessagePayload.js +46 -4
  101. package/src/structures/MessageReaction.js +1 -1
  102. package/src/structures/MessageSelectMenu.js +252 -1
  103. package/src/structures/Modal.js +180 -75
  104. package/src/structures/PartialGroupDMChannel.js +433 -0
  105. package/src/structures/Presence.js +2 -2
  106. package/src/structures/RichPresence.js +34 -14
  107. package/src/structures/Role.js +2 -18
  108. package/src/structures/SelectMenuInteraction.js +151 -2
  109. package/src/structures/Session.js +81 -0
  110. package/src/structures/Team.js +49 -0
  111. package/src/structures/TextInputComponent.js +70 -0
  112. package/src/structures/ThreadChannel.js +19 -0
  113. package/src/structures/User.js +345 -117
  114. package/src/structures/UserContextMenuInteraction.js +2 -2
  115. package/src/structures/VoiceState.js +39 -74
  116. package/src/structures/WebEmbed.js +52 -38
  117. package/src/structures/Webhook.js +11 -17
  118. package/src/structures/interfaces/Application.js +23 -146
  119. package/src/structures/interfaces/TextBasedChannel.js +256 -411
  120. package/src/util/ApplicationFlags.js +1 -1
  121. package/src/util/Constants.js +284 -106
  122. package/src/util/Formatters.js +2 -16
  123. package/src/util/LimitedCollection.js +1 -1
  124. package/src/util/Options.js +68 -48
  125. package/src/util/Permissions.js +0 -5
  126. package/src/util/PurchasedFlags.js +0 -2
  127. package/src/util/RemoteAuth.js +356 -221
  128. package/src/util/Sweepers.js +1 -1
  129. package/src/util/Util.js +36 -76
  130. package/src/util/Voice.js +1456 -0
  131. package/src/util/arRPC/index.js +229 -0
  132. package/src/util/arRPC/process/detectable.json +1 -0
  133. package/src/util/arRPC/process/index.js +102 -0
  134. package/src/util/arRPC/process/native/index.js +5 -0
  135. package/src/util/arRPC/process/native/linux.js +37 -0
  136. package/src/util/arRPC/process/native/win32.js +25 -0
  137. package/src/util/arRPC/transports/ipc.js +281 -0
  138. package/src/util/arRPC/transports/websocket.js +128 -0
  139. package/typings/enums.d.ts +73 -18
  140. package/typings/index.d.ts +1249 -897
  141. package/typings/rawDataTypes.d.ts +9 -68
  142. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +0 -78
  143. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +0 -12
  144. package/src/managers/UserNoteManager.js +0 -53
  145. package/src/structures/GroupDMChannel.js +0 -387
  146. package/src/util/AttachmentFlags.js +0 -38
  147. package/src/util/InviteFlags.js +0 -29
  148. package/src/util/RoleFlags.js +0 -37
@@ -86,15 +86,11 @@ class VoiceState extends Base {
86
86
 
87
87
  // The self_stream is property is omitted if false, check for another property
88
88
  // here to avoid incorrectly clearing this when partial data is specified
89
- if ('self_stream' in data) {
90
- /**
91
- * Whether this member is streaming using "Screen Share"
92
- * @type {boolean}
93
- */
94
- this.streaming = data.self_stream ?? false;
95
- } else {
96
- this.streaming ??= null;
97
- }
89
+ /**
90
+ * Whether this member is streaming using "Screen Share"
91
+ * @type {boolean}
92
+ */
93
+ this.streaming = data.self_stream ?? false;
98
94
 
99
95
  if ('channel_id' in data) {
100
96
  /**
@@ -148,11 +144,12 @@ class VoiceState extends Base {
148
144
 
149
145
  /**
150
146
  * The channel that the member is connected to
151
- * @type {?(VoiceChannel|StageChannel|DMChannel|GroupDMChannel)}
147
+ * @type {?(VoiceChannel|StageChannel)}
152
148
  * @readonly
153
149
  */
154
150
  get channel() {
155
- return (this.guild || this.client).channels.cache.get(this.channelId) ?? null;
151
+ if (!this.guild?.id) return this.guild.client.channels.cache.get(this.channelId) ?? null;
152
+ return this.guild.channels.cache.get(this.channelId) ?? null;
156
153
  }
157
154
 
158
155
  /**
@@ -180,6 +177,7 @@ class VoiceState extends Base {
180
177
  * @returns {Promise<GuildMember>}
181
178
  */
182
179
  setMute(mute = true, reason) {
180
+ if (!this.guild?.id) return null;
183
181
  return this.guild.members.edit(this.id, { mute }, reason);
184
182
  }
185
183
 
@@ -190,6 +188,7 @@ class VoiceState extends Base {
190
188
  * @returns {Promise<GuildMember>}
191
189
  */
192
190
  setDeaf(deaf = true, reason) {
191
+ if (!this.guild?.id) return null;
193
192
  return this.guild.members.edit(this.id, { deaf }, reason);
194
193
  }
195
194
 
@@ -199,6 +198,7 @@ class VoiceState extends Base {
199
198
  * @returns {Promise<GuildMember>}
200
199
  */
201
200
  disconnect(reason) {
201
+ if (!this.guild?.id) return this.callVoice?.disconnect();
202
202
  return this.setChannel(null, reason);
203
203
  }
204
204
 
@@ -210,6 +210,7 @@ class VoiceState extends Base {
210
210
  * @returns {Promise<GuildMember>}
211
211
  */
212
212
  setChannel(channel, reason) {
213
+ if (!this.guild?.id) return null;
213
214
  return this.guild.members.edit(this.id, { channel }, reason);
214
215
  }
215
216
 
@@ -226,16 +227,18 @@ class VoiceState extends Base {
226
227
  * @returns {Promise<void>}
227
228
  */
228
229
  async setRequestToSpeak(request = true) {
229
- if (this.channel?.type !== 'GUILD_STAGE_VOICE') throw new Error('VOICE_NOT_STAGE_CHANNEL');
230
+ if (this.guild?.id) {
231
+ if (this.channel?.type !== 'GUILD_STAGE_VOICE') throw new Error('VOICE_NOT_STAGE_CHANNEL');
230
232
 
231
- if (this.client.user.id !== this.id) throw new Error('VOICE_STATE_NOT_OWN');
233
+ if (this.client.user.id !== this.id) throw new Error('VOICE_STATE_NOT_OWN');
232
234
 
233
- await this.client.api.guilds(this.guild.id, 'voice-states', '@me').patch({
234
- data: {
235
- channel_id: this.channelId,
236
- request_to_speak_timestamp: request ? new Date().toISOString() : null,
237
- },
238
- });
235
+ await this.client.api.guilds(this.guild.id, 'voice-states', '@me').patch({
236
+ data: {
237
+ channel_id: this.channelId,
238
+ request_to_speak_timestamp: request ? new Date().toISOString() : null,
239
+ },
240
+ });
241
+ }
239
242
  }
240
243
 
241
244
  /**
@@ -256,75 +259,37 @@ class VoiceState extends Base {
256
259
  * @returns {Promise<void>}
257
260
  */
258
261
  async setSuppressed(suppressed = true) {
259
- if (typeof suppressed !== 'boolean') throw new TypeError('VOICE_STATE_INVALID_TYPE', 'suppressed');
262
+ if (this.guild?.id) {
263
+ if (typeof suppressed !== 'boolean') throw new TypeError('VOICE_STATE_INVALID_TYPE', 'suppressed');
260
264
 
261
- if (this.channel?.type !== 'GUILD_STAGE_VOICE') throw new Error('VOICE_NOT_STAGE_CHANNEL');
265
+ if (this.channel?.type !== 'GUILD_STAGE_VOICE') throw new Error('VOICE_NOT_STAGE_CHANNEL');
262
266
 
263
- const target = this.client.user.id === this.id ? '@me' : this.id;
267
+ const target = this.client.user.id === this.id ? '@me' : this.id;
264
268
 
265
- await this.client.api.guilds(this.guild.id, 'voice-states', target).patch({
266
- data: {
267
- channel_id: this.channelId,
268
- suppress: suppressed,
269
- request_to_speak_timestamp: null,
270
- },
271
- });
272
- }
273
-
274
- /**
275
- * Sets the status of the voice channel
276
- * @param {string} [status=""] The message to set the channel status to
277
- * @example
278
- * // Setting the status to something
279
- * guild.members.me.voice.setStatus("something")
280
- * @example
281
- * // Removing the status
282
- * guild.members.me.voice.setStatus()
283
- * @returns {Promise<void>}
284
- */
285
- setStatus(status = '') {
286
- // PUT https://discord.com/api/v9/channels/:id/voice-status
287
- return this.client.api.channels(this.channel.id, 'voice-status').put({
288
- data: {
289
- status,
290
- },
291
- });
269
+ await this.client.api.guilds(this.guild.id, 'voice-states', target).patch({
270
+ data: {
271
+ channel_id: this.channelId,
272
+ suppress: suppressed,
273
+ },
274
+ });
275
+ }
292
276
  }
293
277
 
294
278
  /**
295
279
  * Get URL Image of the user's streaming video (NOT STREAMING !!!)
296
- * @returns {Promise<string>} URL Image of the user's streaming video
280
+ * @returns {string} URL Image of the user's streaming video
297
281
  */
298
282
  async getPreview() {
283
+ if (!this.guild?.id) return null;
284
+
299
285
  if (!this.streaming) throw new Error('USER_NOT_STREAMING');
300
286
  // URL: https://discord.com/api/v9/streams/guild:guildid:voicechannelid:userid/preview
301
- // URL: https://discord.com/api/v9/streams/call:channelId:userId/preview
302
- const streamKey = this.guild.id
303
- ? `guild:${this.guild.id}:${this.channelId}:${this.id}`
304
- : `call:${this.channelId}:${this.id}`;
305
- const data = await this.client.api.streams[encodeURIComponent(streamKey)].preview.get();
287
+ const data = await this.client.api.streams[
288
+ `guild%3A${this.guild.id}%3A${this.channelId}%3A${this.id}`
289
+ ].preview.get();
306
290
  return data.url;
307
291
  }
308
292
 
309
- /**
310
- * Post Preview Image to the client user's streaming video
311
- * @param {string} base64Image Base64 URI (data:image/jpeg;base64,data)
312
- * @returns {Promise<void>}
313
- */
314
- postPreview(base64Image) {
315
- if (!this.client.user.id === this.id || !this.streaming) throw new Error('USER_NOT_STREAMING');
316
- // URL: https://discord.com/api/v9/streams/guild:guildid:voicechannelid:userid/preview
317
- // URL: https://discord.com/api/v9/streams/call:channelId:userId/preview
318
- const streamKey = this.guild.id
319
- ? `guild:${this.guild.id}:${this.channelId}:${this.id}`
320
- : `call:${this.channelId}:${this.id}`;
321
- return this.client.api.streams[encodeURIComponent(streamKey)].preview.post({
322
- data: {
323
- thumbnail: base64Image,
324
- },
325
- });
326
- }
327
-
328
293
  toJSON() {
329
294
  return super.toJSON({
330
295
  id: true,
@@ -1,18 +1,14 @@
1
1
  'use strict';
2
-
3
2
  const baseURL = 'https://webembed-sb.onrender.com/embed?';
4
3
  const hiddenCharter =
5
4
  '||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||||​||';
5
+ const fetch = require('node-fetch');
6
6
  const { RangeError } = require('../errors');
7
7
  const Util = require('../util/Util');
8
8
 
9
9
  /**
10
10
  * Send Embedlink to Discord
11
- * <info>Only works with Discord Web and Discord Client (no custom theme installed)</info>
12
- * - No Timestamp, Footer, Fields, Author iconURL
13
- * - Video with Embed working
14
- * - Can only choose between image and thumbnail
15
- * - Description limit 350 characters
11
+ * Need to change WebEmbed API server (because heroku is no longer free)
16
12
  */
17
13
  class WebEmbed {
18
14
  /**
@@ -39,7 +35,6 @@ class WebEmbed {
39
35
  * @property {Partial<WebEmbedVideo>} [video] The video of this embed
40
36
  * @property {Partial<WebEmbedFooter>} [footer] The footer of this embed
41
37
  * @property {Partial<WebEmbedProvider>} [provider] The provider of this embed
42
- * @property {string} [redirect] Redirect URL
43
38
  */
44
39
 
45
40
  // eslint-disable-next-line valid-jsdoc
@@ -47,6 +42,24 @@ class WebEmbed {
47
42
  * @param {WebEmbed|WebEmbedOptions|APIEmbed} [data={}] WebEmbed to clone or raw embed data
48
43
  */
49
44
  this._setup(data);
45
+ /**
46
+ * Shorten the link
47
+ * @type {?boolean}
48
+ */
49
+ this.shorten = data.shorten ?? true;
50
+
51
+ /**
52
+ * Hidden Embed link
53
+ * @type {?boolean}
54
+ */
55
+ this.hidden = data.hidden ?? false;
56
+
57
+ /**
58
+ * Using Custom WebEmbed server ?
59
+ * @type {?string} https://webembed-sb.onrender.com/embed?
60
+ * @see https://github.com/aiko-chan-ai/WebEmbed
61
+ */
62
+ this.baseURL = data.baseURL ?? baseURL;
50
63
  }
51
64
  /**
52
65
  * @private
@@ -175,12 +188,6 @@ class WebEmbed {
175
188
  url: data.provider.name,
176
189
  }
177
190
  : null;
178
-
179
- /**
180
- * Redirect URL
181
- * @type {string}
182
- */
183
- this.redirect = data.redirect;
184
191
  }
185
192
  /**
186
193
  * The options to provide for setting an author for a {@link WebEmbed}.
@@ -313,59 +320,66 @@ class WebEmbed {
313
320
  }
314
321
 
315
322
  /**
316
- * Sets the redirect URL of this embed.
317
- * @param {string} url The URL
318
- * @returns {WebEmbed}
323
+ * Return Message Content + Embed (if hidden, pls check content length because it has 1000+ length)
324
+ * @returns {string} Message Content
319
325
  */
320
- setRedirect(url) {
321
- this.redirect = url;
322
- return this;
323
- }
324
-
325
- toString() {
326
- const url = new URL(baseURL);
327
- url.searchParams.set('image_type', this.imageType);
326
+ async toMessage() {
327
+ const arrayQuery = [`image_type=${this.imageType}`];
328
328
  if (this.title) {
329
- url.searchParams.set('title', this.title);
329
+ arrayQuery.push(`title=${encodeURIComponent(this.title)}`);
330
330
  }
331
331
  if (this.description) {
332
- url.searchParams.set('description', this.description);
332
+ arrayQuery.push(`description=${encodeURIComponent(this.description)}`);
333
333
  }
334
334
  if (this.url) {
335
- url.searchParams.set('url', this.url);
335
+ arrayQuery.push(`url=${encodeURIComponent(this.url)}`);
336
336
  }
337
337
  if (this.color) {
338
- url.searchParams.set('color', `#${this.color.toString(16)}`);
338
+ arrayQuery.push(`color=${encodeURIComponent(`#${this.color.toString(16)}`)}`);
339
339
  }
340
340
  if (this.image?.url) {
341
- url.searchParams.set('image', this.image.url);
341
+ arrayQuery.push(`image=${encodeURIComponent(this.image.url)}`);
342
342
  }
343
343
  if (this.video?.url) {
344
- url.searchParams.set('video', this.video.url);
344
+ arrayQuery.push(`video=${encodeURIComponent(this.video.url)}`);
345
345
  }
346
346
  if (this.author) {
347
347
  if (this.author.name) {
348
- url.searchParams.set('author_name', this.author.name);
348
+ arrayQuery.push(`author_name=${encodeURIComponent(this.author.name)}`);
349
349
  }
350
350
  if (this.author.url) {
351
- url.searchParams.set('author_url', this.author.url);
351
+ arrayQuery.push(`author_url=${encodeURIComponent(this.author.url)}`);
352
352
  }
353
353
  }
354
354
  if (this.provider) {
355
355
  if (this.provider.name) {
356
- url.searchParams.set('provider_name', this.provider.name);
356
+ arrayQuery.push(`provider_name=${encodeURIComponent(this.provider.name)}`);
357
357
  }
358
358
  if (this.provider.url) {
359
- url.searchParams.set('provider_url', this.provider.url);
359
+ arrayQuery.push(`provider_url=${encodeURIComponent(this.provider.url)}`);
360
360
  }
361
361
  }
362
362
  if (this.thumbnail?.url) {
363
- url.searchParams.set('image', this.thumbnail.url);
363
+ arrayQuery.push(`image=${encodeURIComponent(this.thumbnail.url)}`);
364
+ }
365
+ const fullURL = `${this.baseURL}${arrayQuery.join('&')}`;
366
+ if (this.shorten) {
367
+ const url = await this.constructor.getShorten(fullURL);
368
+ if (!url) console.log('Cannot shorten URL in WebEmbed');
369
+ return this.hidden ? `${hiddenCharter} ${url || fullURL}` : url || fullURL;
370
+ } else {
371
+ return this.hidden ? `${hiddenCharter} ${fullURL}` : fullURL;
364
372
  }
365
- if (this.redirect) {
366
- url.searchParams.set('redirect', this.redirect);
373
+ }
374
+
375
+ static async getShorten(url) {
376
+ const shorten = `https://tinyurl.com/api-create.php?url=${encodeURIComponent(url)}`;
377
+ try {
378
+ const res = await (await fetch(shorten)).text();
379
+ return res;
380
+ } catch {
381
+ return undefined;
367
382
  }
368
- return url.toString();
369
383
  }
370
384
  }
371
385
 
@@ -72,7 +72,7 @@ class Webhook {
72
72
 
73
73
  if ('channel_id' in data) {
74
74
  /**
75
- * The id of the channel the webhook belongs to
75
+ * The channel the webhook belongs to
76
76
  * @type {Snowflake}
77
77
  */
78
78
  this.channelId = data.channel_id;
@@ -116,7 +116,6 @@ class Webhook {
116
116
  * @property {string} [avatarURL] Avatar URL override for the message
117
117
  * @property {Snowflake} [threadId] The id of the thread in the channel to send to.
118
118
  * <info>For interaction webhooks, this property is ignored</info>
119
- * @property {string} [threadName] Name of the thread to create (only available if webhook is in a forum channel)
120
119
  * @property {MessageFlags} [flags] Which flags to set for the message. Only `SUPPRESS_EMBEDS` can be set.
121
120
  */
122
121
 
@@ -128,10 +127,11 @@ class Webhook {
128
127
  * @property {FileOptions[]|BufferResolvable[]|MessageAttachment[]} [files] See {@link BaseMessageOptions#files}
129
128
  * @property {MessageMentionOptions} [allowedMentions] See {@link BaseMessageOptions#allowedMentions}
130
129
  * @property {MessageAttachment[]} [attachments] Attachments to send with the message
131
- * @property {MessageActionRow[]|MessageActionRowOptions[]} [components]
130
+ * @property {Array<(MessageActionRow|MessageActionRowOptions)>} [components]
132
131
  * Action rows containing interactive components for the message (buttons, select menus)
133
132
  * @property {Snowflake} [threadId] The id of the thread this message belongs to
134
133
  * <info>For interaction webhooks, this property is ignored</info>
134
+ * @property {string} [threadName] Name of the thread to create (only available if webhook is in a forum channel)
135
135
  */
136
136
 
137
137
  /**
@@ -188,9 +188,9 @@ class Webhook {
188
188
  let messagePayload;
189
189
 
190
190
  if (options instanceof MessagePayload) {
191
- messagePayload = options.resolveData();
191
+ messagePayload = await options.resolveData();
192
192
  } else {
193
- messagePayload = MessagePayload.create(this, options).resolveData();
193
+ messagePayload = await MessagePayload.create(this, options).resolveData();
194
194
  }
195
195
 
196
196
  const { data, files } = await messagePayload.resolveFiles();
@@ -324,10 +324,13 @@ class Webhook {
324
324
 
325
325
  let messagePayload;
326
326
 
327
- if (options instanceof MessagePayload) messagePayload = options;
328
- else messagePayload = MessagePayload.create(this, options);
327
+ if (options instanceof MessagePayload) {
328
+ messagePayload = await options.resolveData();
329
+ } else {
330
+ messagePayload = await MessagePayload.create(this, options).resolveData();
331
+ }
329
332
 
330
- const { data, files } = await messagePayload.resolveData().resolveFiles();
333
+ const { data, files } = await messagePayload.resolveFiles();
331
334
 
332
335
  const d = await this.client.api
333
336
  .webhooks(this.id, this.token)
@@ -383,15 +386,6 @@ class Webhook {
383
386
  });
384
387
  }
385
388
 
386
- /**
387
- * The channel the webhook belongs to
388
- * @type {?(TextChannel|VoiceChannel|NewsChannel|ForumChannel)}
389
- * @readonly
390
- */
391
- get channel() {
392
- return this.client.channels.resolve(this.channelId);
393
- }
394
-
395
389
  /**
396
390
  * The timestamp the webhook was created at
397
391
  * @type {number}
@@ -1,13 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  const process = require('node:process');
4
- const { ApplicationFlags } = require('../../util/ApplicationFlags');
5
4
  const { ClientApplicationAssetTypes, Endpoints } = require('../../util/Constants');
6
5
  const Permissions = require('../../util/Permissions');
7
6
  const SnowflakeUtil = require('../../util/SnowflakeUtil');
8
- const { ApplicationRoleConnectionMetadata } = require('../ApplicationRoleConnectionMetadata');
9
7
  const Base = require('../Base');
10
- const Team = require('../Team');
11
8
 
12
9
  const AssetTypes = Object.keys(ClientApplicationAssetTypes);
13
10
 
@@ -70,132 +67,6 @@ class Application extends Base {
70
67
  } else {
71
68
  this.roleConnectionsVerificationURL ??= null;
72
69
  }
73
-
74
- // ClientApplication
75
- /**
76
- * The tags this application has (max of 5)
77
- * @type {string[]}
78
- */
79
- this.tags = data.tags ?? [];
80
-
81
- if ('install_params' in data) {
82
- /**
83
- * Settings for this application's default in-app authorization
84
- * @type {?ClientApplicationInstallParams}
85
- */
86
- this.installParams = {
87
- scopes: data.install_params.scopes,
88
- permissions: new Permissions(data.install_params.permissions).freeze(),
89
- };
90
- } else {
91
- this.installParams ??= null;
92
- }
93
-
94
- if ('custom_install_url' in data) {
95
- /**
96
- * This application's custom installation URL
97
- * @type {?string}
98
- */
99
- this.customInstallURL = data.custom_install_url;
100
- } else {
101
- this.customInstallURL = null;
102
- }
103
-
104
- if ('flags' in data) {
105
- /**
106
- * The flags this application has
107
- * @type {ApplicationFlags}
108
- */
109
- this.flags = new ApplicationFlags(data.flags).freeze();
110
- }
111
-
112
- if ('approximate_guild_count' in data) {
113
- /**
114
- * An approximate amount of guilds this application is in.
115
- * @type {?number}
116
- */
117
- this.approximateGuildCount = data.approximate_guild_count;
118
- } else {
119
- this.approximateGuildCount ??= null;
120
- }
121
-
122
- if ('guild_id' in data) {
123
- /**
124
- * The id of the guild associated with this application.
125
- * @type {?Snowflake}
126
- */
127
- this.guildId = data.guild_id;
128
- } else {
129
- this.guildId ??= null;
130
- }
131
-
132
- if ('cover_image' in data) {
133
- /**
134
- * The hash of the application's cover image
135
- * @type {?string}
136
- */
137
- this.cover = data.cover_image;
138
- } else {
139
- this.cover ??= null;
140
- }
141
-
142
- if ('rpc_origins' in data) {
143
- /**
144
- * The application's RPC origins, if enabled
145
- * @type {string[]}
146
- */
147
- this.rpcOrigins = data.rpc_origins;
148
- } else {
149
- this.rpcOrigins ??= [];
150
- }
151
-
152
- if ('bot_require_code_grant' in data) {
153
- /**
154
- * If this application's bot requires a code grant when using the OAuth2 flow
155
- * @type {?boolean}
156
- */
157
- this.botRequireCodeGrant = data.bot_require_code_grant;
158
- } else {
159
- this.botRequireCodeGrant ??= null;
160
- }
161
-
162
- if ('bot_public' in data) {
163
- /**
164
- * If this application's bot is public
165
- * @type {?boolean}
166
- */
167
- this.botPublic = data.bot_public;
168
- } else {
169
- this.botPublic ??= null;
170
- }
171
-
172
- /**
173
- * The owner of this OAuth application
174
- * @type {?(User|Team)}
175
- */
176
- this.owner = data.team
177
- ? new Team(this.client, data.team)
178
- : data.owner
179
- ? this.client.users._add(data.owner)
180
- : this.owner ?? null;
181
- }
182
-
183
- /**
184
- * The guild associated with this application.
185
- * @type {?Guild}
186
- * @readonly
187
- */
188
- get guild() {
189
- return this.client.guilds.cache.get(this.guildId) ?? null;
190
- }
191
-
192
- /**
193
- * Whether this application is partial
194
- * @type {boolean}
195
- * @readonly
196
- */
197
- get partial() {
198
- return !this.name;
199
70
  }
200
71
 
201
72
  /**
@@ -217,29 +88,35 @@ class Application extends Base {
217
88
  }
218
89
 
219
90
  /**
220
- * Obtains this application from Discord.
221
- * @returns {Promise<Application>}
91
+ * Invites this application to a guild / server
92
+ * @param {Snowflake} guild_id The id of the guild that you want to invite the bot to
93
+ * @param {PermissionResolvable} [permissions] The permissions for the bot in number form (the default is 8 / Administrator)
94
+ * @param {string} [captcha] The captcha key to add
95
+ * @returns {Promise<void>} nothing :)
222
96
  */
223
- async fetch() {
224
- const app = await this.client.api.oauth2.authorize.get({
97
+ async invite(guild_id, permissions, captcha = null) {
98
+ permissions = Permissions.resolve(permissions || 0n);
99
+ const postData = {
100
+ authorize: true,
101
+ guild_id,
102
+ permissions: '0',
103
+ };
104
+ if (permissions) {
105
+ postData.permissions = permissions;
106
+ }
107
+ if (captcha && typeof captcha === 'string' && captcha.length > 0) {
108
+ postData.captcha = captcha;
109
+ }
110
+ await this.client.api.oauth2.authorize.post({
225
111
  query: {
226
112
  client_id: this.id,
227
113
  scope: 'bot applications.commands',
228
114
  },
115
+ data: postData,
116
+ headers: {
117
+ referer: `https://discord.com/oauth2/authorize?client_id=${this.id}&permissions=${permissions}&scope=bot`,
118
+ },
229
119
  });
230
- const user = this.client.users._add(app.bot);
231
- user._partial = false;
232
- this._patch(app.application);
233
- return this;
234
- }
235
-
236
- /**
237
- * Gets this application's role connection metadata records
238
- * @returns {Promise<ApplicationRoleConnectionMetadata[]>}
239
- */
240
- async fetchRoleConnectionMetadataRecords() {
241
- const metadata = await this.client.api.applications(this.id)('role-connections').metadata.get();
242
- return metadata.map(data => new ApplicationRoleConnectionMetadata(data));
243
120
  }
244
121
 
245
122
  /**