v2.2.0
Discord.js v13.8.0
This commit is contained in:
parent
832bc010c5
commit
305ccaac90
@ -14,7 +14,7 @@
|
||||
|
||||
## About
|
||||
|
||||
<strong>Welcome to `discord.js-selfbot-v13@v2`, based on `discord.js@13.7.0`</strong>
|
||||
<strong>Welcome to `discord.js-selfbot-v13@v2.2`, based on `discord.js@13.8.0`</strong>
|
||||
|
||||
- discord.js-selfbot-v13 is a [Node.js](https://nodejs.org) module that allows user accounts to interact with the Discord API v9.
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
174
package-lock.json
generated
174
package-lock.json
generated
@ -1,17 +1,17 @@
|
||||
{
|
||||
"name": "discord.js-selfbot-v13",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "discord.js-selfbot-v13",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"license": "GNU General Public License v3.0",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^0.13.0",
|
||||
"@discordjs/collection": "^0.6.0",
|
||||
"@discordjs/voice": "^0.9.0",
|
||||
"@discordjs/builders": "^0.14.0",
|
||||
"@discordjs/collection": "^0.7.0",
|
||||
"@discordjs/voice": "^0.10.0",
|
||||
"@sapphire/async-queue": "^1.3.1",
|
||||
"@sapphire/snowflake": "^3.2.2",
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
@ -21,10 +21,10 @@
|
||||
"bignumber.js": "^9.0.2",
|
||||
"bufferutil": "^4.0.6",
|
||||
"chalk": "^4.1.2",
|
||||
"discord-api-types": "^0.33.2",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"discord-bettermarkdown": "^1.2.0",
|
||||
"discord-rpc-contructor": "^1.1.5",
|
||||
"discord.js": "^13.7.0",
|
||||
"discord.js": "^13.8.0",
|
||||
"form-data": "^4.0.0",
|
||||
"i": "^0.3.7",
|
||||
"json-bigint": "^1.0.0",
|
||||
@ -1015,30 +1015,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.13.0.tgz",
|
||||
"integrity": "sha512-4L9y26KRNNU8Y7J78SRUN1Uhava9D8jfit/YqEaKi8gQRc7PdqKqk2poybo6RXaiyt/BgKYPfcjxT7WvzGfYCA==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz",
|
||||
"integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==",
|
||||
"dependencies": {
|
||||
"@sapphire/shapeshift": "^2.0.0",
|
||||
"@sapphire/shapeshift": "^3.1.0",
|
||||
"@sindresorhus/is": "^4.6.0",
|
||||
"discord-api-types": "^0.31.1",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.1",
|
||||
"tslib": "^2.3.1"
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
|
||||
"version": "0.31.2",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.31.2.tgz",
|
||||
"integrity": "sha512-gpzXTvFVg7AjKVVJFH0oJGC0q0tO34iJGSHZNz9u3aqLxlD6LfxEs9wWVVikJqn9gra940oUTaPFizCkRDcEiA=="
|
||||
},
|
||||
"node_modules/@discordjs/collection": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.6.0.tgz",
|
||||
"integrity": "sha512-Ieaetb36l0nmAS5X9Upqk4W7euAO6FdXPxn3I8vBAKEcoIzEZI1mcVcPfCfagGJZSgBKpENnAnKkP4GAn+MV8w==",
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
|
||||
"integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==",
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
}
|
||||
@ -1666,26 +1661,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/voice": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.9.0.tgz",
|
||||
"integrity": "sha512-fSAYtPCEfIyG56hC2cRJuyfvQGr+aawSssLCqYg70vZ51dKO4spEKOB8V6vNMP5HnEplbhmxkB3YbshFKtnCQQ==",
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.10.0.tgz",
|
||||
"integrity": "sha512-tChDKRRbKwWHcyq1dSEzrnuCMJyLtKXcFhgQpqcS2YjZ1TLlXboc/mhrR8jA1Yb1rB81u8dgj/lPkkHsk0ItEg==",
|
||||
"dependencies": {
|
||||
"@types/ws": "^8.5.3",
|
||||
"discord-api-types": "^0.29.0",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"prism-media": "^1.3.2",
|
||||
"tiny-typed-emitter": "^2.1.0",
|
||||
"tslib": "^2.3.1",
|
||||
"ws": "^8.5.0"
|
||||
"tslib": "^2.4.0",
|
||||
"ws": "^8.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@discordjs/voice/node_modules/discord-api-types": {
|
||||
"version": "0.29.0",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.29.0.tgz",
|
||||
"integrity": "sha512-Ekq1ICNpOTVajXKZguNFrsDeTmam+ZeA38txsNLZnANdXUjU6QBPIZLUQTC6MzigFGb0Tt8vk4xLnXmzv0shNg=="
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
|
||||
@ -2337,9 +2327,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@sapphire/shapeshift": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-2.1.0.tgz",
|
||||
"integrity": "sha512-Z1ISLP9pNI3jpKJxx82xtDpEsfomhJ3iPqcKdYLjAHmQP2X5yqQF6phA0Wd+MmdXp081wepOiT59XEN0xdTVvQ==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.1.0.tgz",
|
||||
"integrity": "sha512-PkxFXd3QJ1qAPS05Dy2UkVGYPm/asF1Ugt2Xyzmv4DHzO3+G7l+873C4XFFcJ9M5Je+eCMC7SSifgPTSur5QuA==",
|
||||
"engines": {
|
||||
"node": ">=v15.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
@ -4435,9 +4425,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/discord-api-types": {
|
||||
"version": "0.33.2",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.2.tgz",
|
||||
"integrity": "sha512-ZiYvIUAOQnN98+TRaXH8HZdaCofNZDoUad4piVE1lfjlM1E3LRaRIyZOs4eWcWU/gI0P8oTTXyXCjfqKzV7YDw=="
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.3.tgz",
|
||||
"integrity": "sha512-P3A1RJXKEDmGPHrFTN5+gYLsBPGUVGj+D3+fa3m0K/umc+LMfqGuEad+p7cNq7ry/icReVhS3bz9jvBvne/BRA=="
|
||||
},
|
||||
"node_modules/discord-bettermarkdown": {
|
||||
"version": "1.2.0",
|
||||
@ -4457,30 +4447,25 @@
|
||||
}
|
||||
},
|
||||
"node_modules/discord.js": {
|
||||
"version": "13.7.0",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.7.0.tgz",
|
||||
"integrity": "sha512-iV/An3FEB/CiBGdjWHRtgskM4UuWPq5vjhjKsrQhdVU16dbKrBxA+eIV2HWA07B3tXUGM6eco1wkr42gxxV1BA==",
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz",
|
||||
"integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^0.13.0",
|
||||
"@discordjs/collection": "^0.6.0",
|
||||
"@discordjs/builders": "^0.14.0",
|
||||
"@discordjs/collection": "^0.7.0",
|
||||
"@sapphire/async-queue": "^1.3.1",
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
"@types/ws": "^8.5.3",
|
||||
"discord-api-types": "^0.30.0",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"form-data": "^4.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"ws": "^8.6.0"
|
||||
"ws": "^8.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.6.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/discord.js/node_modules/discord-api-types": {
|
||||
"version": "0.30.0",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz",
|
||||
"integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw=="
|
||||
},
|
||||
"node_modules/dmd": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/dmd/-/dmd-4.0.6.tgz",
|
||||
@ -13934,9 +13919,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"node_modules/tslint": {
|
||||
"version": "6.1.3",
|
||||
@ -15446,29 +15431,22 @@
|
||||
}
|
||||
},
|
||||
"@discordjs/builders": {
|
||||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.13.0.tgz",
|
||||
"integrity": "sha512-4L9y26KRNNU8Y7J78SRUN1Uhava9D8jfit/YqEaKi8gQRc7PdqKqk2poybo6RXaiyt/BgKYPfcjxT7WvzGfYCA==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.14.0.tgz",
|
||||
"integrity": "sha512-+fqLIqa9wN3R+kvlld8sgG0nt04BAZxdCDP4t2qZ9TJsquLWA+xMtT8Waibb3d4li4AQS+IOfjiHAznv/dhHgQ==",
|
||||
"requires": {
|
||||
"@sapphire/shapeshift": "^2.0.0",
|
||||
"@sapphire/shapeshift": "^3.1.0",
|
||||
"@sindresorhus/is": "^4.6.0",
|
||||
"discord-api-types": "^0.31.1",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"ts-mixer": "^6.0.1",
|
||||
"tslib": "^2.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord-api-types": {
|
||||
"version": "0.31.2",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.31.2.tgz",
|
||||
"integrity": "sha512-gpzXTvFVg7AjKVVJFH0oJGC0q0tO34iJGSHZNz9u3aqLxlD6LfxEs9wWVVikJqn9gra940oUTaPFizCkRDcEiA=="
|
||||
}
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"@discordjs/collection": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.6.0.tgz",
|
||||
"integrity": "sha512-Ieaetb36l0nmAS5X9Upqk4W7euAO6FdXPxn3I8vBAKEcoIzEZI1mcVcPfCfagGJZSgBKpENnAnKkP4GAn+MV8w=="
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
|
||||
"integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA=="
|
||||
},
|
||||
"@discordjs/docgen": {
|
||||
"version": "0.11.1",
|
||||
@ -15953,23 +15931,16 @@
|
||||
}
|
||||
},
|
||||
"@discordjs/voice": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.9.0.tgz",
|
||||
"integrity": "sha512-fSAYtPCEfIyG56hC2cRJuyfvQGr+aawSssLCqYg70vZ51dKO4spEKOB8V6vNMP5HnEplbhmxkB3YbshFKtnCQQ==",
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@discordjs/voice/-/voice-0.10.0.tgz",
|
||||
"integrity": "sha512-tChDKRRbKwWHcyq1dSEzrnuCMJyLtKXcFhgQpqcS2YjZ1TLlXboc/mhrR8jA1Yb1rB81u8dgj/lPkkHsk0ItEg==",
|
||||
"requires": {
|
||||
"@types/ws": "^8.5.3",
|
||||
"discord-api-types": "^0.29.0",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"prism-media": "^1.3.2",
|
||||
"tiny-typed-emitter": "^2.1.0",
|
||||
"tslib": "^2.3.1",
|
||||
"ws": "^8.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord-api-types": {
|
||||
"version": "0.29.0",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.29.0.tgz",
|
||||
"integrity": "sha512-Ekq1ICNpOTVajXKZguNFrsDeTmam+ZeA38txsNLZnANdXUjU6QBPIZLUQTC6MzigFGb0Tt8vk4xLnXmzv0shNg=="
|
||||
}
|
||||
"tslib": "^2.4.0",
|
||||
"ws": "^8.7.0"
|
||||
}
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
@ -16483,9 +16454,9 @@
|
||||
}
|
||||
},
|
||||
"@sapphire/shapeshift": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-2.1.0.tgz",
|
||||
"integrity": "sha512-Z1ISLP9pNI3jpKJxx82xtDpEsfomhJ3iPqcKdYLjAHmQP2X5yqQF6phA0Wd+MmdXp081wepOiT59XEN0xdTVvQ=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.1.0.tgz",
|
||||
"integrity": "sha512-PkxFXd3QJ1qAPS05Dy2UkVGYPm/asF1Ugt2Xyzmv4DHzO3+G7l+873C4XFFcJ9M5Je+eCMC7SSifgPTSur5QuA=="
|
||||
},
|
||||
"@sapphire/snowflake": {
|
||||
"version": "3.2.2",
|
||||
@ -18148,9 +18119,9 @@
|
||||
}
|
||||
},
|
||||
"discord-api-types": {
|
||||
"version": "0.33.2",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.2.tgz",
|
||||
"integrity": "sha512-ZiYvIUAOQnN98+TRaXH8HZdaCofNZDoUad4piVE1lfjlM1E3LRaRIyZOs4eWcWU/gI0P8oTTXyXCjfqKzV7YDw=="
|
||||
"version": "0.33.3",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.3.tgz",
|
||||
"integrity": "sha512-P3A1RJXKEDmGPHrFTN5+gYLsBPGUVGj+D3+fa3m0K/umc+LMfqGuEad+p7cNq7ry/icReVhS3bz9jvBvne/BRA=="
|
||||
},
|
||||
"discord-bettermarkdown": {
|
||||
"version": "1.2.0",
|
||||
@ -18170,26 +18141,19 @@
|
||||
}
|
||||
},
|
||||
"discord.js": {
|
||||
"version": "13.7.0",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.7.0.tgz",
|
||||
"integrity": "sha512-iV/An3FEB/CiBGdjWHRtgskM4UuWPq5vjhjKsrQhdVU16dbKrBxA+eIV2HWA07B3tXUGM6eco1wkr42gxxV1BA==",
|
||||
"version": "13.8.0",
|
||||
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.8.0.tgz",
|
||||
"integrity": "sha512-EPAA/2VLycYN5wSzavqa4iJ6qj3UtQFtHw5TH/60Fj29ymfEsCQVn//o1mTpwDxzwb+rPIrWhkxKIGGnjfv0Iw==",
|
||||
"requires": {
|
||||
"@discordjs/builders": "^0.13.0",
|
||||
"@discordjs/collection": "^0.6.0",
|
||||
"@discordjs/builders": "^0.14.0",
|
||||
"@discordjs/collection": "^0.7.0",
|
||||
"@sapphire/async-queue": "^1.3.1",
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
"@types/ws": "^8.5.3",
|
||||
"discord-api-types": "^0.30.0",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"form-data": "^4.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"ws": "^8.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"discord-api-types": {
|
||||
"version": "0.30.0",
|
||||
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.30.0.tgz",
|
||||
"integrity": "sha512-wYst0jrT8EJs2tVlwUTQ2xT0oWMjUrRMpFTkNY3NMleWyQNHgWaKhqFfxdLPdC2im9IuR5EsxcEgjhf/npeftw=="
|
||||
}
|
||||
"ws": "^8.7.0"
|
||||
}
|
||||
},
|
||||
"dmd": {
|
||||
@ -25169,9 +25133,9 @@
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
|
||||
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
|
||||
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="
|
||||
},
|
||||
"tslint": {
|
||||
"version": "6.1.3",
|
||||
|
16
package.json
16
package.json
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "discord.js-selfbot-v13",
|
||||
"version": "2.1.0",
|
||||
"version": "2.2.0",
|
||||
"description": "A unofficial discord.js fork for creating selfbots [Based on discord.js v13]",
|
||||
"main": "./src/index.js",
|
||||
"types": "./typings/index.d.ts",
|
||||
"scripts": {
|
||||
"all": "npm run test && npm run test:typescript && npm run fix:all && npm run build",
|
||||
"test": "npm run lint:all && npm run lint:typings && npm run docs:test",
|
||||
"all": "npm run lint:fix && npm run lint:typings:fix && npm run fix:all && npm run build",
|
||||
"test": "npm run lint:all && npm run docs:test && npm run test:typescript",
|
||||
"fix:all": "npm run lint:fix && npm run lint:typings:fix && npm run format",
|
||||
"test:typescript": "tsc --noEmit && tsd",
|
||||
"lint": "eslint .",
|
||||
@ -51,9 +51,9 @@
|
||||
},
|
||||
"homepage": "https://github.com/aiko-chan-ai/discord.js-selfbot-v13#readme",
|
||||
"dependencies": {
|
||||
"@discordjs/builders": "^0.13.0",
|
||||
"@discordjs/collection": "^0.6.0",
|
||||
"@discordjs/voice": "^0.9.0",
|
||||
"@discordjs/builders": "^0.14.0",
|
||||
"@discordjs/collection": "^0.7.0",
|
||||
"@discordjs/voice": "^0.10.0",
|
||||
"@sapphire/async-queue": "^1.3.1",
|
||||
"@sapphire/snowflake": "^3.2.2",
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
@ -63,10 +63,10 @@
|
||||
"bignumber.js": "^9.0.2",
|
||||
"bufferutil": "^4.0.6",
|
||||
"chalk": "^4.1.2",
|
||||
"discord-api-types": "^0.33.2",
|
||||
"discord-api-types": "^0.33.3",
|
||||
"discord-bettermarkdown": "^1.2.0",
|
||||
"discord-rpc-contructor": "^1.1.5",
|
||||
"discord.js": "^13.7.0",
|
||||
"discord.js": "^13.8.0",
|
||||
"form-data": "^4.0.0",
|
||||
"i": "^0.3.7",
|
||||
"json-bigint": "^1.0.0",
|
||||
|
@ -10,7 +10,7 @@ class WebhooksUpdate extends Action {
|
||||
/**
|
||||
* Emitted whenever a channel has its webhooks changed.
|
||||
* @event Client#webhookUpdate
|
||||
* @param {TextChannel|NewsChannel} channel The channel that had a webhook update
|
||||
* @param {TextChannel|NewsChannel|VoiceChannel} channel The channel that had a webhook update
|
||||
*/
|
||||
if (channel) client.emit(Events.WEBHOOKS_UPDATE, channel);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ const BeforeReadyWhitelist = [
|
||||
WSEvents.GUILD_MEMBER_REMOVE,
|
||||
];
|
||||
|
||||
const UNRECOVERABLE_CLOSE_CODES = Object.keys(WSCodes).slice(1).map(Number);
|
||||
const UNRECOVERABLE_CLOSE_CODES = Object.keys(WSCodes).slice(2).map(Number);
|
||||
const UNRESUMABLE_CLOSE_CODES = [
|
||||
RPCErrorCodes.UnknownError,
|
||||
RPCErrorCodes.InvalidPermissions,
|
||||
@ -216,13 +216,8 @@ class WebSocketManager extends EventEmitter {
|
||||
|
||||
this.shardQueue.add(shard);
|
||||
|
||||
if (shard.sessionId) {
|
||||
this.debug('Session id is present, attempting an immediate reconnect...', shard);
|
||||
this.reconnect();
|
||||
} else {
|
||||
shard.destroy({ reset: true, emit: false, log: false });
|
||||
this.reconnect();
|
||||
}
|
||||
if (shard.sessionId) this.debug(`Session id is present, attempting an immediate reconnect...`, shard);
|
||||
this.reconnect();
|
||||
});
|
||||
|
||||
shard.on(ShardEvents.INVALID_SESSION, () => {
|
||||
@ -352,6 +347,12 @@ class WebSocketManager extends EventEmitter {
|
||||
} else if (packet) {
|
||||
/* Debug mode */
|
||||
// console.log(`Unhandled packet: ${packet.t}`, packet);
|
||||
/**
|
||||
* Emitted whenever a packet isn't handled.
|
||||
* @event Client#unhandledPacket
|
||||
* @param {Object} packet The packet (t: Event name, d: Data)
|
||||
* @param {Number} shard The shard that received the packet (Auto = 0)
|
||||
*/
|
||||
this.client.emit(Events.UNHANDLED_PACKET, packet, shard);
|
||||
}
|
||||
return true;
|
||||
|
@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('node:events');
|
||||
const { setTimeout, setInterval } = require('node:timers');
|
||||
const { setTimeout, setInterval, clearTimeout } = require('node:timers');
|
||||
const WebSocket = require('../../WebSocket');
|
||||
const { Status, Events, ShardEvents, Opcodes, WSEvents } = require('../../util/Constants');
|
||||
const { Status, Events, ShardEvents, Opcodes, WSEvents, WSCodes } = require('../../util/Constants');
|
||||
const Intents = require('../../util/Intents');
|
||||
|
||||
const STATUS_KEYS = Object.keys(Status);
|
||||
@ -81,6 +81,13 @@ class WebSocketShard extends EventEmitter {
|
||||
*/
|
||||
this.lastHeartbeatAcked = true;
|
||||
|
||||
/**
|
||||
* Used to prevent calling {@link WebSocketShard#event:close} twice while closing or terminating the WebSocket.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.closeEmitted = false;
|
||||
|
||||
/**
|
||||
* Contains the rate limit queue and metadata
|
||||
* @name WebSocketShard#ratelimit
|
||||
@ -126,6 +133,14 @@ class WebSocketShard extends EventEmitter {
|
||||
*/
|
||||
Object.defineProperty(this, 'helloTimeout', { value: null, writable: true });
|
||||
|
||||
/**
|
||||
* The WebSocket timeout.
|
||||
* @name WebSocketShard#wsCloseTimeout
|
||||
* @type {?NodeJS.Timeout}
|
||||
* @private
|
||||
*/
|
||||
Object.defineProperty(this, 'wsCloseTimeout', { value: null, writable: true });
|
||||
|
||||
/**
|
||||
* If the manager attached its event handlers on the shard
|
||||
* @name WebSocketShard#eventsAttached
|
||||
@ -250,10 +265,11 @@ class WebSocketShard extends EventEmitter {
|
||||
|
||||
this.status = this.status === Status.DISCONNECTED ? Status.RECONNECTING : Status.CONNECTING;
|
||||
this.setHelloTimeout();
|
||||
|
||||
this.setWsCloseTimeout(-1);
|
||||
this.connectedAt = Date.now();
|
||||
|
||||
const ws = (this.connection = WebSocket.create(gateway, wsQuery));
|
||||
// Adding a handshake timeout to just make sure no zombie connection appears.
|
||||
const ws = (this.connection = WebSocket.create(gateway, wsQuery, { handshakeTimeout: 30_000 }));
|
||||
ws.onopen = this.onOpen.bind(this);
|
||||
ws.onmessage = this.onMessage.bind(this);
|
||||
ws.onerror = this.onError.bind(this);
|
||||
@ -340,21 +356,39 @@ class WebSocketShard extends EventEmitter {
|
||||
* @private
|
||||
*/
|
||||
onClose(event) {
|
||||
this.closeEmitted = true;
|
||||
if (this.sequence !== -1) this.closeSequence = this.sequence;
|
||||
this.sequence = -1;
|
||||
this.setHeartbeatTimer(-1);
|
||||
this.setHelloTimeout(-1);
|
||||
// Clearing the WebSocket close timeout as close was emitted.
|
||||
this.setWsCloseTimeout(-1);
|
||||
// If we still have a connection object, clean up its listeners
|
||||
if (this.connection) {
|
||||
this._cleanupConnection();
|
||||
// Having this after _cleanupConnection to just clean up the connection and not listen to ws.onclose
|
||||
this.destroy({ reset: true, emit: false, log: false });
|
||||
}
|
||||
this.status = Status.DISCONNECTED;
|
||||
this.emitClose(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is responsible to emit close event for this shard.
|
||||
* This method helps the shard reconnect.
|
||||
* @param {CloseEvent} [event] Close event that was received
|
||||
*/
|
||||
emitClose(
|
||||
event = {
|
||||
code: 1011,
|
||||
reason: WSCodes[1011],
|
||||
wasClean: false,
|
||||
},
|
||||
) {
|
||||
this.debug(`[CLOSE]
|
||||
Event Code: ${event.code}
|
||||
Clean : ${event.wasClean}
|
||||
Reason : ${event.reason ?? 'No reason received'}`);
|
||||
|
||||
this.setHeartbeatTimer(-1);
|
||||
this.setHelloTimeout(-1);
|
||||
// If we still have a connection object, clean up its listeners
|
||||
if (this.connection) this._cleanupConnection();
|
||||
|
||||
this.status = Status.DISCONNECTED;
|
||||
|
||||
/**
|
||||
* Emitted when a shard's WebSocket closes.
|
||||
* @private
|
||||
@ -523,6 +557,47 @@ class WebSocketShard extends EventEmitter {
|
||||
}, 20_000).unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the WebSocket Close timeout.
|
||||
* This method is responsible for detecting any zombie connections if the WebSocket fails to close properly.
|
||||
* @param {number} [time] If set to -1, it will clear the timeout
|
||||
* @private
|
||||
*/
|
||||
setWsCloseTimeout(time) {
|
||||
if (this.wsCloseTimeout) {
|
||||
this.debug('[WebSocket] Clearing the close timeout.');
|
||||
clearTimeout(this.wsCloseTimeout);
|
||||
}
|
||||
if (time === -1) {
|
||||
this.wsCloseTimeout = null;
|
||||
return;
|
||||
}
|
||||
this.wsCloseTimeout = setTimeout(() => {
|
||||
this.setWsCloseTimeout(-1);
|
||||
this.debug(`[WebSocket] Close Emitted: ${this.closeEmitted}`);
|
||||
// Check if close event was emitted.
|
||||
if (this.closeEmitted) {
|
||||
this.debug(
|
||||
`[WebSocket] was closed. | WS State: ${
|
||||
CONNECTION_STATE[this.connection?.readyState ?? WebSocket.CLOSED]
|
||||
} | Close Emitted: ${this.closeEmitted}`,
|
||||
);
|
||||
// Setting the variable false to check for zombie connections.
|
||||
this.closeEmitted = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.debug(
|
||||
// eslint-disable-next-line max-len
|
||||
`[WebSocket] did not close properly, assuming a zombie connection.\nEmitting close and reconnecting again.`,
|
||||
);
|
||||
|
||||
this.emitClose();
|
||||
// Setting the variable false to check for zombie connections.
|
||||
this.closeEmitted = false;
|
||||
}, time).unref();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the heartbeat timer for this shard.
|
||||
* @param {number} time If -1, clears the interval, any other number sets an interval
|
||||
@ -564,7 +639,7 @@ class WebSocketShard extends EventEmitter {
|
||||
Connection State: ${this.connection ? CONNECTION_STATE[this.connection.readyState] : 'No Connection??'}`,
|
||||
);
|
||||
|
||||
this.destroy({ closeCode: 4009, reset: true });
|
||||
this.destroy({ reset: true, closeCode: 4009 });
|
||||
return;
|
||||
}
|
||||
|
||||
@ -723,22 +798,30 @@ class WebSocketShard extends EventEmitter {
|
||||
// Step 0: Remove all timers
|
||||
this.setHeartbeatTimer(-1);
|
||||
this.setHelloTimeout(-1);
|
||||
|
||||
this.debug(
|
||||
`[WebSocket] Destroy: Attempting to close the WebSocket. | WS State: ${
|
||||
CONNECTION_STATE[this.connection?.readyState ?? WebSocket.CLOSED]
|
||||
}`,
|
||||
);
|
||||
// Step 1: Close the WebSocket connection, if any, otherwise, emit DESTROYED
|
||||
if (this.connection) {
|
||||
// If the connection is currently opened, we will (hopefully) receive close
|
||||
if (this.connection.readyState === WebSocket.OPEN) {
|
||||
this.connection.close(closeCode);
|
||||
this.debug(`[WebSocket] Close: Tried closing. | WS State: ${CONNECTION_STATE[this.connection.readyState]}`);
|
||||
} else {
|
||||
// Connection is not OPEN
|
||||
this.debug(`WS State: ${CONNECTION_STATE[this.connection.readyState]}`);
|
||||
// Remove listeners from the connection
|
||||
this._cleanupConnection();
|
||||
// Attempt to close the connection just in case
|
||||
try {
|
||||
this.connection.close(closeCode);
|
||||
} catch {
|
||||
// No-op
|
||||
} catch (err) {
|
||||
this.debug(
|
||||
`[WebSocket] Close: Something went wrong while closing the WebSocket: ${
|
||||
err.message || err
|
||||
}. Forcefully terminating the connection | WS State: ${CONNECTION_STATE[this.connection.readyState]}`,
|
||||
);
|
||||
this.connection.terminate();
|
||||
}
|
||||
// Emit the destroyed event if needed
|
||||
if (emit) this._emitDestroyed();
|
||||
@ -748,6 +831,15 @@ class WebSocketShard extends EventEmitter {
|
||||
this._emitDestroyed();
|
||||
}
|
||||
|
||||
if (this.connection?.readyState === WebSocket.CLOSING || this.connection?.readyState === WebSocket.CLOSED) {
|
||||
this.closeEmitted = false;
|
||||
this.debug(
|
||||
`[WebSocket] Adding a WebSocket close timeout to ensure a correct WS reconnect.
|
||||
Timeout: ${this.manager.client.options.closeTimeout}ms`,
|
||||
);
|
||||
this.setWsCloseTimeout(this.manager.client.options.closeTimeout);
|
||||
}
|
||||
|
||||
// Step 2: Null the connection object
|
||||
this.connection = null;
|
||||
|
||||
|
@ -308,7 +308,7 @@ class GuildChannelManager extends CachedManager {
|
||||
channel,
|
||||
position,
|
||||
relative,
|
||||
this.guild._sortedChannels(this),
|
||||
this.guild._sortedChannels(channel),
|
||||
this.client.api.guilds(this.guild.id).channels,
|
||||
reason,
|
||||
);
|
||||
|
@ -89,16 +89,6 @@ class BaseGuildTextChannel extends GuildChannel {
|
||||
return this.edit({ defaultAutoArchiveDuration }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this channel is flagged as NSFW.
|
||||
* @param {boolean} [nsfw=true] Whether the channel should be considered NSFW
|
||||
* @param {string} [reason] Reason for changing the channel's NSFW flag
|
||||
* @returns {Promise<TextChannel>}
|
||||
*/
|
||||
setNSFW(nsfw = true, reason) {
|
||||
return this.edit({ nsfw }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of this channel (only conversion between text and news is supported)
|
||||
* @param {string} type The new channel type
|
||||
@ -109,44 +99,6 @@ class BaseGuildTextChannel extends GuildChannel {
|
||||
return this.edit({ type }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all webhooks for the channel.
|
||||
* @returns {Promise<Collection<Snowflake, Webhook>>}
|
||||
* @example
|
||||
* // Fetch webhooks
|
||||
* channel.fetchWebhooks()
|
||||
* .then(hooks => console.log(`This channel has ${hooks.size} hooks`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
fetchWebhooks() {
|
||||
return this.guild.channels.fetchWebhooks(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options used to create a {@link Webhook} in a {@link TextChannel} or a {@link NewsChannel}.
|
||||
* @typedef {Object} ChannelWebhookCreateOptions
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [avatar] Avatar for the webhook
|
||||
* @property {string} [reason] Reason for creating the webhook
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a webhook for the channel.
|
||||
* @param {string} name The name of the webhook
|
||||
* @param {ChannelWebhookCreateOptions} [options] Options for creating the webhook
|
||||
* @returns {Promise<Webhook>} Returns the created Webhook
|
||||
* @example
|
||||
* // Create a webhook for the current channel
|
||||
* channel.createWebhook('Snek', {
|
||||
* avatar: 'https://i.imgur.com/mI8XcpG.jpg',
|
||||
* reason: 'Needed a cool new Webhook'
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error)
|
||||
*/
|
||||
createWebhook(name, options = {}) {
|
||||
return this.guild.channels.createWebhook(this.id, name, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new topic for the guild channel.
|
||||
* @param {?string} topic The new topic for the guild channel
|
||||
@ -221,6 +173,10 @@ class BaseGuildTextChannel extends GuildChannel {
|
||||
createMessageComponentCollector() {}
|
||||
awaitMessageComponent() {}
|
||||
bulkDelete() {}
|
||||
fetchWebhooks() {}
|
||||
createWebhook() {}
|
||||
setRateLimitPerUser() {}
|
||||
setNSFW() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(BaseGuildTextChannel, true);
|
||||
|
@ -96,6 +96,8 @@ class DMChannel extends Channel {
|
||||
createMessageComponentCollector() {}
|
||||
awaitMessageComponent() {}
|
||||
// Doesn't work on DM channels; bulkDelete() {}
|
||||
// Doesn't work on DM channels; setRateLimitPerUser() {}
|
||||
// Doesn't work on DM channels; setNSFW() {}
|
||||
// Testing feature: Call
|
||||
// URL: https://discord.com/api/v9/channels/DMchannelId/call/ring
|
||||
/**
|
||||
@ -157,6 +159,12 @@ class DMChannel extends Channel {
|
||||
}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(DMChannel, true, ['bulkDelete']);
|
||||
TextBasedChannel.applyToClass(DMChannel, true, [
|
||||
'bulkDelete',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
'setRateLimitPerUser',
|
||||
'setNSFW',
|
||||
]);
|
||||
|
||||
module.exports = DMChannel;
|
||||
|
@ -388,7 +388,7 @@ class Message extends Base {
|
||||
|
||||
/**
|
||||
* The channel that the message was sent in
|
||||
* @type {TextChannel|DMChannel|NewsChannel|ThreadChannel}
|
||||
* @type {TextBasedChannel}
|
||||
* @readonly
|
||||
*/
|
||||
get channel() {
|
||||
|
@ -309,7 +309,7 @@ module.exports = MessagePayload;
|
||||
|
||||
/**
|
||||
* A target for a message.
|
||||
* @typedef {TextChannel|DMChannel|User|GuildMember|Webhook|WebhookClient|Interaction|InteractionWebhook|
|
||||
* @typedef {TextBasedChannel|DMChannel|User|GuildMember|Webhook|WebhookClient|Interaction|InteractionWebhook|
|
||||
* Message|MessageManager} MessageTarget
|
||||
*/
|
||||
|
||||
|
@ -264,6 +264,12 @@ class PartialGroupDMChannel extends Channel {
|
||||
}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(PartialGroupDMChannel, false);
|
||||
TextBasedChannel.applyToClass(PartialGroupDMChannel, true, [
|
||||
'bulkDelete',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
'setRateLimitPerUser',
|
||||
'setNSFW',
|
||||
]);
|
||||
|
||||
module.exports = PartialGroupDMChannel;
|
||||
|
@ -545,8 +545,10 @@ class ThreadChannel extends Channel {
|
||||
createMessageComponentCollector() {}
|
||||
awaitMessageComponent() {}
|
||||
bulkDelete() {}
|
||||
// Doesn't work on Thread channels; setRateLimitPerUser() {}
|
||||
// Doesn't work on Thread channels; setNSFW() {}
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(ThreadChannel, true);
|
||||
TextBasedChannel.applyToClass(ThreadChannel, true, ['setRateLimitPerUser', 'setNSFW']);
|
||||
|
||||
module.exports = ThreadChannel;
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
const process = require('node:process');
|
||||
const BaseGuildVoiceChannel = require('./BaseGuildVoiceChannel');
|
||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const MessageManager = require('../managers/MessageManager');
|
||||
const { VideoQualityModes } = require('../util/Constants');
|
||||
const Permissions = require('../util/Permissions');
|
||||
|
||||
@ -10,8 +12,21 @@ let deprecationEmittedForEditable = false;
|
||||
/**
|
||||
* Represents a guild voice channel on Discord.
|
||||
* @extends {BaseGuildVoiceChannel}
|
||||
* @implements {TextBasedChannel}
|
||||
*/
|
||||
class VoiceChannel extends BaseGuildVoiceChannel {
|
||||
constructor(guild, data, client) {
|
||||
super(guild, data, client, false);
|
||||
|
||||
/**
|
||||
* A manager of the messages sent to this channel
|
||||
* @type {MessageManager}
|
||||
*/
|
||||
this.messages = new MessageManager(this);
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
super._patch(data);
|
||||
|
||||
@ -20,10 +35,30 @@ class VoiceChannel extends BaseGuildVoiceChannel {
|
||||
* The camera video quality mode of the channel.
|
||||
* @type {?VideoQualityMode}
|
||||
*/
|
||||
this.videoQualityMode = VideoQualityModes[data.videoQualityMode];
|
||||
this.videoQualityMode = VideoQualityModes[data.video_quality_mode];
|
||||
} else {
|
||||
this.videoQualityMode ??= null;
|
||||
}
|
||||
|
||||
if ('last_message_id' in data) {
|
||||
/**
|
||||
* The last message id sent in the channel, if one was sent
|
||||
* @type {?Snowflake}
|
||||
*/
|
||||
this.lastMessageId = data.last_message_id;
|
||||
}
|
||||
|
||||
if ('messages' in data) {
|
||||
for (const message of data.messages) this.messages._add(message);
|
||||
}
|
||||
|
||||
if ('rate_limit_per_user' in data) {
|
||||
/**
|
||||
* The rate limit per user (slowmode) for this channel in seconds
|
||||
* @type {number}
|
||||
*/
|
||||
this.rateLimitPerUser = data.rate_limit_per_user;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,6 +147,21 @@ class VoiceChannel extends BaseGuildVoiceChannel {
|
||||
return this.edit({ videoQualityMode }, reason);
|
||||
}
|
||||
|
||||
// These are here only for documentation purposes - they are implemented by TextBasedChannel
|
||||
/* eslint-disable no-empty-function */
|
||||
get lastMessage() {}
|
||||
send() {}
|
||||
sendTyping() {}
|
||||
createMessageCollector() {}
|
||||
awaitMessages() {}
|
||||
createMessageComponentCollector() {}
|
||||
awaitMessageComponent() {}
|
||||
bulkDelete() {}
|
||||
fetchWebhooks() {}
|
||||
createWebhook() {}
|
||||
setRateLimitPerUser() {}
|
||||
setNSFW() {}
|
||||
|
||||
/**
|
||||
* Sets the RTC region of the channel.
|
||||
* @name VoiceChannel#setRTCRegion
|
||||
@ -127,4 +177,6 @@ class VoiceChannel extends BaseGuildVoiceChannel {
|
||||
*/
|
||||
}
|
||||
|
||||
TextBasedChannel.applyToClass(VoiceChannel, true, ['lastPinAt']);
|
||||
|
||||
module.exports = VoiceChannel;
|
||||
|
@ -331,6 +331,64 @@ class TextBasedChannel {
|
||||
throw new TypeError('MESSAGE_BULK_DELETE_TYPE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches all webhooks for the channel.
|
||||
* @returns {Promise<Collection<Snowflake, Webhook>>}
|
||||
* @example
|
||||
* // Fetch webhooks
|
||||
* channel.fetchWebhooks()
|
||||
* .then(hooks => console.log(`This channel has ${hooks.size} hooks`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
fetchWebhooks() {
|
||||
return this.guild.channels.fetchWebhooks(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Options used to create a {@link Webhook} in a guild text-based channel.
|
||||
* @typedef {Object} ChannelWebhookCreateOptions
|
||||
* @property {?(BufferResolvable|Base64Resolvable)} [avatar] Avatar for the webhook
|
||||
* @property {string} [reason] Reason for creating the webhook
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a webhook for the channel.
|
||||
* @param {string} name The name of the webhook
|
||||
* @param {ChannelWebhookCreateOptions} [options] Options for creating the webhook
|
||||
* @returns {Promise<Webhook>} Returns the created Webhook
|
||||
* @example
|
||||
* // Create a webhook for the current channel
|
||||
* channel.createWebhook('Snek', {
|
||||
* avatar: 'https://i.imgur.com/mI8XcpG.jpg',
|
||||
* reason: 'Needed a cool new Webhook'
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error)
|
||||
*/
|
||||
createWebhook(name, options = {}) {
|
||||
return this.guild.channels.createWebhook(this.id, name, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rate limit per user (slowmode) for this channel.
|
||||
* @param {number} rateLimitPerUser The new rate limit in seconds
|
||||
* @param {string} [reason] Reason for changing the channel's rate limit
|
||||
* @returns {Promise<this>}
|
||||
*/
|
||||
setRateLimitPerUser(rateLimitPerUser, reason) {
|
||||
return this.edit({ rateLimitPerUser }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this channel is flagged as NSFW.
|
||||
* @param {boolean} [nsfw=true] Whether the channel should be considered NSFW
|
||||
* @param {string} [reason] Reason for changing the channel's NSFW flag
|
||||
* @returns {Promise<this>}
|
||||
*/
|
||||
setNSFW(nsfw = true, reason) {
|
||||
return this.edit({ nsfw }, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Slash to this channel
|
||||
* @param {Snowflake} botId Bot Id
|
||||
@ -385,6 +443,10 @@ class TextBasedChannel {
|
||||
'awaitMessages',
|
||||
'createMessageComponentCollector',
|
||||
'awaitMessageComponent',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
'setRateLimitPerUser',
|
||||
'setNSFW',
|
||||
);
|
||||
}
|
||||
for (const prop of props) {
|
||||
|
@ -87,6 +87,7 @@ exports.randomUA = () => listUserAgent[Math.floor(Math.random() * listUserAgent.
|
||||
|
||||
exports.WSCodes = {
|
||||
1000: 'WS_CLOSE_REQUESTED',
|
||||
1011: 'INTERNAL_ERROR',
|
||||
4004: 'TOKEN_INVALID',
|
||||
4010: 'SHARDING_INVALID',
|
||||
4011: 'SHARDING_REQUIRED',
|
||||
@ -677,7 +678,8 @@ exports.ChannelTypes = createEnum([
|
||||
* * TextChannel
|
||||
* * NewsChannel
|
||||
* * ThreadChannel
|
||||
* @typedef {DMChannel|TextChannel|NewsChannel|ThreadChannel} TextBasedChannels
|
||||
* * VoiceChannel
|
||||
* @typedef {DMChannel|TextChannel|NewsChannel|ThreadChannel|VoiceChannel} TextBasedChannels
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -695,6 +697,7 @@ exports.ChannelTypes = createEnum([
|
||||
* * GUILD_NEWS_THREAD
|
||||
* * GUILD_PUBLIC_THREAD
|
||||
* * GUILD_PRIVATE_THREAD
|
||||
* * GUILD_VOICE
|
||||
* @typedef {string} TextBasedChannelTypes
|
||||
*/
|
||||
exports.TextBasedChannelTypes = [
|
||||
@ -704,6 +707,7 @@ exports.TextBasedChannelTypes = [
|
||||
'GUILD_NEWS_THREAD',
|
||||
'GUILD_PUBLIC_THREAD',
|
||||
'GUILD_PRIVATE_THREAD',
|
||||
'GUILD_VOICE',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -1156,6 +1160,7 @@ exports.ApplicationCommandTypes = createEnum([null, 'CHAT_INPUT', 'USER', 'MESSA
|
||||
* * ROLE
|
||||
* * MENTIONABLE
|
||||
* * NUMBER
|
||||
* * ATTACHMENT
|
||||
* @typedef {string} ApplicationCommandOptionType
|
||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#application-command-object-application-command-option-type}
|
||||
*/
|
||||
|
@ -34,6 +34,8 @@ const JSONBig = require('json-bigint');
|
||||
* @property {number|number[]|string} [shards] The shard's id to run, or an array of shard ids. If not specified,
|
||||
* the client will spawn {@link ClientOptions#shardCount} shards. If set to `auto`, it will fetch the
|
||||
* recommended amount of shards from Discord and spawn that amount
|
||||
* @property {number} [closeTimeout=5000] The amount of time in milliseconds to wait for the close frame to be received
|
||||
* from the WebSocket. Don't have this too high/low. Its best to have it between 2_000-6_000 ms.
|
||||
* @property {boolean} [checkUpdate=true] Check for module updates at startup
|
||||
* @property {boolean} [readyStatus=true] Sync state with Discord Client
|
||||
* @property {boolean} [autoCookie=true] Automatically add Cookies to Request on startup
|
||||
@ -138,6 +140,7 @@ class Options extends null {
|
||||
static createDefault() {
|
||||
return {
|
||||
jsonTransformer: object => JSONBig.stringify(object),
|
||||
closeTimeout: 5_000,
|
||||
checkUpdate: true,
|
||||
readyStatus: true,
|
||||
autoCookie: true,
|
||||
|
75
typings/index.d.ts
vendored
75
typings/index.d.ts
vendored
@ -443,26 +443,23 @@ export class BaseGuildEmoji extends Emoji {
|
||||
export class BaseGuildTextChannel extends TextBasedChannelMixin(GuildChannel) {
|
||||
protected constructor(guild: Guild, data?: RawGuildChannelData, client?: Client, immediatePatch?: boolean);
|
||||
public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration;
|
||||
public messages: MessageManager;
|
||||
public rateLimitPerUser: number | null;
|
||||
public nsfw: boolean;
|
||||
public threads: ThreadManager<AllowedThreadTypeForTextChannel | AllowedThreadTypeForNewsChannel>;
|
||||
public topic: string | null;
|
||||
public createInvite(options?: CreateInviteOptions): Promise<Invite>;
|
||||
public createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>;
|
||||
public fetchInvites(cache?: boolean): Promise<Collection<string, Invite>>;
|
||||
public setDefaultAutoArchiveDuration(
|
||||
defaultAutoArchiveDuration: ThreadAutoArchiveDuration | 'MAX',
|
||||
reason?: string,
|
||||
): Promise<this>;
|
||||
public setNSFW(nsfw?: boolean, reason?: string): Promise<this>;
|
||||
public setTopic(topic: string | null, reason?: string): Promise<this>;
|
||||
public setType(type: Pick<typeof ChannelTypes, 'GUILD_TEXT'>, reason?: string): Promise<TextChannel>;
|
||||
public setType(type: Pick<typeof ChannelTypes, 'GUILD_NEWS'>, reason?: string): Promise<NewsChannel>;
|
||||
public fetchWebhooks(): Promise<Collection<Snowflake, Webhook>>;
|
||||
}
|
||||
|
||||
export class BaseGuildVoiceChannel extends GuildChannel {
|
||||
protected constructor(guild: Guild, data?: RawGuildChannelData);
|
||||
public constructor(guild: Guild, data?: RawGuildChannelData);
|
||||
public readonly members: Collection<Snowflake, GuildMember>;
|
||||
public readonly full: boolean;
|
||||
public readonly joinable: boolean;
|
||||
@ -936,9 +933,14 @@ export class DiscordAPIError extends Error {
|
||||
public requestData: HTTPErrorData;
|
||||
}
|
||||
|
||||
export class DMChannel extends TextBasedChannelMixin(Channel, ['bulkDelete']) {
|
||||
export class DMChannel extends TextBasedChannelMixin(Channel, [
|
||||
'bulkDelete',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
'setRateLimitPerUser',
|
||||
'setNSFW',
|
||||
]) {
|
||||
private constructor(client: Client, data?: RawDMChannelData);
|
||||
public messages: MessageManager;
|
||||
public recipient: User;
|
||||
public type: 'DM';
|
||||
public fetch(force?: boolean): Promise<this>;
|
||||
@ -2056,7 +2058,13 @@ export class OAuth2Guild extends BaseGuild {
|
||||
public permissions: Readonly<Permissions>;
|
||||
}
|
||||
|
||||
export class PartialGroupDMChannel extends TextBasedChannelMixin(Channel, ['bulkDelete']) {
|
||||
export class PartialGroupDMChannel extends TextBasedChannelMixin(Channel, [
|
||||
'bulkDelete',
|
||||
'fetchWebhooks',
|
||||
'createWebhook',
|
||||
'setRateLimitPerUser',
|
||||
'setNSFW',
|
||||
]) {
|
||||
private constructor(client: Client, data: RawPartialGroupDMChannelData);
|
||||
public name: string | null;
|
||||
public icon: string | null;
|
||||
@ -2537,7 +2545,6 @@ export class TextChannel extends BaseGuildTextChannel {
|
||||
public rateLimitPerUser: number;
|
||||
public threads: ThreadManager<AllowedThreadTypeForTextChannel>;
|
||||
public type: 'GUILD_TEXT';
|
||||
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<TextChannel>;
|
||||
public sendSlash(botID: Snowflake, commandName: string, args?: Options[]): Promise<undefined>;
|
||||
}
|
||||
|
||||
@ -2563,7 +2570,7 @@ export class TextInputComponent extends BaseMessageComponent {
|
||||
public static resolveStyle(style: TextInputStyleResolvable): TextInputStyle;
|
||||
}
|
||||
|
||||
export class ThreadChannel extends TextBasedChannelMixin(Channel) {
|
||||
export class ThreadChannel extends TextBasedChannelMixin(Channel, ['fetchWebhooks', 'createWebhook', 'setNSFW']) {
|
||||
private constructor(guild: Guild, data?: RawThreadChannelData, client?: Client, fromInteraction?: boolean);
|
||||
public archived: boolean | null;
|
||||
public readonly archivedAt: Date | null;
|
||||
@ -2585,7 +2592,6 @@ export class ThreadChannel extends TextBasedChannelMixin(Channel) {
|
||||
public readonly sendable: boolean;
|
||||
public memberCount: number | null;
|
||||
public messageCount: number | null;
|
||||
public messages: MessageManager;
|
||||
public members: ThreadMemberManager;
|
||||
public name: string;
|
||||
public ownerId: Snowflake | null;
|
||||
@ -2618,7 +2624,6 @@ export class ThreadChannel extends TextBasedChannelMixin(Channel) {
|
||||
public setInvitable(invitable?: boolean, reason?: string): Promise<ThreadChannel>;
|
||||
public setLocked(locked?: boolean, reason?: string): Promise<ThreadChannel>;
|
||||
public setName(name: string, reason?: string): Promise<ThreadChannel>;
|
||||
public setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<ThreadChannel>;
|
||||
}
|
||||
|
||||
export class ThreadMember extends Base {
|
||||
@ -2777,12 +2782,13 @@ export class Formatters extends null {
|
||||
public static userMention: typeof userMention;
|
||||
}
|
||||
|
||||
export class VoiceChannel extends BaseGuildVoiceChannel {
|
||||
export class VoiceChannel extends TextBasedChannelMixin(BaseGuildVoiceChannel, ['lastPinTimestamp', 'lastPinAt']) {
|
||||
public videoQualityMode: VideoQualityMode | null;
|
||||
/** @deprecated Use manageable instead */
|
||||
public readonly editable: boolean;
|
||||
public readonly speakable: boolean;
|
||||
public type: 'GUILD_VOICE';
|
||||
public rateLimitPerUser: number | null;
|
||||
public setBitrate(bitrate: number, reason?: string): Promise<VoiceChannel>;
|
||||
public setUserLimit(userLimit: number, reason?: string): Promise<VoiceChannel>;
|
||||
public setVideoQualityMode(videoQualityMode: VideoQualityMode | number, reason?: string): Promise<VoiceChannel>;
|
||||
@ -2914,6 +2920,8 @@ export class WebSocketShard extends EventEmitter {
|
||||
private eventsAttached: boolean;
|
||||
private expectedGuilds: Set<Snowflake> | null;
|
||||
private readyTimeout: NodeJS.Timeout | null;
|
||||
private closeEmitted: boolean;
|
||||
private wsCloseTimeout: NodeJS.Timeout | null;
|
||||
|
||||
public manager: WebSocketManager;
|
||||
public id: number;
|
||||
@ -2929,6 +2937,7 @@ export class WebSocketShard extends EventEmitter {
|
||||
private onPacket(packet: unknown): void;
|
||||
private checkReady(): void;
|
||||
private setHelloTimeout(time?: number): void;
|
||||
private setWsCloseTimeout(time?: number): void;
|
||||
private setHeartbeatTimer(time: number): void;
|
||||
private sendHeartbeat(): void;
|
||||
private ackHeartbeat(): void;
|
||||
@ -2938,6 +2947,7 @@ export class WebSocketShard extends EventEmitter {
|
||||
private _send(data: unknown): void;
|
||||
private processQueue(): void;
|
||||
private destroy(destroyOptions?: { closeCode?: number; reset?: boolean; emit?: boolean; log?: boolean }): void;
|
||||
private emitClose(event?: CloseEvent): void;
|
||||
private _cleanupConnection(): void;
|
||||
private _emitDestroyed(): void;
|
||||
|
||||
@ -3089,9 +3099,12 @@ export const Constants: {
|
||||
};
|
||||
WSCodes: {
|
||||
1000: 'WS_CLOSE_REQUESTED';
|
||||
1011: 'INTERNAL_ERROR';
|
||||
4004: 'TOKEN_INVALID';
|
||||
4010: 'SHARDING_INVALID';
|
||||
4011: 'SHARDING_REQUIRED';
|
||||
4013: 'INVALID_INTENTS';
|
||||
4014: 'DISALLOWED_INTENTS';
|
||||
};
|
||||
Events: ConstantsEvents;
|
||||
ShardEvents: ConstantsShardEvents;
|
||||
@ -3679,6 +3692,7 @@ export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
|
||||
readonly lastMessage: Message | null;
|
||||
lastPinTimestamp: number | null;
|
||||
readonly lastPinAt: Date | null;
|
||||
messages: MessageManager;
|
||||
awaitMessageComponent<T extends MessageComponentTypeResolvable = 'ACTION_ROW'>(
|
||||
options?: AwaitMessageCollectorOptionsParams<T, true>,
|
||||
): Promise<MappedInteractionTypes[T]>;
|
||||
@ -3691,6 +3705,10 @@ export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
|
||||
options?: MessageChannelCollectorOptionsParams<T, true>,
|
||||
): InteractionCollector<MappedInteractionTypes[T]>;
|
||||
createMessageCollector(options?: MessageCollectorOptions): MessageCollector;
|
||||
createWebhook(name: string, options?: ChannelWebhookCreateOptions): Promise<Webhook>;
|
||||
setRateLimitPerUser(rateLimitPerUser: number, reason?: string): Promise<this>;
|
||||
setNSFW(nsfw?: boolean, reason?: string): Promise<this>;
|
||||
fetchWebhooks(): Promise<Collection<Snowflake, Webhook>>;
|
||||
sendTyping(): Promise<void>;
|
||||
}
|
||||
|
||||
@ -4017,7 +4035,7 @@ export interface ClientEvents extends BaseClientEvents {
|
||||
userUpdate: [oldUser: User | PartialUser, newUser: User];
|
||||
userSettingsUpdate: [setting: RawUserSettingsData];
|
||||
voiceStateUpdate: [oldState: VoiceState, newState: VoiceState];
|
||||
webhookUpdate: [channel: TextChannel | NewsChannel];
|
||||
webhookUpdate: [channel: TextChannel | NewsChannel | VoiceChannel];
|
||||
/** @deprecated Use interactionCreate instead */
|
||||
interaction: [interaction: Interaction];
|
||||
interactionCreate: [interaction: Interaction | { nonce: Snowflake; id: Snowflake }];
|
||||
@ -4192,6 +4210,7 @@ export interface RawUserSettingsData {
|
||||
export interface ClientOptions {
|
||||
shards?: number | number[] | 'auto';
|
||||
shardCount?: number;
|
||||
closeTimeout?: number;
|
||||
makeCache?: CacheFactory;
|
||||
/** @deprecated Pass the value of this property as `lifetime` to `sweepers.messages` instead. */
|
||||
messageCacheLifetime?: number;
|
||||
@ -4596,34 +4615,6 @@ export interface ClientFetchInviteOptions {
|
||||
guildScheduledEventId?: Snowflake;
|
||||
}
|
||||
|
||||
export interface ClientOptions {
|
||||
shards?: number | number[] | 'auto';
|
||||
shardCount?: number;
|
||||
makeCache?: CacheFactory;
|
||||
/** @deprecated Pass the value of this property as `lifetime` to `sweepers.messages` instead. */
|
||||
messageCacheLifetime?: number;
|
||||
/** @deprecated Pass the value of this property as `interval` to `sweepers.messages` instead. */
|
||||
messageSweepInterval?: number;
|
||||
allowedMentions?: MessageMentionOptions;
|
||||
invalidRequestWarningInterval?: number;
|
||||
partials?: PartialTypes[];
|
||||
restWsBridgeTimeout?: number;
|
||||
restTimeOffset?: number;
|
||||
restRequestTimeout?: number;
|
||||
restGlobalRateLimit?: number;
|
||||
restSweepInterval?: number;
|
||||
retryLimit?: number;
|
||||
failIfNotExists?: boolean;
|
||||
userAgentSuffix?: string[];
|
||||
presence?: PresenceData;
|
||||
intents?: BitFieldResolvable<IntentsString, number>;
|
||||
waitGuildTimeout?: number;
|
||||
sweepers?: SweeperOptions;
|
||||
ws?: WebSocketOptions;
|
||||
http?: HTTPOptions;
|
||||
rejectOnRateLimit?: string[] | ((data: RateLimitData) => boolean | Promise<boolean>);
|
||||
}
|
||||
|
||||
export type ClientPresenceStatus = 'online' | 'idle' | 'dnd';
|
||||
|
||||
export interface ClientPresenceStatusData {
|
||||
|
Loading…
Reference in New Issue
Block a user