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
@@ -1,10 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  const { Collection } = require('@discordjs/collection');
4
+ const { joinVoiceChannel, entersState, VoiceConnectionStatus } = require('@discordjs/voice');
4
5
  const { Channel } = require('./Channel');
5
6
  const TextBasedChannel = require('./interfaces/TextBasedChannel');
7
+ const InteractionManager = require('../managers/InteractionManager');
6
8
  const MessageManager = require('../managers/MessageManager');
7
- const { Opcodes, Status } = require('../util/Constants');
9
+ const { Status, Opcodes } = require('../util/Constants');
8
10
 
9
11
  /**
10
12
  * Represents a direct message channel between two users.
@@ -23,6 +25,12 @@ class DMChannel extends Channel {
23
25
  * @type {MessageManager}
24
26
  */
25
27
  this.messages = new MessageManager(this);
28
+
29
+ /**
30
+ * A manager of the interactions sent to this channel
31
+ * @type {InteractionManager}
32
+ */
33
+ this.interactions = new InteractionManager(this);
26
34
  }
27
35
 
28
36
  _patch(data) {
@@ -57,7 +65,7 @@ class DMChannel extends Channel {
57
65
  if ('is_message_request' in data) {
58
66
  /**
59
67
  * Whether the channel is a message request
60
- * @type {?boolean}
68
+ * @type {boolean}
61
69
  */
62
70
  this.messageRequest = data.is_message_request;
63
71
  }
@@ -130,6 +138,69 @@ class DMChannel extends Channel {
130
138
  return this.recipient.toString();
131
139
  }
132
140
 
141
+ // These are here only for documentation purposes - they are implemented by TextBasedChannel
142
+ /* eslint-disable no-empty-function */
143
+ get lastMessage() {}
144
+ get lastPinAt() {}
145
+ send() {}
146
+ sendTyping() {}
147
+ createMessageCollector() {}
148
+ awaitMessages() {}
149
+ createMessageComponentCollector() {}
150
+ awaitMessageComponent() {}
151
+ sendSlash() {}
152
+ searchInteraction() {}
153
+ // Doesn't work on DM channels; bulkDelete() {}
154
+ // Doesn't work on DM channels; setRateLimitPerUser() {}
155
+ // Doesn't work on DM channels; setNSFW() {}
156
+ // Testing feature: Call
157
+ // URL: https://discord.com/api/v9/channels/DMchannelId/call/ring
158
+ /**
159
+ * Call this DMChannel. Return discordjs/voice VoiceConnection
160
+ * @param {CallOptions} options Options for the call
161
+ * @returns {Promise<VoiceConnection>}
162
+ */
163
+ call(options = {}) {
164
+ options = Object.assign(
165
+ {
166
+ ring: true,
167
+ },
168
+ options || {},
169
+ );
170
+ return new Promise((resolve, reject) => {
171
+ if (!this.client.options.patchVoice) {
172
+ reject(
173
+ new Error(
174
+ 'VOICE_NOT_PATCHED',
175
+ 'Enable voice patching in client options\nhttps://discordjs-self-v13.netlify.app/#/docs/docs/main/typedef/ClientOptions',
176
+ ),
177
+ );
178
+ } else {
179
+ if (options.ring) {
180
+ this.client.api.channels(this.id).call.ring.post({
181
+ data: {
182
+ recipients: null,
183
+ },
184
+ });
185
+ }
186
+ const connection = joinVoiceChannel({
187
+ channelId: this.id,
188
+ guildId: null,
189
+ adapterCreator: this.voiceAdapterCreator,
190
+ selfDeaf: options.selfDeaf ?? false,
191
+ selfMute: options.selfMute ?? false,
192
+ });
193
+ entersState(connection, VoiceConnectionStatus.Ready, 30000)
194
+ .then(connection => {
195
+ resolve(connection);
196
+ })
197
+ .catch(err => {
198
+ connection.destroy();
199
+ reject(err);
200
+ });
201
+ }
202
+ });
203
+ }
133
204
  /**
134
205
  * Sync VoiceState of this DMChannel.
135
206
  * @returns {undefined}
@@ -142,19 +213,6 @@ class DMChannel extends Channel {
142
213
  },
143
214
  });
144
215
  }
145
-
146
- /**
147
- * Ring the user's phone / PC (call)
148
- * @returns {Promise<void>}
149
- */
150
- ring() {
151
- return this.client.api.channels(this.id).call.ring.post({
152
- data: {
153
- recipients: null,
154
- },
155
- });
156
- }
157
-
158
216
  /**
159
217
  * The user in this voice-based channel
160
218
  * @type {Collection<Snowflake, User>}
@@ -169,7 +227,18 @@ class DMChannel extends Channel {
169
227
  }
170
228
  return coll;
171
229
  }
172
-
230
+ /**
231
+ * Get connection to current call
232
+ * @type {?VoiceConnection}
233
+ * @readonly
234
+ */
235
+ get voiceConnection() {
236
+ const check = this.client.callVoice?.joinConfig?.channelId == this.id;
237
+ if (check) {
238
+ return this.client.callVoice;
239
+ }
240
+ return null;
241
+ }
173
242
  /**
174
243
  * Get current shard
175
244
  * @type {WebSocketShard}
@@ -178,7 +247,6 @@ class DMChannel extends Channel {
178
247
  get shard() {
179
248
  return this.client.ws.shards.first();
180
249
  }
181
-
182
250
  /**
183
251
  * The voice state adapter for this client that can be used with @discordjs/voice to play audio in DM / Group DM channels.
184
252
  * @type {?Function}
@@ -199,19 +267,14 @@ class DMChannel extends Channel {
199
267
  };
200
268
  };
201
269
  }
202
-
203
- // These are here only for documentation purposes - they are implemented by TextBasedChannel
204
- /* eslint-disable no-empty-function */
205
- get lastMessage() {}
206
- get lastPinAt() {}
207
- send() {}
208
- sendTyping() {}
209
- createMessageCollector() {}
210
- awaitMessages() {}
211
- // Doesn't work on DM channels; setRateLimitPerUser() {}
212
- // Doesn't work on DM channels; setNSFW() {}
213
270
  }
214
271
 
215
- TextBasedChannel.applyToClass(DMChannel, true, ['fetchWebhooks', 'createWebhook', 'setRateLimitPerUser', 'setNSFW']);
272
+ TextBasedChannel.applyToClass(DMChannel, true, [
273
+ 'bulkDelete',
274
+ 'fetchWebhooks',
275
+ 'createWebhook',
276
+ 'setRateLimitPerUser',
277
+ 'setNSFW',
278
+ ]);
216
279
 
217
280
  module.exports = DMChannel;
@@ -0,0 +1,520 @@
1
+ 'use strict';
2
+ const { Collection } = require('@discordjs/collection');
3
+ const { ApplicationRoleConnectionMetadata } = require('./ApplicationRoleConnectionMetadata');
4
+ const Base = require('./Base');
5
+ const ApplicationFlags = require('../util/ApplicationFlags');
6
+ const { ClientApplicationAssetTypes, Endpoints, ApplicationRoleConnectionMetadataTypes } = require('../util/Constants');
7
+ const DataResolver = require('../util/DataResolver');
8
+ const Permissions = require('../util/Permissions');
9
+ const SnowflakeUtil = require('../util/SnowflakeUtil');
10
+
11
+ const AssetTypes = Object.keys(ClientApplicationAssetTypes);
12
+
13
+ /**
14
+ * Represents an OAuth2 Application.
15
+ * @extends {Base}
16
+ * @abstract
17
+ */
18
+ class DeveloperPortalApplication extends Base {
19
+ constructor(client, data) {
20
+ super(client);
21
+ this._patch(data);
22
+ }
23
+ _patch(data) {
24
+ /**
25
+ * The application's id
26
+ * @type {Snowflake}
27
+ */
28
+ this.id = data.id;
29
+
30
+ if ('name' in data) {
31
+ /**
32
+ * The name of the application
33
+ * @type {?string}
34
+ */
35
+ this.name = data.name;
36
+ } else {
37
+ this.name ??= null;
38
+ }
39
+
40
+ if ('description' in data) {
41
+ /**
42
+ * The application's description
43
+ * @type {?string}
44
+ */
45
+ this.description = data.description;
46
+ } else {
47
+ this.description ??= null;
48
+ }
49
+
50
+ if ('icon' in data) {
51
+ /**
52
+ * The application's icon hash
53
+ * @type {?string}
54
+ */
55
+ this.icon = data.icon;
56
+ } else {
57
+ this.icon ??= null;
58
+ }
59
+
60
+ if ('bot' in data) {
61
+ /**
62
+ * Bot application
63
+ * @type {User}
64
+ */
65
+ this.bot = this.client.users._add(data.bot);
66
+ }
67
+
68
+ /**
69
+ * The tags this application has (max of 5)
70
+ * @type {string[]}
71
+ */
72
+ this.tags = data.tags ?? [];
73
+
74
+ if ('install_params' in data) {
75
+ /**
76
+ * Settings for this application's default in-app authorization
77
+ * @type {?ClientApplicationInstallParams}
78
+ */
79
+ this.installParams = {
80
+ scopes: data.install_params.scopes,
81
+ permissions: new Permissions(data.install_params.permissions).freeze(),
82
+ };
83
+ } else {
84
+ this.installParams ??= null;
85
+ }
86
+
87
+ if ('custom_install_url' in data) {
88
+ /**
89
+ * This application's custom installation URL
90
+ * @type {?string}
91
+ */
92
+ this.customInstallURL = data.custom_install_url;
93
+ } else {
94
+ this.customInstallURL = null;
95
+ }
96
+
97
+ if ('flags' in data) {
98
+ /**
99
+ * The flags this application has
100
+ * @type {ApplicationFlags}
101
+ */
102
+ this.flags = new ApplicationFlags(data.flags).freeze();
103
+ }
104
+
105
+ if ('cover_image' in data) {
106
+ /**
107
+ * The hash of the application's cover image
108
+ * @type {?string}
109
+ */
110
+ this.cover = data.cover_image;
111
+ } else {
112
+ this.cover ??= null;
113
+ }
114
+
115
+ if ('rpc_origins' in data) {
116
+ /**
117
+ * The application's RPC origins, if enabled
118
+ * @type {string[]}
119
+ */
120
+ this.rpcOrigins = data.rpc_origins;
121
+ } else {
122
+ this.rpcOrigins ??= [];
123
+ }
124
+
125
+ if ('bot_require_code_grant' in data) {
126
+ /**
127
+ * If this application's bot requires a code grant when using the OAuth2 flow
128
+ * @type {?boolean}
129
+ */
130
+ this.botRequireCodeGrant = data.bot_require_code_grant;
131
+ } else {
132
+ this.botRequireCodeGrant ??= null;
133
+ }
134
+
135
+ if ('bot_public' in data) {
136
+ /**
137
+ * If this application's bot is public
138
+ * @type {?boolean}
139
+ */
140
+ this.botPublic = data.bot_public;
141
+ } else {
142
+ this.botPublic ??= null;
143
+ }
144
+
145
+ /**
146
+ * The owner of this OAuth application
147
+ * @type {?(User|Team)}
148
+ */
149
+ this.owner = null;
150
+ if (data.owner.username == `team${data.owner.id}` && data.owner.discriminator == '0000') {
151
+ this.owner = this.client.developerPortal.teams.get(data.owner.id);
152
+ } else {
153
+ this.owner = data.owner ? this.client.users._add(data.owner) : this.owner ?? null;
154
+ }
155
+
156
+ /**
157
+ * Redirect URIs for this application
158
+ * @type {Array<string>}
159
+ */
160
+ this.redirectURIs = data.redirect_uris ?? [];
161
+
162
+ /**
163
+ * BOT_HTTP_INTERACTIONS feature flag
164
+ * @type {?string}
165
+ */
166
+ this.interactionEndpointURL = data.interactions_endpoint_url ?? null;
167
+
168
+ /**
169
+ * Public key
170
+ * @type {?string}
171
+ */
172
+ this.publicKey = data.verify_key ?? null;
173
+
174
+ /**
175
+ * @typedef {Object} Tester
176
+ * @property {number} state The state of the tester (2: Accepted, 1: Pending)
177
+ * @property {User} user The user that the tester is
178
+ */
179
+ /**
180
+ * User tester
181
+ * @type {Collection<Snowflake, Tester>}
182
+ */
183
+ this.testers = new Collection(); // <Snowflake, User>
184
+
185
+ /**
186
+ * Terms of service URL
187
+ * @type {?string}
188
+ */
189
+ this.TermsOfService = data.terms_of_service_url ?? null;
190
+
191
+ /**
192
+ * Privacy policy URL
193
+ * @type {?string}
194
+ */
195
+ this.PrivacyPolicy = data.privacy_policy_url ?? null;
196
+
197
+ if ('role_connections_verification_url' in data) {
198
+ /**
199
+ * This application's role connection verification entry point URL
200
+ * @type {?string}
201
+ */
202
+ this.roleConnectionsVerificationURL = data.role_connections_verification_url;
203
+ } else {
204
+ this.roleConnectionsVerificationURL ??= null;
205
+ }
206
+ }
207
+ /**
208
+ * The timestamp the application was created at
209
+ * @type {number}
210
+ * @readonly
211
+ */
212
+ get createdTimestamp() {
213
+ return SnowflakeUtil.timestampFrom(this.id);
214
+ }
215
+
216
+ /**
217
+ * The time the application was created at
218
+ * @type {Date}
219
+ * @readonly
220
+ */
221
+ get createdAt() {
222
+ return new Date(this.createdTimestamp);
223
+ }
224
+
225
+ /**
226
+ * A link to the application's icon.
227
+ * @param {StaticImageURLOptions} [options={}] Options for the Image URL
228
+ * @returns {?string}
229
+ */
230
+ iconURL({ format, size } = {}) {
231
+ if (!this.icon) return null;
232
+ return this.client.rest.cdn.AppIcon(this.id, this.icon, { format, size });
233
+ }
234
+
235
+ /**
236
+ * A link to this application's cover image.
237
+ * @param {StaticImageURLOptions} [options={}] Options for the Image URL
238
+ * @returns {?string}
239
+ */
240
+ coverURL({ format, size } = {}) {
241
+ if (!this.cover) return null;
242
+ return Endpoints.CDN(this.client.options.http.cdn).AppIcon(this.id, this.cover, { format, size });
243
+ }
244
+
245
+ /**
246
+ * Asset data.
247
+ * @typedef {Object} ApplicationAsset
248
+ * @property {Snowflake} id The asset's id
249
+ * @property {string} name The asset's name
250
+ * @property {string} type The asset's type
251
+ */
252
+
253
+ /**
254
+ * Gets the application's rich presence assets.
255
+ * @returns {Promise<Array<ApplicationAsset>>}
256
+ * @deprecated This will be removed in the next major as it is unsupported functionality.
257
+ */
258
+ async fetchAssets() {
259
+ const assets = await this.client.api.oauth2.applications(this.id).assets.get();
260
+ return assets.map(a => ({
261
+ id: a.id,
262
+ name: a.name,
263
+ type: AssetTypes[a.type - 1],
264
+ }));
265
+ }
266
+
267
+ /**
268
+ * Whether this application is partial
269
+ * @type {boolean}
270
+ * @readonly
271
+ */
272
+ get partial() {
273
+ return !this.name;
274
+ }
275
+
276
+ /**
277
+ * Obtains this application from Discord.
278
+ * @returns {Promise<DeveloperPortalApplication>}
279
+ */
280
+ async fetch() {
281
+ const app = await this.client.api.applications[this.id].get();
282
+ this._patch(app);
283
+ return this;
284
+ }
285
+
286
+ /**
287
+ * Gets all testers for this application.
288
+ * @returns {Promise<DeveloperPortalApplication>}
289
+ */
290
+ async fetchTesters() {
291
+ const app = await this.client.api.applications[this.id].allowlist.get();
292
+ this.testers = new Collection();
293
+ for (const tester of app || []) {
294
+ this.testers.set(tester.user.id, {
295
+ state: tester.state,
296
+ user: this.client.users._add(tester.user),
297
+ });
298
+ }
299
+ return this;
300
+ }
301
+
302
+ /**
303
+ * Add user to this application's allowlist.
304
+ * @param {string} username Username of the user to add
305
+ * @param {string} discriminator Discriminator of the user to add
306
+ * @returns {Promise<DeveloperPortalApplication>}
307
+ */
308
+ async addTester(username, discriminator) {
309
+ const app = await this.client.api.applications[this.id].allowlist.post({
310
+ data: {
311
+ username,
312
+ discriminator,
313
+ },
314
+ });
315
+ this.testers.set(app.user.id, {
316
+ state: app.state,
317
+ user: this.client.users._add(app.user),
318
+ });
319
+ return this;
320
+ }
321
+
322
+ /**
323
+ * Delete user from this application's allowlist.
324
+ * @param {UserResolvable} user User
325
+ * @returns {Promise<DeveloperPortalApplication>}
326
+ */
327
+ async deleteTester(user) {
328
+ const userId = this.client.users.resolveId(user);
329
+ await this.client.api.applications[this.id].allowlist[userId].delete();
330
+ this.testers.delete(userId);
331
+ return this;
332
+ }
333
+
334
+ /**
335
+ * The data for editing a application.
336
+ * @typedef {Object} ApplicationEditData
337
+ * @property {string} [name] The name of the app
338
+ * @property {string} [description] The description of the app
339
+ * @property {?(BufferResolvable|Base64Resolvable)} [icon] The icon of the app
340
+ * @property {?(BufferResolvable|Base64Resolvable)} [cover] The application's default rich presence invite
341
+ * @property {boolean} [botPublic] When false only app owner can join the app's bot to guilds
342
+ * @property {boolean} [botRequireCodeGrant] When true the app's bot will only join upon completion of the full oauth2 code grant flow
343
+ * @property {?string} [TermsOfService] ToS URL
344
+ * @property {?string} [PrivacyPolicy] Privacy policy URL
345
+ * @property {number} [flags] The application's public flags
346
+ * @property {Array<string>} [redirectURIs] Redirect URIs (OAuth2 only)
347
+ * @property {Array<string>} [tags] Up to 5 tags describing the content and functionality of the application
348
+ */
349
+ /**
350
+ * Edits this application.
351
+ * @param {ApplicationEditData} data Edit data for the application
352
+ * @returns {Promise<DeveloperPortalApplication>}
353
+ */
354
+ async edit(data) {
355
+ const _data = {};
356
+ if (data.name) _data.name = data.name;
357
+ if (typeof data.icon !== 'undefined') {
358
+ _data.icon = await DataResolver.resolveImage(data.icon);
359
+ }
360
+ if (data.description) _data.description = data.description;
361
+ if (typeof data.cover !== 'undefined') {
362
+ _data.cover = await DataResolver.resolveImage(data.cover);
363
+ }
364
+ if (data.botPublic) _data.bot_public = data.botPublic;
365
+ if (data.botRequireCodeGrant) _data.bot_require_code_grant = data.botRequireCodeGrant;
366
+ if (data.TermsOfService) _data.terms_of_service_url = data.TermsOfService;
367
+ if (data.PrivacyPolicy) _data.privacy_policy_url = data.PrivacyPolicy;
368
+ if (data.flags) _data.flags = data.flags;
369
+ if (data.redirectURIs) _data.redirect_uris = data.redirectURIs;
370
+ if (data.tags) _data.tags = data.tags;
371
+ //
372
+ const app = await this.client.api.applications[this.id].patch({ data: _data });
373
+ this._patch(app);
374
+ return this;
375
+ }
376
+
377
+ /**
378
+ * Creates a new bot for this application.
379
+ * @returns {Promise<DeveloperPortalApplication>}
380
+ */
381
+ async createBot() {
382
+ if (this.bot) throw new Error('Application already has a bot.');
383
+ await this.client.api.applications[this.id].bot.post();
384
+ const app = await this.fetch();
385
+ return app;
386
+ }
387
+
388
+ /**
389
+ * Reset CLient Secret for this application.
390
+ * @param {number} MFACode The MFA code (if required)
391
+ * @returns {Promise<string>}
392
+ */
393
+ async resetClientSecret(MFACode) {
394
+ const app = MFACode
395
+ ? await this.client.api.applications[this.id].reset.post({
396
+ data: {
397
+ code: MFACode,
398
+ },
399
+ })
400
+ : await this.client.api.applications[this.id].reset.post();
401
+ return app.secret;
402
+ }
403
+
404
+ /**
405
+ * Reset Bot Token for this application.
406
+ * @param {number} MFACode The MFA code (if required)
407
+ * @returns {Promise<string>}
408
+ */
409
+ async resetBotToken(MFACode) {
410
+ const app = MFACode
411
+ ? await this.client.api.applications[this.id].bot.reset.post({
412
+ data: {
413
+ code: MFACode,
414
+ },
415
+ })
416
+ : await this.client.api.applications[this.id].bot.reset.post();
417
+ return app.token;
418
+ }
419
+
420
+ /**
421
+ * Deletes this application.
422
+ * @param {number} MFACode The MFA code (if required)
423
+ * @returns {Promise<void>}
424
+ */
425
+ delete(MFACode) {
426
+ return this.client.developerPortal.deleteApplication(this.id, MFACode);
427
+ }
428
+
429
+ /**
430
+ * Add new image to this application. (RPC)
431
+ * @param {BufferResolvable|Base64Resolvable} image Image Resolvable
432
+ * @param {string} name Name of the image
433
+ * @returns {ApplicationAsset}
434
+ */
435
+ async addAsset(image, name) {
436
+ const data = await DataResolver.resolveImage(image);
437
+ const asset = await this.client.api.applications[this.id].assets.post({
438
+ data: {
439
+ type: 1,
440
+ name,
441
+ image: data,
442
+ },
443
+ });
444
+ return {
445
+ id: asset.id,
446
+ name: asset.name,
447
+ type: AssetTypes[asset.type - 1],
448
+ };
449
+ }
450
+
451
+ /**
452
+ * Delete an image from this application. (RPC)
453
+ * @param {Snowflake} id ID of the image
454
+ * @returns {Promise<undefined>}
455
+ */
456
+ async deleteAsset(id) {
457
+ await this.client.api.applications[this.id].assets[id].delete();
458
+ return undefined;
459
+ }
460
+
461
+ /**
462
+ * Gets this application's role connection metadata records
463
+ * @returns {Promise<ApplicationRoleConnectionMetadata[]>}
464
+ */
465
+ async fetchRoleConnectionMetadataRecords() {
466
+ const metadata = await this.client.api.applications(this.id)('role-connections').metadata.get();
467
+ return metadata.map(data => new ApplicationRoleConnectionMetadata(data));
468
+ }
469
+
470
+ /**
471
+ * Data for creating or editing an application role connection metadata.
472
+ * @typedef {Object} ApplicationRoleConnectionMetadataEditOptions
473
+ * @property {string} name The name of the metadata field
474
+ * @property {?Object<Locale, string>} [nameLocalizations] The name localizations for the metadata field
475
+ * @property {string} description The description of the metadata field
476
+ * @property {?Object<Locale, string>} [descriptionLocalizations] The description localizations for the metadata field
477
+ * @property {string} key The dictionary key of the metadata field
478
+ * @property {ApplicationRoleConnectionMetadataType} type The type of the metadata field
479
+ */
480
+
481
+ /**
482
+ * Updates this application's role connection metadata records
483
+ * @param {ApplicationRoleConnectionMetadataEditOptions[]} records The new role connection metadata records
484
+ * @returns {Promise<ApplicationRoleConnectionMetadata[]>}
485
+ */
486
+ async editRoleConnectionMetadataRecords(records) {
487
+ const newRecords = await this.client.api
488
+ .applications(this.client.user.id)('role-connections')
489
+ .metadata.put({
490
+ data: records.map(record => ({
491
+ type: typeof record.type === 'string' ? ApplicationRoleConnectionMetadataTypes[record.type] : record.type,
492
+ key: record.key,
493
+ name: record.name,
494
+ name_localizations: record.nameLocalizations,
495
+ description: record.description,
496
+ description_localizations: record.descriptionLocalizations,
497
+ })),
498
+ });
499
+
500
+ return newRecords.map(data => new ApplicationRoleConnectionMetadata(data));
501
+ }
502
+
503
+ /**
504
+ * When concatenated with a string, this automatically returns the application's name instead of the
505
+ * Application object.
506
+ * @returns {?string}
507
+ * @example
508
+ * // Logs: Application name: My App
509
+ * console.log(`Application name: ${application}`);
510
+ */
511
+ toString() {
512
+ return this.name;
513
+ }
514
+
515
+ toJSON() {
516
+ return super.toJSON({ createdTimestamp: true });
517
+ }
518
+ }
519
+
520
+ module.exports = DeveloperPortalApplication;