djs-selfbot-v13 3.1.7 → 3.2.2

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 (155) hide show
  1. package/README.md +18 -35
  2. package/package.json +85 -100
  3. package/src/client/BaseClient.js +3 -4
  4. package/src/client/Client.js +249 -530
  5. package/src/client/actions/Action.js +18 -13
  6. package/src/client/actions/ActionsManager.js +7 -1
  7. package/src/client/actions/AutoModerationActionExecution.js +1 -0
  8. package/src/client/actions/AutoModerationRuleCreate.js +1 -0
  9. package/src/client/actions/AutoModerationRuleDelete.js +1 -0
  10. package/src/client/actions/AutoModerationRuleUpdate.js +1 -0
  11. package/src/client/actions/GuildMemberRemove.js +0 -1
  12. package/src/client/actions/GuildMemberUpdate.js +0 -1
  13. package/src/client/actions/MessageCreate.js +0 -4
  14. package/src/client/actions/PresenceUpdate.js +17 -16
  15. package/src/client/websocket/WebSocketManager.js +11 -31
  16. package/src/client/websocket/WebSocketShard.js +39 -38
  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 +16 -13
  21. package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
  22. package/src/client/websocket/handlers/GUILD_CREATE.js +19 -13
  23. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +0 -1
  24. package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +1 -0
  25. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +22 -0
  26. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +12 -0
  27. package/src/client/websocket/handlers/READY.js +90 -140
  28. package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +7 -5
  29. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +7 -5
  30. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +32 -9
  31. package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +2 -8
  32. package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
  33. package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
  34. package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +1 -5
  35. package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
  36. package/src/client/websocket/handlers/index.js +17 -20
  37. package/src/errors/Messages.js +25 -69
  38. package/src/index.js +13 -43
  39. package/src/managers/ApplicationCommandManager.js +9 -12
  40. package/src/managers/ApplicationCommandPermissionsManager.js +3 -11
  41. package/src/managers/ChannelManager.js +2 -3
  42. package/src/managers/ClientUserSettingManager.js +162 -280
  43. package/src/managers/GuildBanManager.js +47 -1
  44. package/src/managers/GuildChannelManager.js +2 -16
  45. package/src/managers/GuildForumThreadManager.js +24 -30
  46. package/src/managers/GuildManager.js +1 -1
  47. package/src/managers/GuildMemberManager.js +50 -222
  48. package/src/managers/GuildSettingManager.js +22 -15
  49. package/src/managers/MessageManager.js +42 -44
  50. package/src/managers/PermissionOverwriteManager.js +1 -1
  51. package/src/managers/ReactionUserManager.js +5 -5
  52. package/src/managers/RelationshipManager.js +83 -76
  53. package/src/managers/ThreadManager.js +12 -45
  54. package/src/managers/ThreadMemberManager.js +1 -1
  55. package/src/managers/UserManager.js +6 -10
  56. package/src/managers/UserNoteManager.js +53 -0
  57. package/src/rest/APIRequest.js +48 -20
  58. package/src/rest/DiscordAPIError.js +17 -16
  59. package/src/rest/RESTManager.js +1 -21
  60. package/src/rest/RequestHandler.js +35 -21
  61. package/src/structures/ApplicationCommand.js +19 -456
  62. package/src/structures/ApplicationRoleConnectionMetadata.js +3 -0
  63. package/src/structures/AutoModerationRule.js +5 -5
  64. package/src/structures/AutocompleteInteraction.js +1 -0
  65. package/src/structures/BaseGuildTextChannel.js +10 -12
  66. package/src/structures/BaseGuildVoiceChannel.js +16 -18
  67. package/src/structures/{Call.js → CallState.js} +17 -12
  68. package/src/structures/CategoryChannel.js +2 -0
  69. package/src/structures/Channel.js +2 -3
  70. package/src/structures/ClientPresence.js +20 -19
  71. package/src/structures/ClientUser.js +117 -338
  72. package/src/structures/ContextMenuInteraction.js +1 -1
  73. package/src/structures/DMChannel.js +29 -92
  74. package/src/structures/ForumChannel.js +0 -10
  75. package/src/structures/GroupDMChannel.js +387 -0
  76. package/src/structures/Guild.js +135 -271
  77. package/src/structures/GuildAuditLogs.js +0 -5
  78. package/src/structures/GuildChannel.js +16 -2
  79. package/src/structures/GuildMember.js +27 -145
  80. package/src/structures/Interaction.js +1 -62
  81. package/src/structures/Invite.js +35 -52
  82. package/src/structures/Message.js +220 -203
  83. package/src/structures/MessageAttachment.js +11 -0
  84. package/src/structures/MessageButton.js +1 -67
  85. package/src/structures/MessageEmbed.js +1 -1
  86. package/src/structures/MessageMentions.js +3 -2
  87. package/src/structures/MessagePayload.js +6 -46
  88. package/src/structures/MessagePoll.js +238 -0
  89. package/src/structures/MessageReaction.js +1 -1
  90. package/src/structures/MessageSelectMenu.js +1 -252
  91. package/src/structures/Modal.js +70 -188
  92. package/src/structures/Presence.js +787 -129
  93. package/src/structures/Role.js +18 -2
  94. package/src/structures/SelectMenuInteraction.js +2 -151
  95. package/src/structures/Team.js +0 -49
  96. package/src/structures/TextInputComponent.js +0 -70
  97. package/src/structures/ThreadChannel.js +0 -19
  98. package/src/structures/User.js +145 -339
  99. package/src/structures/UserContextMenuInteraction.js +2 -2
  100. package/src/structures/VoiceState.js +74 -39
  101. package/src/structures/WebEmbed.js +38 -52
  102. package/src/structures/Webhook.js +17 -11
  103. package/src/structures/interfaces/Application.js +146 -23
  104. package/src/structures/interfaces/TextBasedChannel.js +409 -256
  105. package/src/util/ApplicationFlags.js +1 -1
  106. package/src/util/AttachmentFlags.js +38 -0
  107. package/src/util/Constants.js +120 -285
  108. package/src/util/Formatters.js +16 -2
  109. package/src/util/InviteFlags.js +29 -0
  110. package/src/util/LimitedCollection.js +1 -1
  111. package/src/util/Options.js +48 -74
  112. package/src/util/Permissions.js +15 -0
  113. package/src/util/PurchasedFlags.js +2 -0
  114. package/src/util/RemoteAuth.js +221 -356
  115. package/src/util/RoleFlags.js +37 -0
  116. package/src/util/Sweepers.js +1 -1
  117. package/src/util/Util.js +158 -32
  118. package/typings/enums.d.ts +24 -73
  119. package/typings/index.d.ts +978 -1288
  120. package/typings/rawDataTypes.d.ts +68 -9
  121. package/src/client/actions/InteractionCreate.js +0 -115
  122. package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +0 -23
  123. package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +0 -11
  124. package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +0 -55
  125. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
  126. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
  127. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
  128. package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
  129. package/src/client/websocket/handlers/INTERACTION_CREATE.js +0 -16
  130. package/src/client/websocket/handlers/INTERACTION_FAILURE.js +0 -18
  131. package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +0 -30
  132. package/src/client/websocket/handlers/MESSAGE_ACK.js +0 -16
  133. package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
  134. package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
  135. package/src/managers/DeveloperPortalManager.js +0 -104
  136. package/src/managers/GuildApplicationCommandManager.js +0 -28
  137. package/src/managers/GuildFolderManager.js +0 -24
  138. package/src/managers/SessionManager.js +0 -57
  139. package/src/rest/CaptchaSolver.js +0 -132
  140. package/src/structures/ClientApplication.js +0 -204
  141. package/src/structures/DeveloperPortalApplication.js +0 -520
  142. package/src/structures/GuildFolder.js +0 -75
  143. package/src/structures/InteractionResponse.js +0 -114
  144. package/src/structures/PartialGroupDMChannel.js +0 -433
  145. package/src/structures/RichPresence.js +0 -722
  146. package/src/structures/Session.js +0 -81
  147. package/src/util/Voice.js +0 -1456
  148. package/src/util/arRPC/index.js +0 -229
  149. package/src/util/arRPC/process/detectable.json +0 -1
  150. package/src/util/arRPC/process/index.js +0 -102
  151. package/src/util/arRPC/process/native/index.js +0 -5
  152. package/src/util/arRPC/process/native/linux.js +0 -37
  153. package/src/util/arRPC/process/native/win32.js +0 -25
  154. package/src/util/arRPC/transports/ipc.js +0 -281
  155. package/src/util/arRPC/transports/websocket.js +0 -128
@@ -1,47 +1,41 @@
1
+ /* eslint-disable no-unreachable */
1
2
  'use strict';
2
3
 
3
4
  const process = require('node:process');
4
- const { setInterval, setTimeout } = require('node:timers');
5
+ const { setInterval } = require('node:timers');
6
+ const { setTimeout } = require('node:timers');
5
7
  const { Collection } = require('@discordjs/collection');
6
- const { getVoiceConnection } = require('@discordjs/voice');
7
- const chalk = require('chalk');
8
- const fetch = require('node-fetch');
9
8
  const BaseClient = require('./BaseClient');
10
9
  const ActionsManager = require('./actions/ActionsManager');
11
10
  const ClientVoiceManager = require('./voice/ClientVoiceManager');
12
11
  const WebSocketManager = require('./websocket/WebSocketManager');
13
- const { Error, TypeError, RangeError } = require('../errors');
14
- const Discord = require('../index');
12
+ const { Error, TypeError } = require('../errors');
15
13
  const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager');
16
14
  const BillingManager = require('../managers/BillingManager');
17
15
  const ChannelManager = require('../managers/ChannelManager');
18
16
  const ClientUserSettingManager = require('../managers/ClientUserSettingManager');
19
- const DeveloperPortalManager = require('../managers/DeveloperPortalManager');
20
17
  const GuildManager = require('../managers/GuildManager');
18
+ const PresenceManager = require('../managers/PresenceManager');
21
19
  const RelationshipManager = require('../managers/RelationshipManager');
22
- const SessionManager = require('../managers/SessionManager');
23
20
  const UserManager = require('../managers/UserManager');
21
+ const UserNoteManager = require('../managers/UserNoteManager');
24
22
  const VoiceStateManager = require('../managers/VoiceStateManager');
25
23
  const ShardClientUtil = require('../sharding/ShardClientUtil');
26
24
  const ClientPresence = require('../structures/ClientPresence');
27
25
  const GuildPreview = require('../structures/GuildPreview');
28
26
  const GuildTemplate = require('../structures/GuildTemplate');
29
27
  const Invite = require('../structures/Invite');
30
- const { CustomStatus } = require('../structures/RichPresence');
31
28
  const { Sticker } = require('../structures/Sticker');
32
29
  const StickerPack = require('../structures/StickerPack');
33
30
  const VoiceRegion = require('../structures/VoiceRegion');
34
31
  const Webhook = require('../structures/Webhook');
35
32
  const Widget = require('../structures/Widget');
36
- const { Events, InviteScopes, Status, captchaServices } = require('../util/Constants');
33
+ const { Events, Status } = require('../util/Constants');
37
34
  const DataResolver = require('../util/DataResolver');
38
35
  const Intents = require('../util/Intents');
39
- const Options = require('../util/Options');
40
36
  const Permissions = require('../util/Permissions');
41
37
  const DiscordAuthWebsocket = require('../util/RemoteAuth');
42
38
  const Sweepers = require('../util/Sweepers');
43
- const { lazy, testImportModule } = require('../util/Util');
44
- const Message = lazy(() => require('../structures/Message').Message);
45
39
 
46
40
  /**
47
41
  * The main hub for interacting with the Discord API, and the starting point for any bot.
@@ -49,44 +43,11 @@ const Message = lazy(() => require('../structures/Message').Message);
49
43
  */
50
44
  class Client extends BaseClient {
51
45
  /**
52
- * @param {ClientOptions} options Options for the client
46
+ * @param {ClientOptions} [options] Options for the client
53
47
  */
54
- constructor(options = {}) {
48
+ constructor(options) {
55
49
  super(options);
56
50
 
57
- const data = require('node:worker_threads').workerData ?? process.env;
58
- const defaults = Options.createDefault();
59
-
60
- if (this.options.shards === defaults.shards) {
61
- if ('SHARDS' in data) {
62
- this.options.shards = JSON.parse(data.SHARDS);
63
- }
64
- }
65
-
66
- if (this.options.shardCount === defaults.shardCount) {
67
- if ('SHARD_COUNT' in data) {
68
- this.options.shardCount = Number(data.SHARD_COUNT);
69
- } else if (Array.isArray(this.options.shards)) {
70
- this.options.shardCount = this.options.shards.length;
71
- }
72
- }
73
-
74
- const typeofShards = typeof this.options.shards;
75
-
76
- if (typeofShards === 'undefined' && typeof this.options.shardCount === 'number') {
77
- this.options.shards = Array.from({ length: this.options.shardCount }, (_, i) => i);
78
- }
79
-
80
- if (typeofShards === 'number') this.options.shards = [this.options.shards];
81
-
82
- if (Array.isArray(this.options.shards)) {
83
- this.options.shards = [
84
- ...new Set(
85
- this.options.shards.filter(item => !isNaN(item) && item >= 0 && item < Infinity && item === (item | 0)),
86
- ),
87
- ];
88
- }
89
-
90
51
  this._validateOptions();
91
52
 
92
53
  /**
@@ -142,17 +103,6 @@ class Client extends BaseClient {
142
103
  */
143
104
  this.users = new UserManager(this);
144
105
 
145
- // Patch
146
- /**
147
- * All of the relationships {@link User}
148
- * @type {RelationshipManager}
149
- */
150
- this.relationships = new RelationshipManager(this);
151
- /**
152
- * All of the settings {@link Object}
153
- * @type {ClientUserSettingManager}
154
- */
155
- this.settings = new ClientUserSettingManager(this);
156
106
  /**
157
107
  * All of the guilds the client is currently handling, mapped by their ids -
158
108
  * as long as sharding isn't being used, this will be *every* guild the bot is a member of
@@ -160,18 +110,6 @@ class Client extends BaseClient {
160
110
  */
161
111
  this.guilds = new GuildManager(this);
162
112
 
163
- /**
164
- * Manages the API methods
165
- * @type {BillingManager}
166
- */
167
- this.billing = new BillingManager(this);
168
-
169
- /**
170
- * All of the sessions of the client
171
- * @type {SessionManager}
172
- */
173
- this.sessions = new SessionManager(this);
174
-
175
113
  /**
176
114
  * All of the {@link Channel}s that the client is currently handling, mapped by their ids -
177
115
  * as long as sharding isn't being used, this will be *every* channel in *every* guild the bot
@@ -187,12 +125,6 @@ class Client extends BaseClient {
187
125
  */
188
126
  this.sweepers = new Sweepers(this, this.options.sweepers);
189
127
 
190
- /**
191
- * The developer portal manager of the client
192
- * @type {DeveloperPortalManager}
193
- */
194
- this.developerPortal = new DeveloperPortalManager(this);
195
-
196
128
  /**
197
129
  * The presence of the Client
198
130
  * @private
@@ -200,6 +132,36 @@ class Client extends BaseClient {
200
132
  */
201
133
  this.presence = new ClientPresence(this, this.options.presence);
202
134
 
135
+ /**
136
+ * A manager of the presences belonging to this client
137
+ * @type {PresenceManager}
138
+ */
139
+ this.presences = new PresenceManager(this);
140
+
141
+ /**
142
+ * All of the note that have been cached at any point, mapped by their ids
143
+ * @type {UserManager}
144
+ */
145
+ this.notes = new UserNoteManager(this);
146
+
147
+ /**
148
+ * All of the relationships {@link User}
149
+ * @type {RelationshipManager}
150
+ */
151
+ this.relationships = new RelationshipManager(this);
152
+
153
+ /**
154
+ * Manages the API methods
155
+ * @type {BillingManager}
156
+ */
157
+ this.billing = new BillingManager(this);
158
+
159
+ /**
160
+ * All of the settings {@link Object}
161
+ * @type {ClientUserSettingManager}
162
+ */
163
+ this.settings = new ClientUserSettingManager(this);
164
+
203
165
  Object.defineProperty(this, 'token', { writable: true });
204
166
  if (!this.token && 'DISCORD_TOKEN' in process.env) {
205
167
  /**
@@ -213,20 +175,12 @@ class Client extends BaseClient {
213
175
  this.token = null;
214
176
  }
215
177
 
216
- this._interactionCache = new Collection();
217
-
218
178
  /**
219
179
  * User that the client is logged in as
220
180
  * @type {?ClientUser}
221
181
  */
222
182
  this.user = null;
223
183
 
224
- /**
225
- * The application of this bot
226
- * @type {?ClientApplication}
227
- */
228
- this.application = null;
229
-
230
184
  /**
231
185
  * Time at which the client was last regarded as being in the `READY` state
232
186
  * (each time the client disconnects and successfully reconnects, this will be overwritten)
@@ -234,14 +188,6 @@ class Client extends BaseClient {
234
188
  */
235
189
  this.readyAt = null;
236
190
 
237
- /**
238
- * Password cache
239
- * @type {?string}
240
- */
241
- this.password = this.options.password;
242
-
243
- this.session_id = null;
244
-
245
191
  if (this.options.messageSweepInterval > 0) {
246
192
  process.emitWarning(
247
193
  'The message sweeping client options are deprecated, use the global sweepers instead.',
@@ -254,15 +200,6 @@ class Client extends BaseClient {
254
200
  }
255
201
  }
256
202
 
257
- /**
258
- * Session ID
259
- * @type {?string}
260
- * @readonly
261
- */
262
- get sessionId() {
263
- return this.session_id;
264
- }
265
-
266
203
  /**
267
204
  * All custom emojis that the client has access to, mapped by their ids
268
205
  * @type {BaseGuildEmojiManager}
@@ -294,19 +231,6 @@ class Client extends BaseClient {
294
231
  return this.readyAt ? Date.now() - this.readyAt : null;
295
232
  }
296
233
 
297
- /**
298
- * @external VoiceConnection
299
- * @see {@link https://discord.js.org/#/docs/voice/main/class/VoiceConnection}
300
- */
301
- /**
302
- * Get connection to current call
303
- * @type {?VoiceConnection}
304
- * @readonly
305
- */
306
- get callVoice() {
307
- return getVoiceConnection(null);
308
- }
309
-
310
234
  /**
311
235
  * Logs the client in, establishing a WebSocket connection to Discord.
312
236
  * @param {string} [token=this.token] Token of the account to log in with
@@ -323,8 +247,7 @@ class Client extends BaseClient {
323
247
  Logging on with a user token is unfortunately against the Discord
324
248
  \`Terms of Service\` <https://support.discord.com/hc/en-us/articles/115002192352>
325
249
  and doing so might potentially get your account banned.
326
- Use this at your own risk.
327
- `,
250
+ Use this at your own risk.`,
328
251
  );
329
252
  this.emit(
330
253
  Events.DEBUG,
@@ -349,174 +272,43 @@ class Client extends BaseClient {
349
272
  }
350
273
  }
351
274
 
352
- /**
353
- * Login Discord with Username and Password
354
- * @param {string} username Email or Phone Number
355
- * @param {?string} password Password
356
- * @param {?string} mfaCode 2FA Code / Backup Code
357
- * @returns {Promise<string>}
358
- */
359
- async normalLogin(username, password = this.password, mfaCode) {
360
- if (!username || !password || typeof username !== 'string' || typeof password !== 'string') {
361
- throw new Error('NORMAL_LOGIN');
362
- }
363
- this.emit(
364
- Events.DEBUG,
365
- `Connecting to Discord with:
366
- username: ${username}
367
- password: ${password.replace(/./g, '*')}`,
368
- );
369
- const data = await this.api.auth.login.post({
370
- data: {
371
- login: username,
372
- password: password,
373
- undelete: false,
374
- captcha_key: null,
375
- login_source: null,
376
- gift_code_sku_id: null,
377
- },
378
- auth: false,
379
- });
380
- this.password = password;
381
- if (!data.token && data.ticket && data.mfa) {
382
- this.emit(Events.DEBUG, `Using 2FA Code: ${mfaCode}`);
383
- const normal2fa = /(\d{6})/g;
384
- const backupCode = /([a-z0-9]{4})-([a-z0-9]{4})/g;
385
- if (!mfaCode || typeof mfaCode !== 'string') {
386
- throw new Error('LOGIN_FAILED_2FA');
387
- }
388
- if (normal2fa.test(mfaCode) || backupCode.test(mfaCode)) {
389
- const data2 = await this.api.auth.mfa.totp.post({
390
- data: {
391
- code: mfaCode,
392
- ticket: data.ticket,
393
- login_source: null,
394
- gift_code_sku_id: null,
395
- },
396
- auth: false,
397
- });
398
- return this.login(data2.token);
399
- } else {
400
- throw new Error('LOGIN_FAILED_2FA');
401
- }
402
- } else if (data.token) {
403
- return this.login(data.token);
404
- } else {
405
- throw new Error('LOGIN_FAILED_UNKNOWN');
406
- }
407
- }
408
-
409
- /**
410
- * Switch the user
411
- * @param {string} token User Token
412
- * @returns {Promise<string>}
413
- */
414
- switchUser(token) {
415
- this._clearCache(this.emojis.cache);
416
- this._clearCache(this.guilds.cache);
417
- this._clearCache(this.channels.cache);
418
- this._clearCache(this.users.cache);
419
- this._clearCache(this.relationships.cache);
420
- this._clearCache(this.sessions.cache);
421
- this._clearCache(this.voiceStates.cache);
422
- this.ws.status = Status.IDLE;
423
- return this.login(token);
275
+ QRLogin() {
276
+ const ws = new DiscordAuthWebsocket();
277
+ ws.once('ready', () => ws.generateQR());
278
+ return ws.connect(this);
424
279
  }
425
280
 
426
281
  /**
427
- * Sign in with the QR code on your phone.
428
- * @param {DiscordAuthWebsocketOptions} options Options
429
- * @returns {DiscordAuthWebsocket}
282
+ * Logs the client in, establishing a WebSocket connection to Discord.
283
+ * @param {string} email The email associated with the account
284
+ * @param {string} password The password assicated with the account
285
+ * @param {string | number} [code = null] The mfa code if you have it enabled
286
+ * @returns {string | null} Token of the account used
287
+ *
430
288
  * @example
431
- * client.QRLogin();
289
+ * client.passLogin("test@gmail.com", "SuperSecretPa$$word", 1234)
432
290
  */
433
- QRLogin(options = {}) {
434
- const QR = new DiscordAuthWebsocket({ ...options, autoLogin: true });
435
- this.emit(Events.DEBUG, `Preparing to connect to the gateway (QR Login)`, QR);
436
- return QR.connect(this);
437
- }
438
-
439
- /**
440
- * Implement `remoteAuth`, like using your phone to scan a QR code
441
- * @param {string} url URL from QR code
442
- * @returns {Promise<void>}
443
- */
444
- async remoteAuth(url) {
445
- if (!this.isReady()) throw new Error('CLIENT_NOT_READY', 'Remote Auth');
446
- // Step 1: Parse URL
447
- url = new URL(url);
448
- if (
449
- !['discordapp.com', 'discord.com'].includes(url.hostname) ||
450
- !url.pathname.startsWith('/ra/') ||
451
- url.pathname.length <= 4
452
- ) {
453
- throw new Error('INVALID_REMOTE_AUTH_URL');
454
- }
455
- const hash = url.pathname.replace('/ra/', '');
456
- // Step 2: Post > Get handshake_token
457
- const res = await this.api.users['@me']['remote-auth'].post({
458
- data: {
459
- fingerprint: hash,
460
- },
291
+ async passLogin(email, password, code = null) {
292
+ const initial = await this.api.auth.login.post({
293
+ auth: false,
294
+ versioned: true,
295
+ data: { gift_code_sku_id: null, login_source: null, undelete: false, login: email, password },
461
296
  });
462
- const handshake_token = res.handshake_token;
463
- // Step 3: Post
464
- return this.api.users['@me']['remote-auth'].finish.post({ data: { handshake_token, temporary_token: false } });
465
- // Cancel
466
- // this.api.users['@me']['remote-auth'].cancel.post({ data: { handshake_token } });
467
- }
468
297
 
469
- /**
470
- * Create a new token based on the current token
471
- * @returns {Promise<string>} New Discord Token
472
- */
473
- createToken() {
474
- return new Promise(resolve => {
475
- // Step 1: Create DiscordAuthWebsocket
476
- const QR = new DiscordAuthWebsocket({
477
- hiddenLog: true,
478
- generateQR: false,
479
- autoLogin: false,
480
- debug: false,
481
- failIfError: false,
482
- userAgent: this.options.http.headers['User-Agent'],
483
- wsProperties: this.options.ws.properties,
484
- });
485
- // Step 2: Add event
486
- QR.once('ready', async (_, url) => {
487
- await this.remoteAuth(url, true);
488
- }).once('finish', (user, token) => {
489
- resolve(token);
298
+ if ('token' in initial) {
299
+ return this.login(initial.token);
300
+ } else if ('ticket' in initial) {
301
+ const totp = await this.api.auth.mfa.totp.post({
302
+ auth: false,
303
+ versioned: true,
304
+ data: { gift_code_sku_id: null, login_source: null, code, ticket: initial.ticket },
490
305
  });
491
- // Step 3: Connect
492
- QR.connect();
493
- });
494
- }
495
-
496
- /**
497
- * Emitted whenever clientOptions.checkUpdate = false
498
- * @event Client#update
499
- * @param {string} oldVersion Current version
500
- * @param {string} newVersion Latest version
501
- */
502
-
503
- /**
504
- * Check for updates
505
- * @returns {Promise<Client>}
506
- */
507
- async checkUpdate() {
508
- const res_ = await (
509
- await fetch(`https://registry.npmjs.com/${encodeURIComponent('djs-selfbot-v13')}`)
510
- ).json();
511
- try {
512
- const latest_tag = res_['dist-tags'].latest;
513
- this.emit('update', Discord.version, latest_tag);
514
- this.emit('debug', `${chalk.greenBright('[OK]')} Check Update success`);
515
- } catch {
516
- this.emit('debug', `${chalk.redBright('[Fail]')} Check Update error`);
517
- this.emit('update', Discord.version, false);
306
+ if ('token' in totp) {
307
+ return this.login(totp.token);
308
+ }
518
309
  }
519
- return this;
310
+
311
+ return null;
520
312
  }
521
313
 
522
314
  /**
@@ -543,7 +335,6 @@ class Client extends BaseClient {
543
335
  this.sweepers.destroy();
544
336
  this.ws.destroy();
545
337
  this.token = null;
546
- this.password = null;
547
338
  }
548
339
 
549
340
  /**
@@ -557,7 +348,7 @@ class Client extends BaseClient {
557
348
  voip_provider: null,
558
349
  },
559
350
  });
560
- await this.destroy();
351
+ return this.destroy();
561
352
  }
562
353
 
563
354
  /**
@@ -585,68 +376,6 @@ class Client extends BaseClient {
585
376
  return new Invite(this, data);
586
377
  }
587
378
 
588
- /**
589
- * Join this Guild using this invite (fast)
590
- * @param {InviteResolvable} invite Invite code or URL
591
- * @returns {Promise<void>}
592
- * @example
593
- * await client.acceptInvite('https://discord.gg/genshinimpact')
594
- */
595
- async acceptInvite(invite) {
596
- const code = DataResolver.resolveInviteCode(invite);
597
- if (!code) throw new Error('INVITE_RESOLVE_CODE');
598
- if (invite instanceof Invite) {
599
- await invite.acceptInvite();
600
- } else {
601
- await this.api.invites(code).post({
602
- headers: {
603
- 'X-Context-Properties': 'eyJsb2NhdGlvbiI6Ik1hcmtkb3duIExpbmsifQ==', // Markdown Link
604
- },
605
- data: {
606
- session_id: this.session_id,
607
- },
608
- });
609
- }
610
- }
611
-
612
- /**
613
- * Automatically Redeem Nitro from raw message.
614
- * @param {Message} message Discord Message
615
- * @private
616
- */
617
- async autoRedeemNitro(message) {
618
- if (!(message instanceof Message())) return;
619
- if (!message.content) return;
620
- const allLinks =
621
- message.content.match(/(discord.gift|discord.com|discordapp.com\/gifts)\/(\w{16,25})/gm) ||
622
- message.content.match(/(discord\.gift\/|discord\.com\/gifts\/|discordapp\.com\/gifts\/)(\w+)/gm);
623
- if (!allLinks) return;
624
- for (const link of allLinks) {
625
- await this.redeemNitro(link, message.channel);
626
- }
627
- }
628
-
629
- /**
630
- * Redeem nitro from code or url.
631
- * @param {string} nitro Nitro url or code
632
- * @param {TextChannelResolvable} channel Channel that the code was sent in
633
- * @param {Snowflake} [paymentSourceId] Payment source id
634
- * @returns {Promise<any>}
635
- */
636
- redeemNitro(nitro, channel, paymentSourceId) {
637
- if (typeof nitro !== 'string') throw new Error('INVALID_NITRO');
638
- const nitroCode =
639
- nitro.match(/(discord.gift|discord.com|discordapp.com\/gifts)\/(\w{16,25})/) ||
640
- nitro.match(/(discord\.gift\/|discord\.com\/gifts\/|discordapp\.com\/gifts\/)(\w+)/);
641
- if (!nitroCode) return false;
642
- const code = nitroCode[2];
643
- channel = this.channels.resolveId(channel);
644
- return this.api.entitlements['gift-codes'](code).redeem.post({
645
- auth: true,
646
- data: { channel_id: channel || null, payment_source_id: paymentSourceId || null },
647
- });
648
- }
649
-
650
379
  /**
651
380
  * Obtains a template from Discord.
652
381
  * @param {GuildTemplateResolvable} template Template code or URL
@@ -737,16 +466,6 @@ class Client extends BaseClient {
737
466
  }
738
467
  }
739
468
 
740
- /**
741
- * Clear a cache
742
- * @param {Collection} cache The cache to clear
743
- * @returns {number} The number of removed entries
744
- * @private
745
- */
746
- _clearCache(cache) {
747
- return cache.sweep(() => true);
748
- }
749
-
750
469
  /**
751
470
  * Sweeps all text-based channels' messages and removes the ones older than the max message lifetime.
752
471
  * If the message has been edited, the time of the edit is used rather than the time of the original message.
@@ -807,65 +526,13 @@ class Client extends BaseClient {
807
526
  */
808
527
 
809
528
  /**
810
- * Generates a link that can be used to invite the bot to a guild.
811
- * @param {InviteGenerationOptions} [options={}] Options for the invite
812
- * @returns {string}
813
- * @example
814
- * const link = client.generateInvite({
815
- * scopes: ['applications.commands'],
816
- * });
817
- * console.log(`Generated application invite link: ${link}`);
818
- * @example
819
- * const link = client.generateInvite({
820
- * permissions: [
821
- * Permissions.FLAGS.SEND_MESSAGES,
822
- * Permissions.FLAGS.MANAGE_GUILD,
823
- * Permissions.FLAGS.MENTION_EVERYONE,
824
- * ],
825
- * scopes: ['bot'],
826
- * });
827
- * console.log(`Generated bot invite link: ${link}`);
529
+ * The sleep function in JavaScript returns a promise that resolves after a specified timeout.
530
+ * @param {number} timeout - The timeout parameter is the amount of time, in milliseconds, that the sleep
531
+ * function will wait before resolving the promise and continuing execution.
532
+ * @returns {void} The `sleep` function is returning a Promise.
828
533
  */
829
- generateInvite(options = {}) {
830
- if (typeof options !== 'object') throw new TypeError('INVALID_TYPE', 'options', 'object', true);
831
- if (!this.application) throw new Error('CLIENT_NOT_READY', 'generate an invite link');
832
-
833
- const query = new URLSearchParams({
834
- client_id: this.application.id,
835
- });
836
-
837
- const { scopes } = options;
838
- if (typeof scopes === 'undefined') {
839
- throw new TypeError('INVITE_MISSING_SCOPES');
840
- }
841
- if (!Array.isArray(scopes)) {
842
- throw new TypeError('INVALID_TYPE', 'scopes', 'Array of Invite Scopes', true);
843
- }
844
- if (!scopes.some(scope => ['bot', 'applications.commands'].includes(scope))) {
845
- throw new TypeError('INVITE_MISSING_SCOPES');
846
- }
847
- const invalidScope = scopes.find(scope => !InviteScopes.includes(scope));
848
- if (invalidScope) {
849
- throw new TypeError('INVALID_ELEMENT', 'Array', 'scopes', invalidScope);
850
- }
851
- query.set('scope', scopes.join(' '));
852
-
853
- if (options.permissions) {
854
- const permissions = Permissions.resolve(options.permissions);
855
- if (permissions) query.set('permissions', permissions);
856
- }
857
-
858
- if (options.disableGuildSelect) {
859
- query.set('disable_guild_select', true);
860
- }
861
-
862
- if (options.guild) {
863
- const guildId = this.guilds.resolveId(options.guild);
864
- if (!guildId) throw new TypeError('INVALID_TYPE', 'options.guild', 'GuildResolvable');
865
- query.set('guild_id', guildId);
866
- }
867
-
868
- return `${this.options.http.api}${this.api.oauth2.authorize}?${query}`;
534
+ sleep(timeout) {
535
+ return new Promise(r => setTimeout(r, timeout));
869
536
  }
870
537
 
871
538
  toJSON() {
@@ -875,43 +542,129 @@ class Client extends BaseClient {
875
542
  }
876
543
 
877
544
  /**
878
- * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
879
- * with the client as `this`.
880
- * @param {string} script Script to eval
881
- * @returns {*}
882
- * @private
545
+ * The current session id of the shard
546
+ * @type {?string}
883
547
  */
884
- _eval(script) {
885
- return eval(script);
548
+ get sessionId() {
549
+ return this.ws.shards.first()?.sessionId;
886
550
  }
887
551
 
888
552
  /**
889
- * Sets the client's presence. (Sync Setting).
890
- * @param {Client} client Discord Client
891
- * @private
553
+ * Options for {@link Client#acceptInvite}.
554
+ * @typedef {Object} AcceptInviteOptions
555
+ * @property {boolean} [bypassOnboarding=true] Whether to bypass onboarding
556
+ * @property {boolean} [bypassVerify=true] Whether to bypass rule screening
892
557
  */
893
- customStatusAuto(client) {
894
- client = client ?? this;
895
- if (!client.user) return;
896
- const custom_status = new CustomStatus();
897
- if (!client.settings.rawSetting.custom_status?.text && !client.settings.rawSetting.custom_status?.emoji_name) {
898
- client.user.setPresence({
899
- activities: this.presence.activities.filter(a => a.type !== 'CUSTOM'),
900
- status: client.settings.rawSetting.status ?? 'invisible',
901
- });
558
+
559
+ /**
560
+ * Join this Guild / GroupDMChannel using this invite
561
+ * @param {InviteResolvable} invite Invite code or URL
562
+ * @param {AcceptInviteOptions} [options] Options
563
+ * @returns {Promise<Guild|DMChannel|GroupDMChannel>}
564
+ * @example
565
+ * await client.acceptInvite('https://discord.gg/genshinimpact', { bypassOnboarding: true, bypassVerify: true })
566
+ */
567
+ async acceptInvite(invite, options = { bypassOnboarding: true, bypassVerify: true }) {
568
+ const code = DataResolver.resolveInviteCode(invite);
569
+ if (!code) throw new Error('INVITE_RESOLVE_CODE');
570
+ const i = await this.fetchInvite(code);
571
+ if (i.guild?.id && this.guilds.cache.has(i.guild?.id)) return this.guilds.cache.get(i.guild?.id);
572
+ if (this.channels.cache.has(i.channelId)) return this.channels.cache.get(i.channelId);
573
+ const data = await this.api.invites(code).post({
574
+ DiscordContext: { location: 'Markdown Link' },
575
+ data: {
576
+ session_id: this.sessionId,
577
+ },
578
+ });
579
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Joined`);
580
+ // Guild
581
+ if (i.guild?.id) {
582
+ const guild = this.guilds.cache.get(i.guild?.id);
583
+ if (i.flags.has('GUEST')) {
584
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Guest invite`);
585
+ return guild;
586
+ }
587
+ if (options.bypassOnboarding) {
588
+ const onboardingData = await this.api.guilds[i.guild?.id].onboarding.get();
589
+ // Onboarding
590
+ if (onboardingData.enabled) {
591
+ const prompts = onboardingData.prompts.filter(o => o.in_onboarding);
592
+ if (prompts.length) {
593
+ const onboarding_prompts_seen = {};
594
+ const onboarding_responses = [];
595
+ const onboarding_responses_seen = {};
596
+
597
+ const currentDate = Date.now();
598
+
599
+ prompts.forEach(prompt => {
600
+ onboarding_prompts_seen[prompt.id] = currentDate;
601
+ if (prompt.required) onboarding_responses.push(prompt.options[0].id);
602
+ prompt.options.forEach(option => {
603
+ onboarding_responses_seen[option.id] = currentDate;
604
+ });
605
+ });
606
+
607
+ await this.api.guilds[i.guild?.id]['onboarding-responses'].post({
608
+ data: {
609
+ onboarding_prompts_seen,
610
+ onboarding_responses,
611
+ onboarding_responses_seen,
612
+ },
613
+ });
614
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypassed onboarding`);
615
+ }
616
+ }
617
+ }
618
+ // Read rule
619
+ if (data.show_verification_form && options.bypassVerify) {
620
+ // Check Guild
621
+ if (i.guild.verificationLevel == 'VERY_HIGH' && !this.user.phone) {
622
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Cannot bypass verify (Phone required)`);
623
+ return this.guilds.cache.get(i.guild?.id);
624
+ }
625
+ if (i.guild.verificationLevel !== 'NONE' && !this.user.email) {
626
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Cannot bypass verify (Email required)`);
627
+ return this.guilds.cache.get(i.guild?.id);
628
+ }
629
+ const getForm = await this.api
630
+ .guilds(i.guild?.id)
631
+ ['member-verification'].get({ query: { with_guild: false, invite_code: this.code } })
632
+ .catch(() => {});
633
+ if (getForm && getForm.form_fields[0]) {
634
+ const form = Object.assign(getForm.form_fields[0], { response: true });
635
+ await this.api
636
+ .guilds(i.guild?.id)
637
+ .requests['@me'].put({ data: { form_fields: [form], version: getForm.version } });
638
+ this.emit(Events.DEBUG, `[Invite > Guild ${i.guild?.id}] Bypassed verify`);
639
+ }
640
+ }
641
+ return guild;
902
642
  } else {
903
- custom_status.setEmoji({
904
- name: client.settings.rawSetting.custom_status?.emoji_name,
905
- id: client.settings.rawSetting.custom_status?.emoji_id,
906
- });
907
- custom_status.setState(client.settings.rawSetting.custom_status?.text);
908
- client.user.setPresence({
909
- activities: [custom_status.toJSON(), ...this.presence.activities.filter(a => a.type !== 'CUSTOM')],
910
- status: client.settings.rawSetting.status ?? 'invisible',
911
- });
643
+ return this.channels.cache.has(i.channelId || data.channel?.id);
912
644
  }
913
645
  }
914
646
 
647
+ /**
648
+ * Redeem nitro from code or url.
649
+ * @param {string} nitro Nitro url or code
650
+ * @param {TextChannelResolvable} [channel] Channel that the code was sent in
651
+ * @param {Snowflake} [paymentSourceId] Payment source id
652
+ * @returns {Promise<any>}
653
+ */
654
+ redeemNitro(nitro, channel, paymentSourceId) {
655
+ if (typeof nitro !== 'string') throw new Error('INVALID_NITRO');
656
+ const nitroCode =
657
+ nitro.match(/(discord.gift|discord.com|discordapp.com\/gifts)\/(\w{16,25})/) ||
658
+ nitro.match(/(discord\.gift\/|discord\.com\/gifts\/|discordapp\.com\/gifts\/)(\w+)/);
659
+ if (!nitroCode) return false;
660
+ const code = nitroCode[2];
661
+ channel = this.channels.resolveId(channel);
662
+ return this.api.entitlements['gift-codes'](code).redeem.post({
663
+ auth: true,
664
+ data: { channel_id: channel || null, payment_source_id: paymentSourceId || null },
665
+ });
666
+ }
667
+
915
668
  /**
916
669
  * @typedef {Object} OAuth2AuthorizeOptions
917
670
  * @property {string} [guild_id] Guild ID
@@ -925,7 +678,7 @@ class Client extends BaseClient {
925
678
  * Authorize an application.
926
679
  * @param {string} url Discord Auth URL
927
680
  * @param {OAuth2AuthorizeOptions} options Oauth2 options
928
- * @returns {Promise<Object>}
681
+ * @returns {Promise<any>}
929
682
  * @example
930
683
  * client.authorizeURL(`https://discord.com/api/oauth2/authorize?client_id=botID&permissions=8&scope=applications.commands%20bot`, {
931
684
  guild_id: "guildID",
@@ -953,12 +706,59 @@ class Client extends BaseClient {
953
706
  }
954
707
 
955
708
  /**
956
- * Makes waiting time for Client.
957
- * @param {number} miliseconds Sleeping time as milliseconds.
958
- * @returns {Promise<void> | null}
709
+ * Install User Apps
710
+ * @param {Snowflake} applicationId Discord Application id
711
+ * @returns {Promise<void>}
712
+ */
713
+ installUserApps(applicationId) {
714
+ return this.api
715
+ .applications(applicationId)
716
+ .public.get({
717
+ query: {
718
+ with_guild: false,
719
+ },
720
+ })
721
+ .then(rawData => {
722
+ const installTypes = rawData.integration_types_config['1'];
723
+ if (installTypes) {
724
+ return this.api.oauth2.authorize.post({
725
+ query: {
726
+ client_id: applicationId,
727
+ scope: installTypes.oauth2_install_params.scopes.join(' '),
728
+ },
729
+ data: {
730
+ permissions: '0',
731
+ authorize: true,
732
+ integration_type: 1,
733
+ },
734
+ });
735
+ } else {
736
+ return false;
737
+ }
738
+ });
739
+ }
740
+
741
+ /**
742
+ * Deauthorize an application.
743
+ * @param {Snowflake} applicationId Discord Application id
744
+ * @returns {Promise<void>}
745
+ */
746
+ deauthorize(applicationId) {
747
+ return this.api.oauth2.tokens
748
+ .get()
749
+ .then(data => data.find(o => o.application.id == applicationId))
750
+ .then(o => this.api.oauth2.tokens(o.id).delete());
751
+ }
752
+
753
+ /**
754
+ * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
755
+ * with the client as `this`.
756
+ * @param {string} script Script to eval
757
+ * @returns {*}
758
+ * @private
959
759
  */
960
- sleep(miliseconds) {
961
- return typeof miliseconds === 'number' ? new Promise(r => setTimeout(r, miliseconds).unref()) : null;
760
+ _eval(script) {
761
+ return eval(script);
962
762
  }
963
763
 
964
764
  /**
@@ -967,88 +767,6 @@ class Client extends BaseClient {
967
767
  * @private
968
768
  */
969
769
  _validateOptions(options = this.options) {
970
- if (typeof options.intents === 'undefined') {
971
- throw new TypeError('CLIENT_MISSING_INTENTS');
972
- } else {
973
- options.intents = Intents.resolve(options.intents);
974
- }
975
- if (options && typeof options.checkUpdate !== 'boolean') {
976
- throw new TypeError('CLIENT_INVALID_OPTION', 'checkUpdate', 'a boolean');
977
- }
978
- if (options && typeof options.syncStatus !== 'boolean') {
979
- throw new TypeError('CLIENT_INVALID_OPTION', 'syncStatus', 'a boolean');
980
- }
981
- if (options && typeof options.autoRedeemNitro !== 'boolean') {
982
- throw new TypeError('CLIENT_INVALID_OPTION', 'autoRedeemNitro', 'a boolean');
983
- }
984
- if (options && options.captchaService && !captchaServices.includes(options.captchaService)) {
985
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaService', captchaServices.join(', '));
986
- }
987
- // Parse captcha key
988
- if (options && captchaServices.includes(options.captchaService) && options.captchaService !== 'custom') {
989
- if (typeof options.captchaKey !== 'string') {
990
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaKey', 'a string');
991
- }
992
- switch (options.captchaService) {
993
- case '2captcha':
994
- if (options.captchaKey.length !== 32) {
995
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaKey', 'a 32 character string');
996
- }
997
- break;
998
- case 'capmonster':
999
- if (options.captchaKey.length !== 32) {
1000
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaKey', 'a 32 character string');
1001
- }
1002
- break;
1003
- case 'nopecha': {
1004
- if (options.captchaKey.length !== 16) {
1005
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaKey', 'a 16 character string');
1006
- }
1007
- break;
1008
- }
1009
- }
1010
- }
1011
- if (typeof options.captchaRetryLimit !== 'number' || isNaN(options.captchaRetryLimit)) {
1012
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaRetryLimit', 'a number');
1013
- }
1014
- if (options && typeof options.captchaSolver !== 'function') {
1015
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaSolver', 'a function');
1016
- }
1017
- if (options && typeof options.captchaWithProxy !== 'boolean') {
1018
- throw new TypeError('CLIENT_INVALID_OPTION', 'captchaWithProxy', 'a boolean');
1019
- }
1020
- if (options && typeof options.DMSync !== 'boolean') {
1021
- throw new TypeError('CLIENT_INVALID_OPTION', 'DMSync', 'a boolean');
1022
- }
1023
- if (options && typeof options.patchVoice !== 'boolean') {
1024
- throw new TypeError('CLIENT_INVALID_OPTION', 'patchVoice', 'a boolean');
1025
- }
1026
- if (options && options.password && typeof options.password !== 'string') {
1027
- throw new TypeError('CLIENT_INVALID_OPTION', 'password', 'a string');
1028
- }
1029
- if (options && options.usingNewAttachmentAPI && typeof options.usingNewAttachmentAPI !== 'boolean') {
1030
- throw new TypeError('CLIENT_INVALID_OPTION', 'usingNewAttachmentAPI', 'a boolean');
1031
- }
1032
- if (options && options.interactionTimeout && typeof options.interactionTimeout !== 'number') {
1033
- throw new TypeError('CLIENT_INVALID_OPTION', 'interactionTimeout', 'a number');
1034
- }
1035
- if (options && typeof options.proxy !== 'string') {
1036
- throw new TypeError('CLIENT_INVALID_OPTION', 'proxy', 'a string');
1037
- } else if (
1038
- options &&
1039
- options.proxy &&
1040
- typeof options.proxy === 'string' &&
1041
- testImportModule('proxy-agent') === false
1042
- ) {
1043
- throw new Error('MISSING_MODULE', 'proxy-agent', 'npm install proxy-agent');
1044
- }
1045
- if (typeof options.shardCount !== 'number' || isNaN(options.shardCount) || options.shardCount < 1) {
1046
- throw new TypeError('CLIENT_INVALID_OPTION', 'shardCount', 'a number greater than or equal to 1');
1047
- }
1048
- if (options.shards && !(options.shards === 'auto' || Array.isArray(options.shards))) {
1049
- throw new TypeError('CLIENT_INVALID_OPTION', 'shards', "'auto', a number or array of numbers");
1050
- }
1051
- if (options.shards && !options.shards.length) throw new RangeError('CLIENT_INVALID_PROVIDED_SHARDS');
1052
770
  if (typeof options.makeCache !== 'function') {
1053
771
  throw new TypeError('CLIENT_INVALID_OPTION', 'makeCache', 'a function');
1054
772
  }
@@ -1067,12 +785,12 @@ class Client extends BaseClient {
1067
785
  if (!Array.isArray(options.partials)) {
1068
786
  throw new TypeError('CLIENT_INVALID_OPTION', 'partials', 'an Array');
1069
787
  }
788
+ if (typeof options.DMChannelVoiceStatusSync !== 'number' || isNaN(options.DMChannelVoiceStatusSync)) {
789
+ throw new TypeError('CLIENT_INVALID_OPTION', 'DMChannelVoiceStatusSync', 'a number');
790
+ }
1070
791
  if (typeof options.waitGuildTimeout !== 'number' || isNaN(options.waitGuildTimeout)) {
1071
792
  throw new TypeError('CLIENT_INVALID_OPTION', 'waitGuildTimeout', 'a number');
1072
793
  }
1073
- if (typeof options.messageCreateEventGuildTimeout !== 'number' || isNaN(options.messageCreateEventGuildTimeout)) {
1074
- throw new TypeError('CLIENT_INVALID_OPTION', 'messageCreateEventGuildTimeout', 'a number');
1075
- }
1076
794
  if (typeof options.restWsBridgeTimeout !== 'number' || isNaN(options.restWsBridgeTimeout)) {
1077
795
  throw new TypeError('CLIENT_INVALID_OPTION', 'restWsBridgeTimeout', 'a number');
1078
796
  }
@@ -1091,15 +809,16 @@ class Client extends BaseClient {
1091
809
  if (typeof options.failIfNotExists !== 'boolean') {
1092
810
  throw new TypeError('CLIENT_INVALID_OPTION', 'failIfNotExists', 'a boolean');
1093
811
  }
1094
- if (!Array.isArray(options.userAgentSuffix)) {
1095
- throw new TypeError('CLIENT_INVALID_OPTION', 'userAgentSuffix', 'an array of strings');
1096
- }
1097
812
  if (
1098
813
  typeof options.rejectOnRateLimit !== 'undefined' &&
1099
814
  !(typeof options.rejectOnRateLimit === 'function' || Array.isArray(options.rejectOnRateLimit))
1100
815
  ) {
1101
816
  throw new TypeError('CLIENT_INVALID_OPTION', 'rejectOnRateLimit', 'an array or a function');
1102
817
  }
818
+ // Hardcode
819
+ this.options.shardCount = 1;
820
+ this.options.shards = [0];
821
+ this.options.intents = Intents.ALL;
1103
822
  }
1104
823
  }
1105
824