diff --git a/.eslintrc.json b/.eslintrc.json
index d9c6fa782..f524f5f7d 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,44 +1,65 @@
{
- "extends": "eslint:recommended",
+ "extends": ["eslint:recommended", "plugin:prettier/recommended"],
+ "plugins": ["import"],
"parserOptions": {
- "ecmaVersion": 6
+ "ecmaVersion": 2019
},
"env": {
"es6": true,
"node": true
},
+ "overrides": [{ "files": ["*.browser.js"], "env": { "browser": true } }],
"rules": {
+ "import/order": [
+ "error",
+ {
+ "groups": ["builtin", "external", "internal", "index", "sibling", "parent"],
+ "alphabetize": {
+ "order": "asc"
+ }
+ }
+ ],
+ "prettier/prettier": [
+ 2,
+ {
+ "printWidth": 120,
+ "singleQuote": true,
+ "quoteProps": "as-needed",
+ "trailingComma": "all",
+ "endOfLine": "lf"
+ }
+ ],
+ "strict": ["error", "global"],
"no-await-in-loop": "warn",
"no-compare-neg-zero": "error",
- "no-extra-parens": ["warn", "all", {
- "nestedBinaryExpressions": false
- }],
"no-template-curly-in-string": "error",
"no-unsafe-negation": "error",
- "valid-jsdoc": ["error", {
- "requireReturn": false,
- "requireReturnDescription": false,
- "prefer": {
- "return": "returns",
- "arg": "param"
- },
- "preferType": {
- "String": "string",
- "Number": "number",
- "Boolean": "boolean",
- "Symbol": "symbol",
- "object": "Object",
- "function": "Function",
- "array": "Array",
- "date": "Date",
- "error": "Error",
- "null": "void"
+ "valid-jsdoc": [
+ "error",
+ {
+ "requireReturn": false,
+ "requireReturnDescription": false,
+ "prefer": {
+ "return": "returns",
+ "arg": "param"
+ },
+ "preferType": {
+ "String": "string",
+ "Number": "number",
+ "Boolean": "boolean",
+ "Symbol": "symbol",
+ "object": "Object",
+ "function": "Function",
+ "array": "Array",
+ "date": "Date",
+ "error": "Error",
+ "null": "void"
+ }
}
- }],
+ ],
"accessor-pairs": "warn",
"array-callback-return": "error",
- "complexity": "warn",
"consistent-return": "error",
"curly": ["error", "multi-line", "consistent"],
"dot-location": ["error", "property"],
@@ -96,7 +117,6 @@
"func-names": "error",
"func-name-matching": "error",
"func-style": ["error", "declaration", { "allowArrowFunctions": true }],
- "indent": ["error", 2, { "SwitchCase": 1 }],
"key-spacing": "error",
"keyword-spacing": "error",
"max-depth": "error",
@@ -108,7 +128,6 @@
"no-array-constructor": "error",
"no-inline-comments": "error",
"no-lonely-if": "error",
- "no-mixed-operators": "error",
"no-multiple-empty-lines": ["error", { "max": 2, "maxEOF": 1, "maxBOF": 0 }],
"no-new-object": "error",
"no-spaced-func": "error",
@@ -118,14 +137,20 @@
"nonblock-statement-body-position": "error",
"object-curly-spacing": ["error", "always"],
"operator-assignment": "error",
- "operator-linebreak": ["error", "after"],
"padded-blocks": ["error", "never"],
"quote-props": ["error", "as-needed"],
"quotes": ["error", "single", { "avoidEscape": true, "allowTemplateLiterals": true }],
"semi-spacing": "error",
"semi": "error",
"space-before-blocks": "error",
- "space-before-function-paren": ["error", "never"],
+ "space-before-function-paren": [
+ "error",
+ {
+ "anonymous": "never",
+ "named": "never",
+ "asyncArrow": "always"
+ }
+ ],
"space-in-parens": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index fd6de7242..84ecd2d46 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -7,6 +7,7 @@ pull request. We use ESLint to enforce a consistent coding style, so having that
is a great boon to your development process.
## Setup
+
To get ready to work on the codebase, please do the following:
1. Fork & clone the repository, and make sure you're on the **master** branch
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..6aa35f01b
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,11 @@
+# These are supported funding model platforms
+
+# github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+# patreon: # Replace with a single Patreon username
+# open_collective: # Replace with a single Open Collective username
+# ko_fi: # Replace with a single Ko-fi username
+# tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+# custom: # Replace with a single custom sponsorship URL
+
+github: amishshah
+patreon: discordjs
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
deleted file mode 100644
index b368eeb5c..000000000
--- a/.github/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-**Please describe the problem you are having in as much detail as possible:**
-
-
-**Include a reproducible code sample here, if possible:**
-```js
-
-```
-
-**Further details:**
-
-- discord.js version:
-- node.js version:
-- Operating system:
-- Priority this issue should have – please be realistic and elaborate if possible:
-
-
-- [ ] I have also tested the issue on latest master, commit hash:
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 000000000..caa9425b7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,39 @@
+---
+
+name: Bug report
+about: Report incorrect or unexpected behaviour of discord.js
+title: ''
+labels: 's: unverified, type: bug'
+assignees: ''
+---
+
+
+**Please describe the problem you are having in as much detail as possible:**
+
+**Include a reproducible code sample here, if possible:**
+
+```js
+// Place your code here
+```
+
+**Further details:**
+
+- discord.js version:
+- Node.js version:
+- Operating system:
+- Priority this issue should have – please be realistic and elaborate if possible:
+
+
+
+- [ ] I have also tested the issue on latest master, commit hash:
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..2584693cd
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+ - name: discord.js discord server
+ url: https://discord.gg/bRCvFy9
+ about: Please use this Discord Server to ask questions and get support. We don't typically answer questions here and they will likely be closed and redirected to the Discord server.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 000000000..5510d5f0d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,26 @@
+---
+
+name: Feature request
+about: Request a feature for the core discord.js library
+title: ''
+labels: 'type: enhancement'
+assignees: ''
+---
+
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the ideal solution**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 735a552ec..3de83cd65 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,7 +1,12 @@
**Please describe the changes this PR makes and why it should be merged:**
+**Status**
+
+- [ ] Code changes have been tested against the Discord API, or there are no code changes
+- [ ] I know how to update typings and have done so, or typings don't need updating
+
+**Semantic versioning classification:**
-**Semantic versioning classification:**
- [ ] This PR changes the library's interface (methods or parameters added)
- [ ] This PR includes breaking changes (methods removed or renamed, parameters moved or removed)
- [ ] This PR **only** includes non-code changes, like changes to documentation, README, etc.
diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md
new file mode 100644
index 000000000..032cbc2b9
--- /dev/null
+++ b/.github/SUPPORT.md
@@ -0,0 +1,7 @@
+# Seeking support?
+
+We're sorry, we only use this issue tracker for bugs in the library itself and feature requests for it. We are not able to provide general support or answser questions on the issue tracker.
+
+Should you want to ask such questions, please post in one of our support channels in our Discord server: https://discord.gg/bRCvFy9
+
+Any issues that don't directly involve a bug in the library or a feature request will likely be closed and redirected to the Discord server.
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 000000000..4deae7738
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,47 @@
+name: Deployment
+on:
+ push:
+ branches:
+ - '*'
+ - '!webpack'
+ - '!docs'
+jobs:
+ docs:
+ name: Documentation
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@master
+
+ - name: Install Node v12
+ uses: actions/setup-node@master
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Build and deploy documentation
+ uses: discordjs/action-docs@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ webpack:
+ name: webpack
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@master
+
+ - name: Install Node v12
+ uses: actions/setup-node@master
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Build and deploy webpack
+ uses: discordjs/action-webpack@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/test-cron.yml b/.github/workflows/test-cron.yml
new file mode 100644
index 000000000..10f97e38f
--- /dev/null
+++ b/.github/workflows/test-cron.yml
@@ -0,0 +1,58 @@
+name: Testing Cron
+on:
+ schedule:
+ - cron: '0 */12 * * *'
+jobs:
+ lint:
+ name: ESLint
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v1
+
+ - name: Install Node v12
+ uses: actions/setup-node@v1
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Run ESLint
+ uses: icrawl/action-eslint@v1
+
+ typings:
+ name: TSLint
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v1
+
+ - name: Install Node v12
+ uses: actions/setup-node@v1
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Run TSLint
+ run: npm run lint:typings
+
+ docs:
+ name: Documentation
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v1
+
+ - name: Install Node v12
+ uses: actions/setup-node@v1
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Test documentation
+ run: npm run docs:test
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 000000000..6bdfc2967
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,56 @@
+name: Testing
+on: [push, pull_request]
+jobs:
+ lint:
+ name: ESLint
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ - name: Install Node v12
+ uses: actions/setup-node@v1
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Run ESLint
+ uses: icrawl/action-eslint@v1
+
+ typings:
+ name: TSLint
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ - name: Install Node v12
+ uses: actions/setup-node@v1
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Run TSLint
+ run: npm run lint:typings
+
+ docs:
+ name: Documentation
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+
+ - name: Install Node v12
+ uses: actions/setup-node@v1
+ with:
+ node-version: 12
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Test documentation
+ run: npm run docs:test
diff --git a/.gitignore b/.gitignore
index ffe623718..55693512d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
# Packages
node_modules/
yarn.lock
+package-lock.json
# Log files
logs/
diff --git a/.npmignore b/.npmignore
index a480c140f..9d6674214 100644
--- a/.npmignore
+++ b/.npmignore
@@ -14,8 +14,6 @@ deploy/
.vscode/
docs/
-webpack/
-
# NPM ignore
.eslintrc.json
.gitattributes
diff --git a/.npmrc b/.npmrc
index 579e0e4d9..43c97e719 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1 +1 @@
-package-json=false
+package-lock=false
diff --git a/.tern-project b/.tern-project
index 8f37bf06e..f5ce94809 100644
--- a/.tern-project
+++ b/.tern-project
@@ -1,12 +1,8 @@
{
"ecmaVersion": 7,
"libs": [],
- "loadEagerly": [
- "./src/*.js"
- ],
- "dontLoad": [
- "node_modules/**"
- ],
+ "loadEagerly": ["./src/*.js"],
+ "dontLoad": ["node_modules/**"],
"plugins": {
"es_modules": {},
"node": {},
@@ -15,7 +11,7 @@
"strong": true
},
"webpack": {
- "configPath": "./webpack.config.js",
+ "configPath": "./webpack.config.js"
}
}
}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b14042581..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-language: node_js
-node_js:
- - "6"
- - "8"
- - "10"
- - "12"
-cache:
- directories:
- - node_modules
-install: npm install
-script: bash ./deploy/test.sh
-jobs:
- include:
- - stage: build
- node_js: "6"
- script: bash ./deploy/deploy.sh
-env:
- global:
- - ENCRYPTION_LABEL: "af862fa96d3e"
- - COMMIT_AUTHOR_EMAIL: "amishshah.2k@gmail.com"
-dist: trusty
-sudo: false
diff --git a/LICENSE b/LICENSE
index 90cf11032..9997d13f9 100644
--- a/LICENSE
+++ b/LICENSE
@@ -175,7 +175,7 @@
END OF TERMS AND CONDITIONS
- Copyright 2017 Amish Shah
+ Copyright 2015 - 2020 Amish Shah
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.md b/README.md
index abb18fb65..b6d86a4ab 100644
--- a/README.md
+++ b/README.md
@@ -8,17 +8,31 @@
-
+
+
-
+
+## Table of contents
+
+- [About](#about)
+- [Installation](#installation)
+ - [Audio engines](#audio-engines)
+ - [Optional packages](#optional-packages)
+- [Example Usage](#example-usage)
+- [Links](#links)
+ - [Extensions](#extensions)
+- [Contributing](#contributing)
+- [Help](#help)
+
## About
-discord.js is a powerful [node.js](https://nodejs.org) module that allows you to interact with the
-[Discord API](https://discordapp.com/developers/docs/intro) very easily.
+
+discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to easily interact with the
+[Discord API](https://discordapp.com/developers/docs/intro).
- Object-oriented
- Predictable abstractions
@@ -26,7 +40,8 @@ discord.js is a powerful [node.js](https://nodejs.org) module that allows you to
- 100% coverage of the Discord API
## Installation
-**Node.js 6.0.0 or newer is required.**
+
+**Node.js 12.0.0 or newer is required.**
Ignore any warnings about unmet peer dependencies, as they're all optional.
Without voice support: `npm install discord.js`
@@ -34,18 +49,23 @@ With voice support ([@discordjs/opus](https://www.npmjs.com/package/@discordjs/o
With voice support ([opusscript](https://www.npmjs.com/package/opusscript)): `npm install discord.js opusscript`
### Audio engines
+
The preferred audio engine is @discordjs/opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose @discordjs/opus.
Using opusscript is only recommended for development environments where @discordjs/opus is tough to get working.
For production bots, using @discordjs/opus should be considered a necessity, especially if they're going to be running on multiple servers.
### Optional packages
-- [bufferutil](https://www.npmjs.com/package/bufferutil) to greatly speed up the WebSocket when *not* using uws (`npm install bufferutil`)
-- [erlpack](https://github.com/hammerandchisel/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install hammerandchisel/erlpack`)
+
+- [zlib-sync](https://www.npmjs.com/package/zlib-sync) for WebSocket data compression and inflation (`npm install zlib-sync`)
+- [erlpack](https://github.com/discordapp/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install discordapp/erlpack`)
- One of the following packages can be installed for faster voice packet encryption and decryption:
- - [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
- - [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
+ - [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
+ - [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
+- [bufferutil](https://www.npmjs.com/package/bufferutil) for a much faster WebSocket connection (`npm install bufferutil`)
+- [utf-8-validate](https://www.npmjs.com/package/utf-8-validate) in combination with `bufferutil` for much faster WebSocket processing (`npm install utf-8-validate`)
## Example usage
+
```js
const Discord = require('discord.js');
const client = new Discord.Client();
@@ -64,23 +84,28 @@ client.login('token');
```
## Links
-* [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
-* [Documentation](https://discord.js.org/#/docs)
-* [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide))
-* [Discord.js Discord server](https://discord.gg/bRCvFy9)
-* [Discord API Discord server](https://discord.gg/discord-api)
-* [GitHub](https://github.com/discordjs/discord.js)
-* [NPM](https://www.npmjs.com/package/discord.js)
-* [Related libraries](https://discordapi.com/unofficial/libs.html)
+
+- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
+- [Documentation](https://discord.js.org/#/docs/main/master/general/welcome)
+- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide)) - this is still for stable
+ See also the [Update Guide](https://discordjs.guide/additional-info/changes-in-v12.html), including updated and removed items in the library.
+- [Discord.js Discord server](https://discord.gg/bRCvFy9)
+- [Discord API Discord server](https://discord.gg/discord-api)
+- [GitHub](https://github.com/discordjs/discord.js)
+- [NPM](https://www.npmjs.com/package/discord.js)
+- [Related libraries](https://discordapi.com/unofficial/libs.html)
### Extensions
-* [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
+
+- [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
## Contributing
+
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the
[documentation](https://discord.js.org/#/docs).
See [the contribution guide](https://github.com/discordjs/discord.js/blob/master/.github/CONTRIBUTING.md) if you'd like to submit a PR.
## Help
+
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
nudge in the right direction, please don't hesitate to join our official [Discord.js Server](https://discord.gg/bRCvFy9).
diff --git a/browser.js b/browser.js
deleted file mode 100644
index 9f9341efc..000000000
--- a/browser.js
+++ /dev/null
@@ -1,9 +0,0 @@
-const browser = typeof window !== 'undefined';
-const webpack = !!process.env.__DISCORD_WEBPACK__;
-
-const Discord = require('./');
-
-module.exports = Discord;
-if (browser && webpack) window.Discord = Discord; // eslint-disable-line no-undef
-// eslint-disable-next-line no-console
-else if (!browser) console.warn('Warning: Attempting to use browser version of Discord.js in a non-browser environment!');
diff --git a/deploy/deploy-key.enc b/deploy/deploy-key.enc
deleted file mode 100644
index e03fc36d7..000000000
Binary files a/deploy/deploy-key.enc and /dev/null differ
diff --git a/deploy/deploy.sh b/deploy/deploy.sh
deleted file mode 100644
index d12ee608b..000000000
--- a/deploy/deploy.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/bin/bash
-# Adapted from https://gist.github.com/domenic/ec8b0fc8ab45f39403dd.
-
-set -e
-
-function build {
- npm run docs
- VERSIONED=false npm run webpack
-}
-
-# For revert branches, do nothing
-if [[ "$TRAVIS_BRANCH" == revert-* ]]; then
- echo -e "\e[36m\e[1mBuild triggered for reversion branch \"${TRAVIS_BRANCH}\" - doing nothing."
- exit 0
-fi
-
-# For PRs, do nothing
-if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
- echo -e "\e[36m\e[1mBuild triggered for PR #${TRAVIS_PULL_REQUEST} to branch \"${TRAVIS_BRANCH}\" - doing nothing."
- exit 0
-fi
-
-# Figure out the source of the build
-if [ -n "$TRAVIS_TAG" ]; then
- echo -e "\e[36m\e[1mBuild triggered for tag \"${TRAVIS_TAG}\"."
- SOURCE=$TRAVIS_TAG
- SOURCE_TYPE="tag"
-else
- echo -e "\e[36m\e[1mBuild triggered for branch \"${TRAVIS_BRANCH}\"."
- SOURCE=$TRAVIS_BRANCH
- SOURCE_TYPE="branch"
-fi
-
-# For Node != 6, do nothing
-if [ "$TRAVIS_NODE_VERSION" != "6" ]; then
- echo -e "\e[36m\e[1mBuild triggered with Node v${TRAVIS_NODE_VERSION} - doing nothing."
- exit 0
-fi
-
-build
-
-# Initialise some useful variables
-REPO=`git config remote.origin.url`
-SSH_REPO=${REPO/https:\/\/github.com\//git@github.com:}
-SHA=`git rev-parse --verify HEAD`
-
-# Decrypt and add the ssh key
-ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key"
-ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv"
-ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR}
-ENCRYPTED_IV=${!ENCRYPTED_IV_VAR}
-openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in deploy/deploy-key.enc -out deploy-key -d
-chmod 600 deploy-key
-eval `ssh-agent -s`
-ssh-add deploy-key
-
-# Checkout the repo in the target branch so we can build docs and push to it
-TARGET_BRANCH="docs"
-git clone $REPO out -b $TARGET_BRANCH
-
-# Move the generated JSON file to the newly-checked-out repo, to be committed and pushed
-mv docs/docs.json out/$SOURCE.json
-
-# Commit and push
-cd out
-git add .
-git config user.name "Travis CI"
-git config user.email "$COMMIT_AUTHOR_EMAIL"
-git commit -m "Docs build for ${SOURCE_TYPE} ${SOURCE}: ${SHA}" || true
-git push $SSH_REPO $TARGET_BRANCH
-
-# Clean up...
-cd ..
-rm -rf out
-
-# ...then do the same once more for the webpack
-TARGET_BRANCH="webpack"
-git clone $REPO out -b $TARGET_BRANCH
-
-# Move the generated webpack over
-mv webpack/discord.js out/discord.$SOURCE.js
-mv webpack/discord.min.js out/discord.$SOURCE.min.js
-
-# Commit and push
-cd out
-git add .
-git config user.name "Travis CI"
-git config user.email "$COMMIT_AUTHOR_EMAIL"
-git commit -m "Webpack build for ${SOURCE_TYPE} ${SOURCE}: ${SHA}" || true
-git push $SSH_REPO $TARGET_BRANCH
diff --git a/deploy/test.sh b/deploy/test.sh
deleted file mode 100644
index 9e076a4c4..000000000
--- a/deploy/test.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-
-set -e
-
-function tests {
- npm run lint
- npm run docs:test
- exit 0
-}
-
-# For revert branches, do nothing
-if [[ "$TRAVIS_BRANCH" == revert-* ]]; then
- echo -e "\e[36m\e[1mTest triggered for reversion branch \"${TRAVIS_BRANCH}\" - doing nothing."
- exit 0
-fi
-
-# For PRs
-if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
- echo -e "\e[36m\e[1mTest triggered for PR #${TRAVIS_PULL_REQUEST} to branch \"${TRAVIS_BRANCH}\" - only running tests."
- tests
-fi
-
-# Figure out the source of the test
-if [ -n "$TRAVIS_TAG" ]; then
- echo -e "\e[36m\e[1mTest triggered for tag \"${TRAVIS_TAG}\"."
-else
- echo -e "\e[36m\e[1mTest triggered for branch \"${TRAVIS_BRANCH}\"."
-fi
-
-# For Node != 6
-if [ "$TRAVIS_NODE_VERSION" != "6" ]; then
- echo -e "\e[36m\e[1mTest triggered with Node v${TRAVIS_NODE_VERSION} - only running tests."
- tests
-fi
diff --git a/docs/examples/attachments.md b/docs/examples/attachments.md
index 292f964c9..21295acc6 100644
--- a/docs/examples/attachments.md
+++ b/docs/examples/attachments.md
@@ -6,11 +6,11 @@ In here you'll see a few examples showing how you can send an attachment using d
There are a few ways you can do this, but we'll show you the easiest.
-The following examples use [Attachment](/#/docs/main/stable/class/Attachment).
+The following examples use [MessageAttachment](/#/docs/main/master/class/MessageAttachment).
```js
// Extract the required classes from the discord.js module
-const { Client, Attachment } = require('discord.js');
+const { Client, MessageAttachment } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
@@ -24,13 +24,13 @@ client.on('ready', () => {
});
client.on('message', message => {
- // If the message is '!rip'
- if (message.content === '!rip') {
- // Create the attachment using Attachment
- const attachment = new Attachment('https://i.imgur.com/w3duR07.png');
- // Send the attachment in the message channel
- message.channel.send(attachment);
- }
+ // If the message is '!rip'
+ if (message.content === '!rip') {
+ // Create the attachment using MessageAttachment
+ const attachment = new MessageAttachment('https://i.imgur.com/w3duR07.png');
+ // Send the attachment in the message channel
+ message.channel.send(attachment);
+ }
});
// Log our bot in using the token from https://discordapp.com/developers/applications/me
@@ -41,11 +41,11 @@ And here is the result:

-But what if you want to send an attachment with a message content? Fear not, for it is easy to do that too! We'll recommend reading [the TextChannel's "send" function documentation](/#/docs/main/stable/class/TextChannel?scrollTo=send) to see what other options are available.
+But what if you want to send an attachment with a message content? Fear not, for it is easy to do that too! We'll recommend reading [the TextChannel's "send" function documentation](/#/docs/main/master/class/TextChannel?scrollTo=send) to see what other options are available.
```js
// Extract the required classes from the discord.js module
-const { Client, Attachment } = require('discord.js');
+const { Client, MessageAttachment } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
@@ -59,13 +59,13 @@ client.on('ready', () => {
});
client.on('message', message => {
- // If the message is '!rip'
- if (message.content === '!rip') {
- // Create the attachment using Attachment
- const attachment = new Attachment('https://i.imgur.com/w3duR07.png');
- // Send the attachment in the message channel with a content
- message.channel.send(`${message.author},`, attachment);
- }
+ // If the message is '!rip'
+ if (message.content === '!rip') {
+ // Create the attachment using MessageAttachment
+ const attachment = new MessageAttachment('https://i.imgur.com/w3duR07.png');
+ // Send the attachment in the message channel with a content
+ message.channel.send(`${message.author},`, attachment);
+ }
});
// Log our bot in using the token from https://discordapp.com/developers/applications/me
@@ -78,11 +78,11 @@ And here's the result of this one:
## Sending a local file or buffer
-Sending a local file isn't hard either! We'll be using [Attachment](/#/docs/main/stable/class/Attachment) for these examples too.
+Sending a local file isn't hard either! We'll be using [MessageAttachment](/#/docs/main/master/class/MessageAttachment) for these examples too.
```js
// Extract the required classes from the discord.js module
-const { Client, Attachment } = require('discord.js');
+const { Client, MessageAttachment } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
@@ -96,13 +96,13 @@ client.on('ready', () => {
});
client.on('message', message => {
- // If the message is '!rip'
- if (message.content === '!rip') {
- // Create the attachment using Attachment
- const attachment = new Attachment('./rip.png');
- // Send the attachment in the message channel with a content
- message.channel.send(`${message.author},`, attachment);
- }
+ // If the message is '!rip'
+ if (message.content === '!rip') {
+ // Create the attachment using MessageAttachment
+ const attachment = new MessageAttachment('./rip.png');
+ // Send the attachment in the message channel with a content
+ message.channel.send(`${message.author},`, attachment);
+ }
});
// Log our bot in using the token from https://discordapp.com/developers/applications/me
@@ -120,7 +120,7 @@ You can use any buffer you want, and send it. Just make sure to overwrite the fi
```js
// Extract the required classes from the discord.js module
-const { Client, Attachment } = require('discord.js');
+const { Client, MessageAttachment } = require('discord.js');
// Import the native fs module
const fs = require('fs');
@@ -137,21 +137,21 @@ client.on('ready', () => {
});
client.on('message', message => {
- // If the message is '!memes'
- if (message.content === '!memes') {
- // Get the buffer from the 'memes.txt', assuming that the file exists
- const buffer = fs.readFileSync('./memes.txt');
+ // If the message is '!memes'
+ if (message.content === '!memes') {
+ // Get the buffer from the 'memes.txt', assuming that the file exists
+ const buffer = fs.readFileSync('./memes.txt');
- /**
- * Create the attachment using Attachment,
- * overwritting the default file name to 'memes.txt'
- * Read more about it over at
- * http://discord.js.org/#/docs/main/stable/class/Attachment
- */
- const attachment = new Attachment(buffer, 'memes.txt');
- // Send the attachment in the message channel with a content
- message.channel.send(`${message.author}, here are your memes!`, attachment);
- }
+ /**
+ * Create the attachment using MessageAttachment,
+ * overwritting the default file name to 'memes.txt'
+ * Read more about it over at
+ * http://discord.js.org/#/docs/main/master/class/MessageAttachment
+ */
+ const attachment = new MessageAttachment(buffer, 'memes.txt');
+ // Send the attachment in the message channel with a content
+ message.channel.send(`${message.author}, here are your memes!`, attachment);
+ }
});
// Log our bot in using the token from https://discordapp.com/developers/applications/me
diff --git a/docs/examples/avatars.js b/docs/examples/avatars.js
index c77020efd..57972f57e 100644
--- a/docs/examples/avatars.js
+++ b/docs/examples/avatars.js
@@ -1,3 +1,5 @@
+'use strict';
+
/**
* Send a user a link to their avatar
*/
@@ -21,7 +23,7 @@ client.on('message', message => {
// If the message is "what is my avatar"
if (message.content === 'what is my avatar') {
// Send the user's avatar URL
- message.reply(message.author.avatarURL);
+ message.reply(message.author.displayAvatarURL());
}
});
diff --git a/docs/examples/embed.js b/docs/examples/embed.js
index 66e0fcf10..a03921271 100644
--- a/docs/examples/embed.js
+++ b/docs/examples/embed.js
@@ -1,9 +1,11 @@
+'use strict';
+
/**
* An example of how you can send embeds
*/
// Extract the required classes from the discord.js module
-const { Client, RichEmbed } = require('discord.js');
+const { Client, MessageEmbed } = require('discord.js');
// Create an instance of a Discord client
const client = new Client();
@@ -21,12 +23,12 @@ client.on('message', message => {
if (message.content === 'how to embed') {
// We can create embeds using the MessageEmbed constructor
// Read more about all that you can do with the constructor
- // over at https://discord.js.org/#/docs/main/stable/class/RichEmbed
- const embed = new RichEmbed()
+ // over at https://discord.js.org/#/docs/main/master/class/MessageEmbed
+ const embed = new MessageEmbed()
// Set the title of the field
.setTitle('A slick little embed')
// Set the color of the embed
- .setColor(0xFF0000)
+ .setColor(0xff0000)
// Set the main content of the embed
.setDescription('Hello, this is a slick embed!');
// Send the embed to the same channel as the message
diff --git a/docs/examples/greeting.js b/docs/examples/greeting.js
index 8fc1dfada..f61b1c5fe 100644
--- a/docs/examples/greeting.js
+++ b/docs/examples/greeting.js
@@ -1,3 +1,5 @@
+'use strict';
+
/**
* A bot that welcomes new guild members when they join
*/
@@ -19,7 +21,7 @@ client.on('ready', () => {
// Create an event listener for new guild members
client.on('guildMemberAdd', member => {
// Send the message to a designated channel on a server:
- const channel = member.guild.channels.find(ch => ch.name === 'member-log');
+ const channel = member.guild.channels.cache.find(ch => ch.name === 'member-log');
// Do nothing if the channel wasn't found on this server
if (!channel) return;
// Send the message, mentioning the member
diff --git a/docs/examples/moderation.md b/docs/examples/moderation.md
index 959f404a1..36481a462 100644
--- a/docs/examples/moderation.md
+++ b/docs/examples/moderation.md
@@ -4,7 +4,7 @@ In here, you'll see some basic examples for kicking and banning a member.
## Kicking a member
-Let's say you have a member that you'd like to kick. Here is an example of how you *can* do it.
+Let's say you have a member that you'd like to kick. Here is an example of how you _can_ do it.
```js
// Import the discord.js module
@@ -28,7 +28,7 @@ client.on('message', message => {
// If the message content starts with "!kick"
if (message.content.startsWith('!kick')) {
// Assuming we mention someone in the message, this will return the user
- // Read more about mentions over at https://discord.js.org/#/docs/main/stable/class/MessageMentions
+ // Read more about mentions over at https://discord.js.org/#/docs/main/master/class/MessageMentions
const user = message.mentions.users.first();
// If we have a user mentioned
if (user) {
@@ -41,24 +41,27 @@ client.on('message', message => {
* Make sure you run this on a member, not a user!
* There are big differences between a user and a member
*/
- member.kick('Optional reason that will display in the audit logs').then(() => {
- // We let the message author know we were able to kick the person
- message.reply(`Successfully kicked ${user.tag}`);
- }).catch(err => {
- // An error happened
- // This is generally due to the bot not being able to kick the member,
- // either due to missing permissions or role hierarchy
- message.reply('I was unable to kick the member');
- // Log the error
- console.error(err);
- });
+ member
+ .kick('Optional reason that will display in the audit logs')
+ .then(() => {
+ // We let the message author know we were able to kick the person
+ message.reply(`Successfully kicked ${user.tag}`);
+ })
+ .catch(err => {
+ // An error happened
+ // This is generally due to the bot not being able to kick the member,
+ // either due to missing permissions or role hierarchy
+ message.reply('I was unable to kick the member');
+ // Log the error
+ console.error(err);
+ });
} else {
// The mentioned user isn't in this guild
- message.reply('That user isn\'t in this guild!');
+ message.reply("That user isn't in this guild!");
}
- // Otherwise, if no user was mentioned
+ // Otherwise, if no user was mentioned
} else {
- message.reply('You didn\'t mention the user to kick!');
+ message.reply("You didn't mention the user to kick!");
}
}
});
@@ -97,7 +100,7 @@ client.on('message', message => {
// if the message content starts with "!ban"
if (message.content.startsWith('!ban')) {
// Assuming we mention someone in the message, this will return the user
- // Read more about mentions over at https://discord.js.org/#/docs/main/stable/class/MessageMentions
+ // Read more about mentions over at https://discord.js.org/#/docs/main/master/class/MessageMentions
const user = message.mentions.users.first();
// If we have a user mentioned
if (user) {
@@ -110,28 +113,31 @@ client.on('message', message => {
* Make sure you run this on a member, not a user!
* There are big differences between a user and a member
* Read more about what ban options there are over at
- * https://discord.js.org/#/docs/main/stable/class/GuildMember?scrollTo=ban
+ * https://discord.js.org/#/docs/main/master/class/GuildMember?scrollTo=ban
*/
- member.ban({
- reason: 'They were bad!',
- }).then(() => {
- // We let the message author know we were able to ban the person
- message.reply(`Successfully banned ${user.tag}`);
- }).catch(err => {
- // An error happened
- // This is generally due to the bot not being able to ban the member,
- // either due to missing permissions or role hierarchy
- message.reply('I was unable to ban the member');
- // Log the error
- console.error(err);
- });
+ member
+ .ban({
+ reason: 'They were bad!',
+ })
+ .then(() => {
+ // We let the message author know we were able to ban the person
+ message.reply(`Successfully banned ${user.tag}`);
+ })
+ .catch(err => {
+ // An error happened
+ // This is generally due to the bot not being able to ban the member,
+ // either due to missing permissions or role hierarchy
+ message.reply('I was unable to ban the member');
+ // Log the error
+ console.error(err);
+ });
} else {
// The mentioned user isn't in this guild
- message.reply('That user isn\'t in this guild!');
+ message.reply("That user isn't in this guild!");
}
} else {
- // Otherwise, if no user was mentioned
- message.reply('You didn\'t mention the user to ban!');
+ // Otherwise, if no user was mentioned
+ message.reply("You didn't mention the user to ban!");
}
}
});
diff --git a/docs/examples/ping.js b/docs/examples/ping.js
index 1b14332de..55888e888 100644
--- a/docs/examples/ping.js
+++ b/docs/examples/ping.js
@@ -1,3 +1,5 @@
+'use strict';
+
/**
* A ping pong bot, whenever you send "ping", it replies "pong".
*/
diff --git a/docs/examples/webhook.js b/docs/examples/webhook.js
index 77f58c448..451ac58b3 100644
--- a/docs/examples/webhook.js
+++ b/docs/examples/webhook.js
@@ -1,3 +1,5 @@
+'use strict';
+
/**
* Send a message using a webhook
*/
diff --git a/docs/general/faq.md b/docs/general/faq.md
index 69864395b..e265f81c1 100644
--- a/docs/general/faq.md
+++ b/docs/general/faq.md
@@ -1,23 +1,30 @@
# Frequently Asked Questions
-These are just questions that get asked frequently, that usually have a common resolution.
-If you have issues not listed here, please ask in the [official Discord server](https://discord.gg/bRCvFy9).
-Always make sure to read the documentation.
+
+These questions are some of the most frequently asked.
## No matter what, I get `SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode`‽
-Update to Node.js 6.0.0 or newer.
+
+Update to Node.js 12.0.0 or newer.
## How do I get voice working?
+
- Install FFMPEG.
- Install either the `@discordjs/opus` package or the `opusscript` package.
@discordjs/opus is greatly preferred, due to it having significantly better performance.
## How do I install FFMPEG?
+
- **npm:** `npm install ffmpeg-binaries`
- **Ubuntu 16.04:** `sudo apt install ffmpeg`
- **Ubuntu 14.04:** `sudo apt-get install libav-tools`
- **Windows:** `npm install ffmpeg-binaries` or see the [FFMPEG section of AoDude's guide](https://github.com/bdistin/OhGodMusicBot/blob/master/README.md#download-ffmpeg).
## How do I set up @discordjs/opus?
+
- **Ubuntu:** Simply run `npm install @discordjs/opus`, and it's done. Congrats!
- **Windows:** Run `npm install --global --production windows-build-tools` in an admin command prompt or PowerShell.
Then, running `npm install @discordjs/opus` in your bot's directory should successfully build it. Woo!
+
+Other questions can be found at the [official Discord.js guide](https://discordjs.guide/popular-topics/common-questions.html)
+If you have issues not listed here or on the guide, feel free to ask in the [official Discord.js server](https://discord.gg/bRCvFy9).
+Always make sure to read the [documentation](https://discord.js.org/#/docs/main/stable/general/welcome).
diff --git a/docs/general/updating.md b/docs/general/updating.md
index 70008c1e8..85fee04e8 100644
--- a/docs/general/updating.md
+++ b/docs/general/updating.md
@@ -1,92 +1,93 @@
-# Version 11.6.0
-v11.6.0 backports new features from the in-development v12, and fixes bugs in the v11.5.x releases.
-See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.6.0) for a full list of changes, including information about deprecations.
+# Version 12.0.0
-# Version 11.5.0
-v11.5.0 backports new features from the in-development v12, and fixes bugs in the v11.4.x releases.
-See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.5.0) for a full list of changes, including information about deprecations.
-
-# Version 11.4.0
-v11.4.0 backports many new features such as Rich Presence and bugfixes from v11.3.0.
-See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.4.0) for a full list of changes, including information about deprecations.
-
-# Version 11.3.0
-v11.3.0 backports many new features and bug fixes from the in-development v12.
-See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.3.0) for a full list of changes, including information about deprecations.
-
-# Version 11.2.0
-v11.2.0 fixes a lot of bugs we encountered along the 11.1.0 release, as well as support for new features such as Message Attachments and UserGuildSettings.
-See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.2.0) for a full list of changes, including information about deprecations.
+v12.0.0 contains many new and improved features, optimisations, and bug fixes.
+See [the changelog](https://github.com/discordjs/discord.js/releases/tag/12.0.0) for a full list of changes.
+You can also visit [the guide](https://discordjs.guide/additional-info/changes-in-v12.html) for help with updating your v11 code to v12.
# Version 11.1.0
+
v11.1.0 features improved voice and gateway stability, as well as support for new features such as audit logs and searching for messages.
See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.1.0) for a full list of changes, including
information about deprecations.
# Version 11
+
Version 11 contains loads of new and improved features, optimisations, and bug fixes.
See [the changelog](https://github.com/discordjs/discord.js/releases/tag/11.0.0) for a full list of changes.
## Significant additions
-* Message Reactions and Embeds (rich text)
-* Support for uws and erlpack for better performance
-* OAuthApplication support
-* Web distributions
+
+- Message Reactions and Embeds (rich text)
+- Support for uws and erlpack for better performance
+- OAuthApplication support
+- Web distributions
## Breaking changes
+
### Client.login() no longer supports logging in with email + password
+
Logging in with an email and password has always been heavily discouraged since the advent of proper token support, but in v11 we have made the decision to completely remove the functionality, since Hammer & Chisel have [officially stated](https://github.com/hammerandchisel/discord-api-docs/issues/69#issuecomment-223886862) it simply shouldn't be done.
User accounts can still log in with tokens just like bot accounts. To obtain the token for a user account, you can log in to Discord with that account, and use Ctrl + Shift + I to open the developer tools. In the console tab, evaluating `localStorage.token` will give you the token for that account.
### ClientUser.setEmail()/setPassword() now require the current password, as well as setUsername() on user accounts
+
Since you can no longer log in with email and password, you must provide the current account password to the `setEmail()`, `setPassword()`, and `setUsername()` methods for user accounts (self-bots).
### Removed TextBasedChannel.sendTTSMessage()
+
This method was deemed to be an entirely pointless shortcut that virtually nobody even used.
The same results can be achieved by passing options to `send()` or `sendMessage()`.
Example:
+
```js
channel.send('Hi there', { tts: true });
```
### Using Collection.find()/exists() with IDs will throw an error
+
This is simply to help prevent a common mistake that is made frequently.
To find something or check its existence using an ID, you should use `.get()` and `.has()` which are part of the [ES6 Map class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map), which Collection is an extension of.
# Version 10
+
Version 10's non-BC changes focus on cleaning up some inconsistencies that exist in previous versions.
Upgrading from v9 should be quick and painless.
## Client options
+
All client options have been converted to camelCase rather than snake_case, and `max_message_cache` was renamed to `messageCacheMaxSize`.
v9 code example:
+
```js
const client = new Discord.Client({
disable_everyone: true,
max_message_cache: 500,
message_cache_lifetime: 120,
- message_sweep_interval: 60
+ message_sweep_interval: 60,
});
```
v10 code example:
+
```js
const client = new Discord.Client({
disableEveryone: true,
messageCacheMaxSize: 500,
messageCacheLifetime: 120,
- messageSweepInterval: 60
+ messageSweepInterval: 60,
});
```
## Presences
+
Presences have been completely restructured.
Previous versions of discord.js assumed that users had the same presence amongst all guilds - with the introduction of sharding, however, this is no longer the case.
v9 discord.js code may look something like this:
+
```js
User.status; // the status of the user
User.game; // the game that the user is playing
@@ -101,6 +102,7 @@ Additionally, the introduction of the Presence class keeps all of the presence d
A user may have an entirely different presence between two different guilds.**
v10 code:
+
```js
MemberOrUser.presence.status; // the status of the member or user
MemberOrUser.presence.game; // the game that the member or user is playing
@@ -110,41 +112,46 @@ ClientUser.setPresence(fullPresence); // status and game combined
```
## Voice
+
Voice has been rewritten internally, but in a backwards-compatible manner.
There is only one breaking change here; the `disconnected` event was renamed to `disconnect`.
Several more events have been made available to a VoiceConnection, so see the documentation.
## Events
+
Many events have been renamed or had their arguments change.
### Client events
-| Version 9 | Version 10 |
-|------------------------------------------------------|-----------------------------------------------|
-| guildMemberAdd(guild, member) | guildMemberAdd(member) |
-| guildMemberAvailable(guild, member) | guildMemberAvailable(member) |
-| guildMemberRemove(guild, member) | guildMemberRemove(member) |
-| guildMembersChunk(guild, members) | guildMembersChunk(members) |
-| guildMemberUpdate(guild, oldMember, newMember) | guildMemberUpdate(oldMember, newMember) |
-| guildRoleCreate(guild, role) | roleCreate(role) |
-| guildRoleDelete(guild, role) | roleDelete(role) |
-| guildRoleUpdate(guild, oldRole, newRole) | roleUpdate(oldRole, newRole) |
+
+| Version 9 | Version 10 |
+| ---------------------------------------------- | --------------------------------------- |
+| guildMemberAdd(guild, member) | guildMemberAdd(member) |
+| guildMemberAvailable(guild, member) | guildMemberAvailable(member) |
+| guildMemberRemove(guild, member) | guildMemberRemove(member) |
+| guildMembersChunk(guild, members) | guildMembersChunk(members) |
+| guildMemberUpdate(guild, oldMember, newMember) | guildMemberUpdate(oldMember, newMember) |
+| guildRoleCreate(guild, role) | roleCreate(role) |
+| guildRoleDelete(guild, role) | roleDelete(role) |
+| guildRoleUpdate(guild, oldRole, newRole) | roleUpdate(oldRole, newRole) |
The guild parameter that has been dropped from the guild-related events can still be derived using `member.guild` or `role.guild`.
### VoiceConnection events
+
| Version 9 | Version 10 |
-|--------------|------------|
+| ------------ | ---------- |
| disconnected | disconnect |
## Dates and timestamps
+
All dates/timestamps on the structures have been refactored to have a consistent naming scheme and availability.
-All of them are named similarly to this:
-**Date:** `Message.createdAt`
-**Timestamp:** `Message.createdTimestamp`
+All of them are named similarly to this:
+**Date:** `Message.createdAt`
+**Timestamp:** `Message.createdTimestamp`
See the docs for each structure to see which date/timestamps are available on them.
-
# Version 9
+
The version 9 (v9) rewrite takes a much more object-oriented approach than previous versions,
which allows your code to be much more readable and manageable.
It's been rebuilt from the ground up and should be much more stable, fixing caching issues that affected
@@ -157,19 +164,22 @@ into other more relevant classes where they belong.
Because of this, you will need to convert most of your calls over to the new methods.
Here are a few examples of methods that have changed:
-* `Client.sendMessage(channel, message)` ==> `TextChannel.sendMessage(message)`
- * `Client.sendMessage(user, message)` ==> `User.sendMessage(message)`
-* `Client.updateMessage(message, "New content")` ==> `Message.edit("New Content")`
-* `Client.getChannelLogs(channel, limit)` ==> `TextChannel.fetchMessages({options})`
-* `Server.detailsOfUser(User)` ==> `Server.members.get(User).properties` (retrieving a member gives a GuildMember object)
-* `Client.joinVoiceChannel(voicechannel)` => `VoiceChannel.join()`
+
+- `Client.sendMessage(channel, message)` ==> `TextChannel.sendMessage(message)`
+ - `Client.sendMessage(user, message)` ==> `User.sendMessage(message)`
+- `Client.updateMessage(message, "New content")` ==> `Message.edit("New Content")`
+- `Client.getChannelLogs(channel, limit)` ==> `TextChannel.fetchMessages({options})`
+- `Server.detailsOfUser(User)` ==> `Server.members.get(User).properties` (retrieving a member gives a GuildMember object)
+- `Client.joinVoiceChannel(voicechannel)` => `VoiceChannel.join()`
A couple more important details:
-* `Client.loginWithToken("token")` ==> `client.login("token")`
-* `Client.servers.length` ==> `client.guilds.size` (all instances of `server` are now `guild`)
+
+- `Client.loginWithToken("token")` ==> `client.login("token")`
+- `Client.servers.length` ==> `client.guilds.size` (all instances of `server` are now `guild`)
## No more callbacks!
-Version 9 eschews callbacks in favour of Promises. This means all code relying on callbacks must be changed.
+
+Version 9 eschews callbacks in favour of Promises. This means all code relying on callbacks must be changed.
For example, the following code:
```js
@@ -179,7 +189,7 @@ client.getChannelLogs(channel, 100, function(messages) {
```
```js
-channel.fetchMessages({limit: 100}).then(messages => {
+channel.fetchMessages({ limit: 100 }).then(messages => {
console.log(`${messages.size} messages found`);
});
```
diff --git a/docs/general/welcome.md b/docs/general/welcome.md
index 3ffb66026..a83717e62 100644
--- a/docs/general/welcome.md
+++ b/docs/general/welcome.md
@@ -1,7 +1,7 @@
-
+
@@ -18,15 +18,13 @@
# Welcome!
-Welcome to the discord.js v11.6 documentation.
-The v11.6 release contains bugfixes from v11.5 and backports features from the in-development v12.
-v12 is still very much a work-in-progress, as we're aiming to make it the best it can possibly be before releasing.
-If you are fond of living life on the bleeding-edge, check out the master branch.
+Welcome to the discord.js v12 documentation.
## About
-discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to interact with the
-[Discord API](https://discordapp.com/developers/docs/intro) very easily.
+
+discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to easily interact with the
+[Discord API](https://discordapp.com/developers/docs/intro).
- Object-oriented
- Predictable abstractions
@@ -34,7 +32,8 @@ discord.js is a powerful [Node.js](https://nodejs.org) module that allows you to
- 100% coverage of the Discord API
## Installation
-**Node.js 6.0.0 or newer is required.**
+
+**Node.js 12.0.0 or newer is required.**
Ignore any warnings about unmet peer dependencies, as they're all optional.
Without voice support: `npm install discord.js`
@@ -42,19 +41,23 @@ With voice support ([@discordjs/opus](https://www.npmjs.com/package/@discordjs/o
With voice support ([opusscript](https://www.npmjs.com/package/opusscript)): `npm install discord.js opusscript`
### Audio engines
+
The preferred audio engine is @discordjs/opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose @discordjs/opus.
Using opusscript is only recommended for development environments where @discordjs/opus is tough to get working.
For production bots, using @discordjs/opus should be considered a necessity, especially if they're going to be running on multiple servers.
### Optional packages
-- [bufferutil](https://www.npmjs.com/package/bufferutil) to greatly speed up the WebSocket when *not* using uws (`npm install bufferutil`)
-- [erlpack](https://github.com/hammerandchisel/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install hammerandchisel/erlpack`)
+
+- [zlib-sync](https://www.npmjs.com/package/zlib-sync) for WebSocket data compression and inflation (`npm install zlib-sync`)
+- [erlpack](https://github.com/discordapp/erlpack) for significantly faster WebSocket data (de)serialisation (`npm install discordapp/erlpack`)
- One of the following packages can be installed for faster voice packet encryption and decryption:
- - [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
- - [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
-- [uws](https://www.npmjs.com/package/@discordjs/uws) for a much faster WebSocket connection (`npm install @discordjs/uws`)
+ - [sodium](https://www.npmjs.com/package/sodium) (`npm install sodium`)
+ - [libsodium.js](https://www.npmjs.com/package/libsodium-wrappers) (`npm install libsodium-wrappers`)
+- [bufferutil](https://www.npmjs.com/package/bufferutil) for a much faster WebSocket connection (`npm install bufferutil`)
+- [utf-8-validate](https://www.npmjs.com/package/utf-8-validate) in combination with `bufferutil` for much faster WebSocket processing (`npm install utf-8-validate`)
## Example usage
+
```js
const Discord = require('discord.js');
const client = new Discord.Client();
@@ -73,23 +76,28 @@ client.login('token');
```
## Links
-* [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
-* [Documentation](https://discord.js.org/#/docs)
-* [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide))
-* [Discord.js Discord server](https://discord.gg/bRCvFy9)
-* [Discord API Discord server](https://discord.gg/discord-api)
-* [GitHub](https://github.com/discordjs/discord.js)
-* [NPM](https://www.npmjs.com/package/discord.js)
-* [Related libraries](https://discordapi.com/unofficial/libs.html)
+
+- [Website](https://discord.js.org/) ([source](https://github.com/discordjs/website))
+- [Documentation](https://discord.js.org/#/docs/main/master/general/welcome)
+- [Guide](https://discordjs.guide/) ([source](https://github.com/discordjs/guide)) - this is still for stable
+ See also the WIP [Update Guide](https://discordjs.guide/additional-info/changes-in-v12.html) also including updated and removed items in the library.
+- [Discord.js Discord server](https://discord.gg/bRCvFy9)
+- [Discord API Discord server](https://discord.gg/discord-api)
+- [GitHub](https://github.com/discordjs/discord.js)
+- [NPM](https://www.npmjs.com/package/discord.js)
+- [Related libraries](https://discordapi.com/unofficial/libs.html)
### Extensions
-* [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
+
+- [RPC](https://www.npmjs.com/package/discord-rpc) ([source](https://github.com/discordjs/RPC))
## Contributing
+
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the
[documentation](https://discord.js.org/#/docs).
See [the contribution guide](https://github.com/discordjs/discord.js/blob/master/.github/CONTRIBUTING.md) if you'd like to submit a PR.
## Help
+
If you don't understand something in the documentation, you are experiencing problems, or you just need a gentle
nudge in the right direction, please don't hesitate to join our official [Discord.js Server](https://discord.gg/bRCvFy9).
diff --git a/docs/index.yml b/docs/index.yml
index 7c5b3b280..175780574 100644
--- a/docs/index.yml
+++ b/docs/index.yml
@@ -12,6 +12,8 @@
path: voice.md
- name: Web builds
path: web.md
+ - name: Partials
+ path: partials.md
- name: Examples
files:
- name: Ping
diff --git a/docs/topics/partials.md b/docs/topics/partials.md
new file mode 100644
index 000000000..4b58f4356
--- /dev/null
+++ b/docs/topics/partials.md
@@ -0,0 +1,65 @@
+# Partials
+
+Partials allow you to receive events that contain uncached instances, providing structures that contain very minimal
+data. For example, if you were to receive a `messageDelete` event with an uncached message, normally Discord.js would
+discard the event. With partials, you're able to receive the event, with a Message object that contains just an ID.
+
+## Opting in
+
+Partials are opt-in, and you can enable them in the Client options by specifying [PartialTypes](/#/docs/main/master/typedef/PartialType):
+
+```js
+// Accept partial messages, DM channels, and reactions when emitting events
+new Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] });
+```
+
+## Usage & warnings
+
+The only guaranteed data a partial structure can store is its ID. All other properties/methods should be
+considered invalid/defunct while accessing a partial structure.
+
+After opting-in with the above, you begin to allow partial messages and channels in your caches, so it's important
+to check whether they're safe to access whenever you encounter them, whether it be in events or through normal cache
+usage.
+
+All instance of structures that you opted-in for will have a `partial` property. As you'd expect, this value is `true`
+when the instance is partial. Partial structures are only guaranteed to contain an ID, any other properties and methods
+no longer carry their normal type guarantees.
+
+This means you have to take time to consider possible parts of your program that might need checks put in place to
+prevent accessing partial data:
+
+```js
+client.on('messageDelete', message => {
+ console.log(`${message.id} was deleted!`);
+ // Partial messages do not contain any content so skip them
+ if (!message.partial) {
+ console.log(`It had content: "${message.content}"`);
+ }
+});
+
+// You can also try to upgrade partials to full instances:
+client.on('messageReactionAdd', async (reaction, user) => {
+ // If a message gains a reaction and it is uncached, fetch and cache the message
+ // You should account for any errors while fetching, it could return API errors if the resource is missing
+ if (reaction.message.partial) await reaction.message.fetch();
+ // Now the message has been cached and is fully available:
+ console.log(`${reaction.message.author}'s message "${reaction.message.content}" gained a reaction!`);
+ // Fetches and caches the reaction itself, updating resources that were possibly defunct.
+ if (reaction.partial) await reaction.fetch();
+ // Now the reaction is fully available and the properties will be reflected accurately:
+ console.log(`${reaction.count} user(s) have given the same reaction to this message!`);
+});
+```
+
+If a message is deleted and both the message and channel are uncached, you must enable both 'MESSAGE' and
+'CHANNEL' in the client options to receive the messageDelete event.
+
+## Why?
+
+This allows developers to listen to events that contain uncached data, which is useful if you're running a moderation
+bot or any bot that relies on still receiving updates to resources you don't have cached -- message reactions are a
+good example.
+
+Currently, the only type of channel that can be uncached is a DM channel, there is no reason why guild channels should
+not be cached.
diff --git a/docs/topics/voice.md b/docs/topics/voice.md
index 7e9faf056..cb20dd5cc 100644
--- a/docs/topics/voice.md
+++ b/docs/topics/voice.md
@@ -1,20 +1,23 @@
# Introduction to Voice
+
Voice in discord.js can be used for many things, such as music bots, recording or relaying audio.
In discord.js, you can use voice by connecting to a `VoiceChannel` to obtain a `VoiceConnection`, where you can start streaming and receiving audio.
To get started, make sure you have:
-* FFmpeg - `npm install ffmpeg-binaries`
-* an opus encoder, choose one from below:
- * `npm install opusscript`
- * `npm install @discordjs/opus`
-* a good network connection
+
+- FFmpeg - `npm install ffmpeg-static`
+- an opus encoder, choose one from below:
+ - `npm install @discordjs/opus` (better performance)
+ - `npm install opusscript`
+- a good network connection
The preferred opus engine is @discordjs/opus, as it performs significantly better than opusscript. When both are available, discord.js will automatically choose @discordjs/opus.
Using opusscript is only recommended for development environments where @discordjs/opus is tough to get working.
For production bots, using @discordjs/opus should be considered a necessity, especially if they're going to be running on multiple servers.
## Joining a voice channel
+
The example below reacts to a message and joins the sender's voice channel, catching any errors. This is important
as it allows us to obtain a `VoiceConnection` that we can start to stream audio with.
@@ -24,19 +27,15 @@ const client = new Discord.Client();
client.login('token here');
-client.on('message', message => {
+client.on('message', async message => {
// Voice only works in guilds, if the message does not come from a guild,
// we ignore it
if (!message.guild) return;
if (message.content === '/join') {
// Only try to join the sender's voice channel if they are in one themselves
- if (message.member.voiceChannel) {
- message.member.voiceChannel.join()
- .then(connection => { // Connection is an instance of VoiceConnection
- message.reply('I have successfully connected to the channel!');
- })
- .catch(console.log);
+ if (message.member.voice.channel) {
+ const connection = await message.member.voice.channel.join();
} else {
message.reply('You need to join a voice channel first!');
}
@@ -45,69 +44,97 @@ client.on('message', message => {
```
## Streaming to a Voice Channel
+
In the previous example, we looked at how to join a voice channel in order to obtain a `VoiceConnection`. Now that we
-have obtained a voice connection, we can start streaming audio to it. The following example shows how to stream an mp3
-file:
+have obtained a voice connection, we can start streaming audio to it.
+
+### Introduction to playing on voice connections
+
+The most basic example of playing audio over a connection would be playing a local file:
-**Playing a file:**
```js
-// To play a file, we need to give an absolute path to it
-const dispatcher = connection.playFile('C:/Users/Discord/Desktop/myfile.mp3');
+const dispatcher = connection.play('/home/discord/audio.mp3');
```
-Your file doesn't have to be just an mp3; ffmpeg can convert videos and audios of many formats.
-
-The `dispatcher` variable is an instance of a `StreamDispatcher`, which manages streaming a specific resource to a voice
-channel. We can do many things with the dispatcher, such as finding out when the stream ends or changing the volume:
+The `dispatcher` in this case is a `StreamDispatcher` - here you can control the volume and playback of the stream:
```js
-dispatcher.on('end', () => {
- // The song has finished
+dispatcher.pause();
+dispatcher.resume();
+
+dispatcher.setVolume(0.5); // half the volume
+
+dispatcher.on('finish', () => {
+ console.log('Finished playing!');
});
-dispatcher.on('error', e => {
- // Catch any errors that may arise
- console.log(e);
+dispatcher.destroy(); // end the stream
+```
+
+We can also pass in options when we first play the stream:
+
+```js
+const dispatcher = connection.play('/home/discord/audio.mp3', {
+ volume: 0.5,
+});
+```
+
+### What can I play?
+
+Discord.js allows you to play a lot of things:
+
+```js
+// ReadableStreams, in this example YouTube audio
+const ytdl = require('ytdl-core');
+connection.play(ytdl('https://www.youtube.com/watch?v=ZlAU_w7-Xp8', { filter: 'audioonly' }));
+
+// Files on the internet
+connection.play('http://www.sample-videos.com/audio/mp3/wave.mp3');
+
+// Local files
+connection.play('/home/discord/audio.mp3');
+```
+
+New to v12 is the ability to play OggOpus and WebmOpus streams with much better performance by skipping out Ffmpeg. Note this comes at the cost of no longer having volume control over the stream:
+
+```js
+connection.play(fs.createReadStream('./media.webm'), {
+ type: 'webm/opus',
});
-dispatcher.setVolume(0.5); // Set the volume to 50%
-dispatcher.setVolume(1); // Set the volume back to 100%
-
-console.log(dispatcher.time); // The time in milliseconds that the stream dispatcher has been playing for
-
-dispatcher.pause(); // Pause the stream
-dispatcher.resume(); // Carry on playing
-
-dispatcher.end(); // End the dispatcher, emits 'end' event
+connection.play(fs.createReadStream('./media.ogg'), {
+ type: 'ogg/opus',
+});
```
-If you have an existing [ReadableStream](https://nodejs.org/api/stream.html#stream_readable_streams),
-this can also be used:
+Make sure to consult the documentation for a full list of what you can play - there's too much to cover here!
-**Playing a ReadableStream:**
-```js
-connection.playStream(myReadableStream);
+## Voice Broadcasts
-// If you don't want to use absolute paths, you can use
-// fs.createReadStream to circumvent it
-
-const fs = require('fs');
-const stream = fs.createReadStream('./test.mp3');
-connection.playStream(stream);
-```
-
-It's important to note that creating a readable stream to a file is less efficient than simply using `connection.playFile()`.
-
-**Playing anything else:**
-
-For anything else, such as a URL to a file, you can use `connection.playArbitraryInput()`. You should consult the [ffmpeg protocol documentation](https://ffmpeg.org/ffmpeg-protocols.html) to see what you can use this for.
+A voice broadcast is very useful for "radio" bots, that play the same audio across multiple channels. It means audio is only transcoded once, and is much better on performance.
```js
-// Play an mp3 from a URL
-connection.playArbitraryInput('http://mysite.com/sound.mp3');
+const broadcast = client.voice.createBroadcast();
+
+broadcast.on('subscribe', dispatcher => {
+ console.log('New broadcast subscriber!');
+});
+
+broadcast.on('unsubscribe', dispatcher => {
+ console.log('Channel unsubscribed from broadcast :(');
+});
```
-Again, playing a file from a URL like this is more performant than creating a ReadableStream to the file.
+`broadcast` is an instance of `VoiceBroadcast`, which has the same `play` method you are used to with regular VoiceConnections:
-## Advanced Topics
-soon:tm:
+```js
+const dispatcher = broadcast.play('./audio.mp3');
+
+connection.play(broadcast);
+```
+
+It's important to note that the `dispatcher` stored above is a `BroadcastDispatcher` - it controls all the dispatcher subscribed to the broadcast, e.g. setting the volume of this dispatcher affects the volume of all subscribers.
+
+## Voice Receive
+
+coming soon™
diff --git a/docs/topics/web.md b/docs/topics/web.md
index 611834e8b..87a853279 100644
--- a/docs/topics/web.md
+++ b/docs/topics/web.md
@@ -1,13 +1,32 @@
# Web builds
+
In addition to your usual Node applications, discord.js has special distributions available that are capable of running in web browsers.
This is useful for client-side web apps that need to interact with the Discord API.
[Webpack 3](https://webpack.js.org/) is used to build these.
-## Usage
+## Restrictions
+
+- Any voice-related functionality is unavailable, as there is currently no audio encoding/decoding capabilities without external native libraries,
+ which web browsers do not support.
+- The ShardingManager cannot be used, since it relies on being able to spawn child processes for shards.
+- None of the native optional packages are usable.
+
+### Require Library
+
+If you are making your own webpack project, you can require `discord.js/browser` wherever you need to use discord.js, like so:
+
+```js
+const Discord = require('discord.js/browser');
+// do something with Discord like you normally would
+```
+
+### Webpack File
+
You can obtain your desired version of discord.js' web build from the [webpack branch](https://github.com/discordjs/discord.js/tree/webpack) of the GitHub repository.
There is a file for each branch and version of the library, and the ones ending in `.min.js` are minified to substantially reduce the size of the source code.
Include the file on the page just as you would any other JS library, like so:
+
```html
```
@@ -15,15 +34,10 @@ Include the file on the page just as you would any other JS library, like so:
Rather than importing discord.js with `require('discord.js')`, the entire `Discord` object is available as a global (on the `window`) object.
The usage of the API isn't any different from using it in Node.js.
-## Restrictions
-- Any voice-related functionality is unavailable, as there is currently no audio encoding/decoding capabilities without external native libraries,
- which web browsers do not support.
-- The ShardingManager cannot be used, since it relies on being able to spawn child processes for shards.
-- None of the optional packages are usable, since they're native libraries.
+#### Example
-## Example
```html
-
+
-
+
-