djs-selfbot-v13 3.1.8 → 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 (43) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +18 -8
  3. package/package.json +85 -71
  4. package/src/client/BaseClient.js +1 -1
  5. package/src/client/Client.js +81 -10
  6. package/src/client/actions/GuildMemberRemove.js +0 -1
  7. package/src/client/actions/GuildMemberUpdate.js +0 -1
  8. package/src/client/websocket/WebSocketShard.js +3 -3
  9. package/src/client/websocket/handlers/GUILD_CREATE.js +13 -14
  10. package/src/client/websocket/handlers/GUILD_MEMBER_ADD.js +0 -1
  11. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_ADD.js +22 -0
  12. package/src/client/websocket/handlers/MESSAGE_POLL_VOTE_REMOVE.js +12 -0
  13. package/src/client/websocket/handlers/READY.js +61 -21
  14. package/src/client/websocket/handlers/RELATIONSHIP_REMOVE.js +1 -1
  15. package/src/client/websocket/handlers/RELATIONSHIP_UPDATE.js +1 -1
  16. package/src/client/websocket/handlers/index.js +2 -0
  17. package/src/errors/Messages.js +1 -0
  18. package/src/index.js +4 -3
  19. package/src/managers/ChannelManager.js +1 -1
  20. package/src/managers/ClientUserSettingManager.js +2 -2
  21. package/src/managers/GuildBanManager.js +46 -0
  22. package/src/managers/GuildChannelManager.js +0 -16
  23. package/src/managers/GuildForumThreadManager.js +3 -3
  24. package/src/managers/GuildManager.js +1 -1
  25. package/src/managers/GuildMemberManager.js +11 -7
  26. package/src/managers/RelationshipManager.js +3 -3
  27. package/src/rest/APIRequest.js +13 -7
  28. package/src/structures/ClientPresence.js +9 -12
  29. package/src/structures/ClientUser.js +0 -2
  30. package/src/structures/Message.js +67 -76
  31. package/src/structures/MessagePayload.js +2 -0
  32. package/src/structures/MessagePoll.js +238 -0
  33. package/src/structures/Modal.js +11 -24
  34. package/src/structures/Presence.js +786 -128
  35. package/src/structures/User.js +35 -1
  36. package/src/structures/interfaces/TextBasedChannel.js +21 -23
  37. package/src/util/Constants.js +17 -4
  38. package/src/util/Options.js +1 -7
  39. package/src/util/Permissions.js +10 -0
  40. package/src/util/Util.js +88 -2
  41. package/typings/enums.d.ts +7 -1
  42. package/typings/index.d.ts +112 -70
  43. package/src/structures/RichPresence.js +0 -702
package/LICENSE CHANGED
@@ -1,7 +1,7 @@
1
1
  GNU GENERAL PUBLIC LICENSE
2
2
  Version 3, 29 June 2007
3
3
 
4
- Copyright (C) 2022 aiko-chan-ai and discordjs and 002-sans
4
+ Copyright (C) 2022 aiko-chan-ai and discordjs
5
5
  Everyone is permitted to copy and distribute verbatim copies
6
6
  of this license document, but changing it is not allowed.
7
7
 
package/README.md CHANGED
@@ -7,15 +7,15 @@
7
7
 
8
8
  ## About
9
9
 
10
- <strong>Welcome to `djs-selfbot-v13`, based on `discord.js@13.17`</strong>
10
+ <strong>Welcome to `discord.js-selfbot-v13@v3.2`, based on `discord.js@13.17`</strong>
11
11
 
12
- - djs-selfbot-v13 is a [Node.js](https://nodejs.org) module that allows user accounts to interact with the Discord API v9.
12
+ - discord.js-selfbot-v13 is a [Node.js](https://nodejs.org) module that allows user accounts to interact with the Discord API v9.
13
13
 
14
14
 
15
15
  <div align="center">
16
16
  <p>
17
- <a href="https://www.npmjs.com/package/djs-selfbot-v13"><img src="https://img.shields.io/npm/v/djs-selfbot-v13.svg" alt="npm version" /></a>
18
- <a href="https://www.npmjs.com/package/djs-selfbot-v13"><img src="https://img.shields.io/npm/dt/djs-selfbot-v13.svg" alt="npm downloads" /></a>
17
+ <a href="https://www.npmjs.com/package/discord.js-selfbot-v13"><img src="https://img.shields.io/npm/v/discord.js-selfbot-v13.svg" alt="npm version" /></a>
18
+ <a href="https://www.npmjs.com/package/discord.js-selfbot-v13"><img src="https://img.shields.io/npm/dt/discord.js-selfbot-v13.svg" alt="npm downloads" /></a>
19
19
  <a href="https://github.com/aiko-chan-ai/discord.js-selfbot-v13/actions"><img src="https://github.com/aiko-chan-ai/discord.js-selfbot-v13/actions/workflows/lint.yml/badge.svg" alt="Tests status" /></a>
20
20
  </p>
21
21
  </div>
@@ -38,7 +38,7 @@
38
38
  - [X] Interactions: Slash Commands, Buttons, Menu, Modal
39
39
  - [X] Captcha Handler (2captcha, capmonster, custom)
40
40
  - [X] Documentation
41
- - [x] Voice & Video stream
41
+ - [x] Voice & [Video stream](https://github.com/aiko-chan-ai/discord.js-selfbot-v13/issues/293)
42
42
  - [ ] Everything
43
43
 
44
44
  ## Installation
@@ -48,13 +48,13 @@
48
48
  > Recommended Node.js version: 18+ (LTS)
49
49
 
50
50
  ```sh-session
51
- npm install djs-selfbot-v13
51
+ npm install discord.js-selfbot-v13@latest
52
52
  ```
53
53
 
54
54
  ## Example
55
55
 
56
56
  ```js
57
- const { Client } = require('djs-selfbot-v13');
57
+ const { Client } = require('discord.js-selfbot-v13');
58
58
  const client = new Client();
59
59
 
60
60
  client.on('ready', async () => {
@@ -102,4 +102,14 @@ Github Discussion: [Here](https://github.com/aiko-chan-ai/discord.js-selfbot-v13
102
102
  ## Credits
103
103
  - [Discord.js](https://github.com/discordjs/discord.js)
104
104
 
105
- ## <strong><img src="https://cdn.discordapp.com/attachments/820557032016969751/952436539118456882/flag-vietnam_1f1fb-1f1f3.png" alt="." width="20" height="20"/> Other project(s)
105
+ ## <strong>Other project(s)
106
+
107
+ - 📘 [***aiko-chan-ai/DiscordBotClient***](https://github.com/aiko-chan-ai/DiscordBotClient) <br/>
108
+ A patched version of discord, with bot login support
109
+
110
+ ## Star History
111
+
112
+ [![Star History Chart](https://api.star-history.com/svg?repos=aiko-chan-ai/discord.js-selfbot-v13&type=Date)](https://star-history.com/#aiko-chan-ai/discord.js-selfbot-v13&Date)
113
+
114
+
115
+ # From Github with love 💕
package/package.json CHANGED
@@ -1,71 +1,85 @@
1
- {
2
- "name": "djs-selfbot-v13",
3
- "version": "3.1.8",
4
- "description": "A unofficial discord.js fork for creating selfbots [Based on discord.js v13]",
5
- "main": "./src/index.js",
6
- "types": "./typings/index.d.ts",
7
- "scripts": {
8
- "all": "npm run build && npm publish",
9
- "test": "npm run lint:all && npm run docs:test && npm run test:typescript",
10
- "fix:all": "npm run lint:fix && npm run lint:typings:fix && npm run format",
11
- "test:typescript": "tsc --noEmit && tsd",
12
- "lint": "eslint .",
13
- "lint:fix": "eslint . --fix",
14
- "lint:typings": "tslint typings/index.d.ts",
15
- "lint:typings:fix": "tslint typings/index.d.ts --fix",
16
- "format": "prettier --write src/**/*.js typings/**/*.ts",
17
- "lint:all": "npm run lint && npm run lint:typings",
18
- "docs": "docgen --source src --custom docs/index.yml --output docs/main.json",
19
- "docs:test": "docgen --source src --custom docs/index.yml",
20
- "build": "npm run lint:fix && npm run lint:typings:fix && npm run format && npm run docs"
21
- },
22
- "files": [
23
- "src",
24
- "typings"
25
- ],
26
- "directories": {
27
- "lib": "src",
28
- "test": "test"
29
- },
30
- "license": "GNU General Public License v3.0",
31
- "dependencies": {
32
- "@aikochan2k6/qrcode-terminal": "^0.12.1",
33
- "@discordjs/builders": "^1.6.3",
34
- "@discordjs/collection": "^1.5.3",
35
- "@sapphire/async-queue": "^1.5.1",
36
- "@sapphire/shapeshift": "^3.9.5",
37
- "@types/node-fetch": "^2.6.10",
38
- "@types/ws": "^8.5.10",
39
- "discord-api-types": "^0.37.61",
40
- "fetch-cookie": "^2.1.0",
41
- "form-data": "^4.0.0",
42
- "node-fetch": "^2.6.9",
43
- "tough-cookie": "^4.1.3",
44
- "ws": "^8.16.0"
45
- },
46
- "engines": {
47
- "node": ">=16.6.0",
48
- "npm": ">=7.0.0"
49
- },
50
- "devDependencies": {
51
- "@commitlint/cli": "^16.0.1",
52
- "@commitlint/config-angular": "^16.0.0",
53
- "@discordjs/docgen": "^0.11.1",
54
- "@favware/npm-deprecate": "^1.0.7",
55
- "@types/node": "^18.16.0",
56
- "conventional-changelog-cli": "^2.2.2",
57
- "dtslint": "^4.2.1",
58
- "eslint": "^8.39.0",
59
- "eslint-config-prettier": "^8.8.0",
60
- "eslint-plugin-import": "^2.27.5",
61
- "eslint-plugin-prettier": "^4.2.1",
62
- "husky": "^7.0.4",
63
- "is-ci": "^3.0.1",
64
- "jest": "^28.1.3",
65
- "lint-staged": "^12.1.4",
66
- "prettier": "^2.8.8",
67
- "tsd": "^0.28.1",
68
- "tslint": "^6.1.3",
69
- "typescript": "^4.9.5"
70
- }
71
- }
1
+ {
2
+ "name": "djs-selfbot-v13",
3
+ "version": "3.2.2",
4
+ "description": "A unofficial discord.js fork for creating selfbots [Based on discord.js v13]",
5
+ "main": "./src/index.js",
6
+ "types": "./typings/index.d.ts",
7
+ "scripts": {
8
+ "all": "npm run build && npm publish",
9
+ "test": "npm run lint:all && npm run docs:test && npm run test:typescript",
10
+ "fix:all": "npm run lint:fix && npm run lint:typings:fix && npm run format",
11
+ "test:typescript": "tsc --noEmit && tsd",
12
+ "lint": "eslint .",
13
+ "lint:fix": "eslint . --fix",
14
+ "lint:typings": "tslint typings/index.d.ts",
15
+ "lint:typings:fix": "tslint typings/index.d.ts --fix",
16
+ "format": "prettier --write src/**/*.js typings/**/*.ts",
17
+ "lint:all": "npm run lint && npm run lint:typings",
18
+ "docs": "docgen --source src --custom docs/index.yml --output docs/main.json",
19
+ "docs:test": "docgen --source src --custom docs/index.yml",
20
+ "build": "npm run lint:fix && npm run lint:typings:fix && npm run format && npm run docs"
21
+ },
22
+ "files": [
23
+ "src",
24
+ "typings"
25
+ ],
26
+ "directories": {
27
+ "lib": "src",
28
+ "test": "test"
29
+ },
30
+ "keywords": [
31
+ "discord.js",
32
+ "discord.js v13",
33
+ "selfbot",
34
+ "selfbot v13",
35
+ "djs",
36
+ "api",
37
+ "bot",
38
+ "node",
39
+ "discord",
40
+ "client",
41
+ "discordapp"
42
+ ],
43
+ "author": "aiko-chan-ai",
44
+ "license": "GNU General Public License v3.0",
45
+ "dependencies": {
46
+ "@aikochan2k6/qrcode-terminal": "^0.12.1",
47
+ "@discordjs/builders": "^1.6.3",
48
+ "@discordjs/collection": "^1.5.3",
49
+ "@sapphire/async-queue": "^1.5.2",
50
+ "@sapphire/shapeshift": "^3.9.5",
51
+ "@types/node-fetch": "^2.6.11",
52
+ "@types/ws": "^8.5.10",
53
+ "discord-api-types": "^0.37.61",
54
+ "fetch-cookie": "^2.1.0",
55
+ "form-data": "^4.0.0",
56
+ "node-fetch": "^2.6.9",
57
+ "tough-cookie": "^4.1.4",
58
+ "ws": "^8.16.0"
59
+ },
60
+ "engines": {
61
+ "node": ">=16.6.0",
62
+ "npm": ">=7.0.0"
63
+ },
64
+ "devDependencies": {
65
+ "@commitlint/cli": "^16.0.1",
66
+ "@commitlint/config-angular": "^16.0.0",
67
+ "@discordjs/docgen": "^0.11.1",
68
+ "@favware/npm-deprecate": "^1.0.7",
69
+ "@types/node": "^18.16.0",
70
+ "conventional-changelog-cli": "^2.2.2",
71
+ "dtslint": "^4.2.1",
72
+ "eslint": "^8.39.0",
73
+ "eslint-config-prettier": "^8.8.0",
74
+ "eslint-plugin-import": "^2.27.5",
75
+ "eslint-plugin-prettier": "^4.2.1",
76
+ "husky": "^7.0.4",
77
+ "is-ci": "^3.0.1",
78
+ "jest": "^28.1.3",
79
+ "lint-staged": "^12.1.4",
80
+ "prettier": "^2.8.8",
81
+ "tsd": "^0.28.1",
82
+ "tslint": "^6.1.3",
83
+ "typescript": "^4.9.5"
84
+ }
85
+ }
@@ -12,7 +12,7 @@ const Util = require('../util/Util');
12
12
  */
13
13
  class BaseClient extends EventEmitter {
14
14
  constructor(options = {}) {
15
- super();
15
+ super({ captureRejections: true });
16
16
 
17
17
  if (options.intents) {
18
18
  process.emitWarning('Intents is not available.', 'DeprecationWarning');
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-unreachable */
1
2
  'use strict';
2
3
 
3
4
  const process = require('node:process');
@@ -277,6 +278,39 @@ class Client extends BaseClient {
277
278
  return ws.connect(this);
278
279
  }
279
280
 
281
+ /**
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
+ *
288
+ * @example
289
+ * client.passLogin("test@gmail.com", "SuperSecretPa$$word", 1234)
290
+ */
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 },
296
+ });
297
+
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 },
305
+ });
306
+ if ('token' in totp) {
307
+ return this.login(totp.token);
308
+ }
309
+ }
310
+
311
+ return null;
312
+ }
313
+
280
314
  /**
281
315
  * Returns whether the client has logged in, indicative of being able to access
282
316
  * properties such as `user` and `application`.
@@ -525,7 +559,7 @@ class Client extends BaseClient {
525
559
  /**
526
560
  * Join this Guild / GroupDMChannel using this invite
527
561
  * @param {InviteResolvable} invite Invite code or URL
528
- * @param {AcceptInviteOptions} [options={ bypassOnboarding: true, bypassVerify: true }] Options
562
+ * @param {AcceptInviteOptions} [options] Options
529
563
  * @returns {Promise<Guild|DMChannel|GroupDMChannel>}
530
564
  * @example
531
565
  * await client.acceptInvite('https://discord.gg/genshinimpact', { bypassOnboarding: true, bypassVerify: true })
@@ -536,14 +570,6 @@ class Client extends BaseClient {
536
570
  const i = await this.fetchInvite(code);
537
571
  if (i.guild?.id && this.guilds.cache.has(i.guild?.id)) return this.guilds.cache.get(i.guild?.id);
538
572
  if (this.channels.cache.has(i.channelId)) return this.channels.cache.get(i.channelId);
539
- /*
540
- {
541
- location: 'Desktop Invite Modal',
542
- location_guild_id: i.guild?.id,
543
- location_channel_id: i.channelId,
544
- location_channel_type: typeof i.channel.type == 'number' ? i.channel.type : ChannelTypes[i.channel.type],
545
- }
546
- */
547
573
  const data = await this.api.invites(code).post({
548
574
  DiscordContext: { location: 'Markdown Link' },
549
575
  data: {
@@ -604,7 +630,7 @@ class Client extends BaseClient {
604
630
  .guilds(i.guild?.id)
605
631
  ['member-verification'].get({ query: { with_guild: false, invite_code: this.code } })
606
632
  .catch(() => {});
607
- if (getForm) {
633
+ if (getForm && getForm.form_fields[0]) {
608
634
  const form = Object.assign(getForm.form_fields[0], { response: true });
609
635
  await this.api
610
636
  .guilds(i.guild?.id)
@@ -679,6 +705,51 @@ class Client extends BaseClient {
679
705
  });
680
706
  }
681
707
 
708
+ /**
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
+
682
753
  /**
683
754
  * Calls {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval} on a script
684
755
  * with the client as `this`.
@@ -19,7 +19,6 @@ class GuildMemberRemoveAction extends Action {
19
19
  * Emitted whenever a member leaves a guild, or is kicked.
20
20
  * @event Client#guildMemberRemove
21
21
  * @param {GuildMember} member The member that has left/been kicked from the guild
22
- * @deprecated See {@link https://github.com/aiko-chan-ai/discord.js-selfbot-v13/issues/197 this issue} for more information.
23
22
  */
24
23
  if (shard.status === Status.READY) client.emit(Events.GUILD_MEMBER_REMOVE, member);
25
24
  }
@@ -25,7 +25,6 @@ class GuildMemberUpdateAction extends Action {
25
25
  * @event Client#guildMemberUpdate
26
26
  * @param {GuildMember} oldMember The member before the update
27
27
  * @param {GuildMember} newMember The member after the update
28
- * @deprecated See {@link https://github.com/aiko-chan-ai/discord.js-selfbot-v13/issues/197 this issue} for more information.
29
28
  */
30
29
  if (shard.status === Status.READY && !member.equals(old)) client.emit(Events.GUILD_MEMBER_UPDATE, old, member);
31
30
  } else {
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  const EventEmitter = require('node:events');
4
- const http = require('node:http');
5
4
  const { setTimeout, setInterval, clearTimeout } = require('node:timers');
6
5
  const WebSocket = require('../../WebSocket');
7
6
  const { Status, Events, ShardEvents, Opcodes, WSEvents, WSCodes } = require('../../util/Constants');
8
7
  const Intents = require('../../util/Intents');
8
+ const Util = require('../../util/Util');
9
9
 
10
10
  const STATUS_KEYS = Object.keys(Status);
11
11
  const CONNECTION_STATE = Object.keys(WebSocket.WebSocket);
@@ -272,7 +272,7 @@ class WebSocketShard extends EventEmitter {
272
272
  Version : ${client.options.ws.version}
273
273
  Encoding : ${WebSocket.encoding}
274
274
  Compression: ${zlib ? 'zlib-stream' : 'none'}
275
- Agent : ${client.options.ws.agent instanceof http.Agent}`,
275
+ Agent : ${Util.verifyProxyAgent(client.options.ws.agent)}`,
276
276
  );
277
277
 
278
278
  this.status = this.status === Status.DISCONNECTED ? Status.RECONNECTING : Status.CONNECTING;
@@ -283,7 +283,7 @@ class WebSocketShard extends EventEmitter {
283
283
  // Adding a handshake timeout to just make sure no zombie connection appears.
284
284
  const ws = (this.connection = WebSocket.create(gateway, wsQuery, {
285
285
  handshakeTimeout: 30_000,
286
- agent: client.options.ws.agent instanceof http.Agent ? client.options.ws.agent : undefined,
286
+ agent: Util.verifyProxyAgent(client.options.ws.agent) ? client.options.ws.agent : undefined,
287
287
  }));
288
288
  ws.onopen = this.onOpen.bind(this);
289
289
  ws.onmessage = this.onMessage.bind(this);
@@ -2,33 +2,32 @@
2
2
 
3
3
  const { Events, Opcodes, Status } = require('../../../util/Constants');
4
4
 
5
- // Receive messages in large guilds
6
5
  const run = (client, guild) => {
7
- if (!guild.large) return;
6
+ const subs = {};
7
+ subs[guild.id] = {
8
+ typing: true,
9
+ threads: true,
10
+ activities: true,
11
+ member_updates: true,
12
+ thread_member_lists: [],
13
+ members: [],
14
+ channels: {},
15
+ };
8
16
  client.ws.broadcast({
9
- op: Opcodes.GUILD_SUBSCRIPTIONS,
17
+ op: Opcodes.GUILD_SUBSCRIPTIONS_BULK,
10
18
  d: {
11
- guild_id: guild.id,
12
- typing: true,
13
- threads: false,
14
- activities: true,
15
- thread_member_lists: [],
16
- members: [],
17
- channels: {
18
- // [guild.channels.cache.first().id]: [[0, 99]],
19
- },
19
+ subscriptions: subs,
20
20
  },
21
21
  });
22
22
  };
23
23
 
24
24
  module.exports = (client, { d: data }, shard) => {
25
25
  let guild = client.guilds.cache.get(data.id);
26
+ run(client, data);
26
27
  if (guild) {
27
28
  if (!guild.available && !data.unavailable) {
28
29
  // A newly available guild
29
30
  guild._patch(data);
30
- run(client, guild);
31
-
32
31
  /**
33
32
  * Emitted whenever a guild becomes available.
34
33
  * @event Client#guildAvailable
@@ -12,7 +12,6 @@ module.exports = (client, { d: data }, shard) => {
12
12
  * Emitted whenever a user joins a guild.
13
13
  * @event Client#guildMemberAdd
14
14
  * @param {GuildMember} member The member that has joined a guild
15
- * @deprecated See {@link https://github.com/aiko-chan-ai/discord.js-selfbot-v13/issues/197 this issue} for more information.
16
15
  */
17
16
  client.emit(Events.GUILD_MEMBER_ADD, member);
18
17
  }
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const { Events } = require('../../../util/Constants');
4
+
5
+ module.exports = (client, { d: data }) => {
6
+ /**
7
+ * Poll Vote Structure
8
+ * @see {@link https://docs.discord.sex/resources/message#poll-results-structure}
9
+ * @typedef {Object} MessagePollUserVote
10
+ * @property {Snowflake} user_id ID of the user
11
+ * @property {Snowflake} channel_id ID of the channel
12
+ * @property {Snowflake} message_id ID of the message
13
+ * @property {?Snowflake} guild_id ID of the guild
14
+ * @property {number} answer_id ID of the answer
15
+ */
16
+ /**
17
+ * Emitted when a user votes on a poll. If the poll allows multiple selection, one event will be sent per answer.
18
+ * @event Client#messagePollVoteAdd
19
+ * @param {MessagePollUserVote} data Raw data
20
+ */
21
+ client.emit(Events.MESSAGE_POLL_VOTE_ADD, data);
22
+ };
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const { Events } = require('../../../util/Constants');
4
+
5
+ module.exports = (client, { d: data }) => {
6
+ /**
7
+ * Emitted when a user removes their vote on a poll. If the poll allows for multiple selections, one event will be sent per answer.
8
+ * @event Client#messagePollVoteRemove
9
+ * @param {MessagePollUserVote} data Raw data
10
+ */
11
+ client.emit(Events.MESSAGE_POLL_VOTE_REMOVE, data);
12
+ };
@@ -9,6 +9,9 @@ module.exports = (client, { d: data }, shard) => {
9
9
  // Check
10
10
  USER_REQUIRED_ACTION(client, { d: data });
11
11
 
12
+ // Overwrite ClientPresence
13
+ client.presence.userId = data.user.id;
14
+
12
15
  if (client.user) {
13
16
  client.user._patch(data.user);
14
17
  } else {
@@ -26,9 +29,6 @@ module.exports = (client, { d: data }, shard) => {
26
29
  client.guilds._add(guild);
27
30
  }
28
31
 
29
- const largeGuilds = data.guilds.filter(g => g.large);
30
- client.emit('debug', `[READY] Received ${data.guilds.length} guilds, ${largeGuilds.length} large guilds`);
31
-
32
32
  // User Notes
33
33
  client.notes._reload(data.notes);
34
34
 
@@ -45,24 +45,64 @@ module.exports = (client, { d: data }, shard) => {
45
45
  }
46
46
  // Todo: data.auth_session_id_hash
47
47
 
48
- if (largeGuilds.length) {
49
- client.ws.broadcast({
50
- op: Opcodes.GUILD_SUBSCRIPTIONS_BULK,
51
- d: {
52
- subscriptions: largeGuilds.reduce((accumulator, guild) => {
53
- accumulator[guild.id] = {
54
- typing: true,
55
- threads: true,
56
- activities: true,
57
- member_updates: true,
58
- thread_member_lists: [],
59
- members: [],
60
- channels: {},
61
- };
62
- return accumulator;
63
- }, {}),
64
- },
65
- });
48
+ if (data.guilds.length) {
49
+ if (data.guilds.length > 80) {
50
+ // Split data bc 15kb
51
+ const data1 = data.guilds.slice(0, Math.floor(data.guilds.length / 2));
52
+ const data2 = data.guilds.slice(Math.floor(data.guilds.length / 2));
53
+ client.ws.broadcast({
54
+ op: Opcodes.GUILD_SUBSCRIPTIONS_BULK,
55
+ d: {
56
+ subscriptions: data1.reduce((accumulator, guild) => {
57
+ accumulator[guild.id] = {
58
+ typing: true,
59
+ threads: true,
60
+ activities: true,
61
+ member_updates: true,
62
+ thread_member_lists: [],
63
+ members: [],
64
+ channels: {},
65
+ };
66
+ return accumulator;
67
+ }, {}),
68
+ },
69
+ });
70
+ client.ws.broadcast({
71
+ op: Opcodes.GUILD_SUBSCRIPTIONS_BULK,
72
+ d: {
73
+ subscriptions: data2.reduce((accumulator, guild) => {
74
+ accumulator[guild.id] = {
75
+ typing: true,
76
+ threads: true,
77
+ activities: true,
78
+ member_updates: true,
79
+ thread_member_lists: [],
80
+ members: [],
81
+ channels: {},
82
+ };
83
+ return accumulator;
84
+ }, {}),
85
+ },
86
+ });
87
+ } else {
88
+ client.ws.broadcast({
89
+ op: Opcodes.GUILD_SUBSCRIPTIONS_BULK,
90
+ d: {
91
+ subscriptions: data.guilds.reduce((accumulator, guild) => {
92
+ accumulator[guild.id] = {
93
+ typing: true,
94
+ threads: true,
95
+ activities: true,
96
+ member_updates: true,
97
+ thread_member_lists: [],
98
+ members: [],
99
+ channels: {},
100
+ };
101
+ return accumulator;
102
+ }, {}),
103
+ },
104
+ });
105
+ }
66
106
  }
67
107
 
68
108
  Promise.all(
@@ -10,7 +10,7 @@ module.exports = (client, { d: data }) => {
10
10
  * Emitted when a relationship is removed, relevant to the current user.
11
11
  * @event Client#relationshipRemove
12
12
  * @param {Snowflake} user The userID that was updated
13
- * @param {RelationshipTypes} type The type of the old relationship
13
+ * @param {RelationshipType} type The type of the old relationship
14
14
  * @param {string | null} nickname The nickname of the user in this relationship (1-32 characters)
15
15
  */
16
16
  client.emit(Events.RELATIONSHIP_REMOVE, data.id, data.type, data.nickname);
@@ -5,7 +5,7 @@ const { Events } = require('../../../util/Constants');
5
5
  module.exports = (client, { d: data }) => {
6
6
  /**
7
7
  * @typedef {Object} RelationshipUpdateObject
8
- * @property {RelationshipTypes} type The type of relationship
8
+ * @property {RelationshipType} type The type of relationship
9
9
  * @property {Date} since When the user requested a relationship
10
10
  * @property {string | null} nickname The nickname of the user in this relationship (1-32 characters)
11
11
  */
@@ -76,6 +76,8 @@ const handlers = Object.fromEntries([
76
76
  ['USER_SETTINGS_UPDATE', require('./USER_SETTINGS_UPDATE')],
77
77
  ['USER_GUILD_SETTINGS_UPDATE', require('./USER_GUILD_SETTINGS_UPDATE')],
78
78
  ['VOICE_CHANNEL_STATUS_UPDATE', require('./VOICE_CHANNEL_STATUS_UPDATE')],
79
+ ['MESSAGE_POLL_VOTE_ADD', require('./MESSAGE_POLL_VOTE_ADD')],
80
+ ['MESSAGE_POLL_VOTE_REMOVE', require('./MESSAGE_POLL_VOTE_REMOVE')],
79
81
  ]);
80
82
 
81
83
  module.exports = handlers;
@@ -169,6 +169,7 @@ const Messages = {
169
169
 
170
170
  // Selfbot
171
171
  INVALID_USER_API: 'User accounts cannot use this endpoint',
172
+ INVALID_APPLICATION_COMMAND: id => `Could not find a valid command for this bot: ${id}`,
172
173
  INVALID_COMMAND_NAME: allCMD => `Could not parse subGroupCommand and subCommand due to too long: ${allCMD.join(' ')}`,
173
174
  INVALID_SLASH_COMMAND_CHOICES: (parentOptions, value) =>
174
175
  `${value} is not a valid choice for this option (${parentOptions})`,