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.
- package/README.md +18 -35
- package/package.json +85 -100
- package/src/client/BaseClient.js +3 -4
- package/src/client/Client.js +249 -530
- package/src/client/actions/Action.js +18 -13
- package/src/client/actions/ActionsManager.js +7 -1
- package/src/client/actions/AutoModerationActionExecution.js +1 -0
- package/src/client/actions/AutoModerationRuleCreate.js +1 -0
- package/src/client/actions/AutoModerationRuleDelete.js +1 -0
- package/src/client/actions/AutoModerationRuleUpdate.js +1 -0
- package/src/client/actions/GuildMemberRemove.js +0 -1
- package/src/client/actions/GuildMemberUpdate.js +0 -1
- package/src/client/actions/MessageCreate.js +0 -4
- package/src/client/actions/PresenceUpdate.js +17 -16
- package/src/client/websocket/WebSocketManager.js +11 -31
- package/src/client/websocket/WebSocketShard.js +39 -38
- package/src/client/websocket/handlers/CALL_CREATE.js +3 -3
- package/src/client/websocket/handlers/CALL_DELETE.js +2 -2
- package/src/client/websocket/handlers/CALL_UPDATE.js +2 -2
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_ADD.js +16 -13
- package/src/client/websocket/handlers/CHANNEL_RECIPIENT_REMOVE.js +11 -11
- package/src/client/websocket/handlers/GUILD_CREATE.js +19 -13
- package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +0 -1
- package/src/client/websocket/handlers/INTERACTION_MODAL_CREATE.js +1 -0
- package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +22 -0
- package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +12 -0
- package/src/client/websocket/handlers/READY.js +90 -140
- package/src/client/websocket/handlers/RELATIONSHIP_ADD.js +7 -5
- package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +7 -5
- package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +32 -9
- package/src/client/websocket/handlers/USER_GUILD_SETTINGS_UPDATE.js +2 -8
- package/src/client/websocket/handlers/USER_NOTE_UPDATE.js +1 -1
- package/src/client/websocket/handlers/USER_REQUIRED_ACTION_UPDATE.js +78 -0
- package/src/client/websocket/handlers/USER_SETTINGS_UPDATE.js +1 -5
- package/src/client/websocket/handlers/VOICE_CHANNEL_STATUS_UPDATE.js +12 -0
- package/src/client/websocket/handlers/index.js +17 -20
- package/src/errors/Messages.js +25 -69
- package/src/index.js +13 -43
- package/src/managers/ApplicationCommandManager.js +9 -12
- package/src/managers/ApplicationCommandPermissionsManager.js +3 -11
- package/src/managers/ChannelManager.js +2 -3
- package/src/managers/ClientUserSettingManager.js +162 -280
- package/src/managers/GuildBanManager.js +47 -1
- package/src/managers/GuildChannelManager.js +2 -16
- package/src/managers/GuildForumThreadManager.js +24 -30
- package/src/managers/GuildManager.js +1 -1
- package/src/managers/GuildMemberManager.js +50 -222
- package/src/managers/GuildSettingManager.js +22 -15
- package/src/managers/MessageManager.js +42 -44
- package/src/managers/PermissionOverwriteManager.js +1 -1
- package/src/managers/ReactionUserManager.js +5 -5
- package/src/managers/RelationshipManager.js +83 -76
- package/src/managers/ThreadManager.js +12 -45
- package/src/managers/ThreadMemberManager.js +1 -1
- package/src/managers/UserManager.js +6 -10
- package/src/managers/UserNoteManager.js +53 -0
- package/src/rest/APIRequest.js +48 -20
- package/src/rest/DiscordAPIError.js +17 -16
- package/src/rest/RESTManager.js +1 -21
- package/src/rest/RequestHandler.js +35 -21
- package/src/structures/ApplicationCommand.js +19 -456
- package/src/structures/ApplicationRoleConnectionMetadata.js +3 -0
- package/src/structures/AutoModerationRule.js +5 -5
- package/src/structures/AutocompleteInteraction.js +1 -0
- package/src/structures/BaseGuildTextChannel.js +10 -12
- package/src/structures/BaseGuildVoiceChannel.js +16 -18
- package/src/structures/{Call.js → CallState.js} +17 -12
- package/src/structures/CategoryChannel.js +2 -0
- package/src/structures/Channel.js +2 -3
- package/src/structures/ClientPresence.js +20 -19
- package/src/structures/ClientUser.js +117 -338
- package/src/structures/ContextMenuInteraction.js +1 -1
- package/src/structures/DMChannel.js +29 -92
- package/src/structures/ForumChannel.js +0 -10
- package/src/structures/GroupDMChannel.js +387 -0
- package/src/structures/Guild.js +135 -271
- package/src/structures/GuildAuditLogs.js +0 -5
- package/src/structures/GuildChannel.js +16 -2
- package/src/structures/GuildMember.js +27 -145
- package/src/structures/Interaction.js +1 -62
- package/src/structures/Invite.js +35 -52
- package/src/structures/Message.js +220 -203
- package/src/structures/MessageAttachment.js +11 -0
- package/src/structures/MessageButton.js +1 -67
- package/src/structures/MessageEmbed.js +1 -1
- package/src/structures/MessageMentions.js +3 -2
- package/src/structures/MessagePayload.js +6 -46
- package/src/structures/MessagePoll.js +238 -0
- package/src/structures/MessageReaction.js +1 -1
- package/src/structures/MessageSelectMenu.js +1 -252
- package/src/structures/Modal.js +70 -188
- package/src/structures/Presence.js +787 -129
- package/src/structures/Role.js +18 -2
- package/src/structures/SelectMenuInteraction.js +2 -151
- package/src/structures/Team.js +0 -49
- package/src/structures/TextInputComponent.js +0 -70
- package/src/structures/ThreadChannel.js +0 -19
- package/src/structures/User.js +145 -339
- package/src/structures/UserContextMenuInteraction.js +2 -2
- package/src/structures/VoiceState.js +74 -39
- package/src/structures/WebEmbed.js +38 -52
- package/src/structures/Webhook.js +17 -11
- package/src/structures/interfaces/Application.js +146 -23
- package/src/structures/interfaces/TextBasedChannel.js +409 -256
- package/src/util/ApplicationFlags.js +1 -1
- package/src/util/AttachmentFlags.js +38 -0
- package/src/util/Constants.js +120 -285
- package/src/util/Formatters.js +16 -2
- package/src/util/InviteFlags.js +29 -0
- package/src/util/LimitedCollection.js +1 -1
- package/src/util/Options.js +48 -74
- package/src/util/Permissions.js +15 -0
- package/src/util/PurchasedFlags.js +2 -0
- package/src/util/RemoteAuth.js +221 -356
- package/src/util/RoleFlags.js +37 -0
- package/src/util/Sweepers.js +1 -1
- package/src/util/Util.js +158 -32
- package/typings/enums.d.ts +24 -73
- package/typings/index.d.ts +978 -1288
- package/typings/rawDataTypes.d.ts +68 -9
- package/src/client/actions/InteractionCreate.js +0 -115
- package/src/client/websocket/handlers/APPLICATION_COMMAND_AUTOCOMPLETE_RESPONSE.js +0 -23
- package/src/client/websocket/handlers/GUILD_APPLICATION_COMMANDS_UPDATE.js +0 -11
- package/src/client/websocket/handlers/GUILD_MEMBER_LIST_UPDATE.js +0 -55
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUNDS_UPDATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js +0 -0
- package/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js +0 -0
- package/src/client/websocket/handlers/INTERACTION_CREATE.js +0 -16
- package/src/client/websocket/handlers/INTERACTION_FAILURE.js +0 -18
- package/src/client/websocket/handlers/INTERACTION_SUCCESS.js +0 -30
- package/src/client/websocket/handlers/MESSAGE_ACK.js +0 -16
- package/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js +0 -0
- package/src/client/websocket/handlers/VOICE_CHANNEL_EFFECT_SEND.js +0 -0
- package/src/managers/DeveloperPortalManager.js +0 -104
- package/src/managers/GuildApplicationCommandManager.js +0 -28
- package/src/managers/GuildFolderManager.js +0 -24
- package/src/managers/SessionManager.js +0 -57
- package/src/rest/CaptchaSolver.js +0 -132
- package/src/structures/ClientApplication.js +0 -204
- package/src/structures/DeveloperPortalApplication.js +0 -520
- package/src/structures/GuildFolder.js +0 -75
- package/src/structures/InteractionResponse.js +0 -114
- package/src/structures/PartialGroupDMChannel.js +0 -433
- package/src/structures/RichPresence.js +0 -722
- package/src/structures/Session.js +0 -81
- package/src/util/Voice.js +0 -1456
- package/src/util/arRPC/index.js +0 -229
- package/src/util/arRPC/process/detectable.json +0 -1
- package/src/util/arRPC/process/index.js +0 -102
- package/src/util/arRPC/process/native/index.js +0 -5
- package/src/util/arRPC/process/native/linux.js +0 -37
- package/src/util/arRPC/process/native/win32.js +0 -25
- package/src/util/arRPC/transports/ipc.js +0 -281
- package/src/util/arRPC/transports/websocket.js +0 -128
package/src/client/Client.js
CHANGED
|
@@ -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
|
|
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
|
|
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,
|
|
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
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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
|
-
*
|
|
428
|
-
* @param {
|
|
429
|
-
* @
|
|
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.
|
|
289
|
+
* client.passLogin("test@gmail.com", "SuperSecretPa$$word", 1234)
|
|
432
290
|
*/
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
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
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
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
|
-
|
|
492
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
811
|
-
* @param {
|
|
812
|
-
*
|
|
813
|
-
* @
|
|
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
|
-
|
|
830
|
-
|
|
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
|
-
*
|
|
879
|
-
*
|
|
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
|
-
|
|
885
|
-
return
|
|
548
|
+
get sessionId() {
|
|
549
|
+
return this.ws.shards.first()?.sessionId;
|
|
886
550
|
}
|
|
887
551
|
|
|
888
552
|
/**
|
|
889
|
-
*
|
|
890
|
-
* @
|
|
891
|
-
* @
|
|
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
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
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
|
-
|
|
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<
|
|
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
|
-
*
|
|
957
|
-
* @param {
|
|
958
|
-
* @returns {Promise<void>
|
|
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
|
-
|
|
961
|
-
return
|
|
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
|
|