mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-10 08:33:30 +01:00
Merge remote-tracking branch 'refs/remotes/origin/master' into indev
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -35,3 +35,4 @@ build/Release
|
||||
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
|
||||
node_modules
|
||||
test/auth.json
|
||||
examples/auth.json
|
||||
|
||||
5
.npmignore
Normal file
5
.npmignore
Normal file
@@ -0,0 +1,5 @@
|
||||
.vscode/
|
||||
docs/
|
||||
examples/
|
||||
web-dist/
|
||||
.travis.yml
|
||||
@@ -1,3 +1,2 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
}
|
||||
{ "editor.wrappingColumn": 0 }
|
||||
2
.settings/tasks.json → .vscode/tasks.json
vendored
2
.settings/tasks.json → .vscode/tasks.json
vendored
@@ -19,7 +19,7 @@
|
||||
"isBuildCommand": true,
|
||||
"isWatching": true,
|
||||
"args": [
|
||||
"src", "--out-dir", "lib", "-w"
|
||||
"src", "--out-dir", "lib", "-w", "--loose=all"
|
||||
]
|
||||
}
|
||||
]
|
||||
84
README.md
84
README.md
@@ -1,13 +1,17 @@
|
||||
# discord.js
|
||||
<p align="center">
|
||||
<a href="https://hydrabolt.github.io/discord.js">
|
||||
<img alt="discord.js" src="http://hydrabolt.github.io/discord.js/res/logo.png" width="546">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
[](https://travis-ci.org/hydrabolt/discord.js)
|
||||
[](https://travis-ci.org/hydrabolt/discord.js) [](http://discordjs.readthedocs.org/en/latest/?badge=latest)
|
||||
|
||||
|
||||
discord.js is a node module used as a way of interfacing with
|
||||
[Discord](https://discordapp.com/). It is a very useful module for creating
|
||||
bots.
|
||||
|
||||
**Updating to 3.1.1 is essential as it has new changes to be compatible with Discord's API,
|
||||
and to make sure your application still works an update is a good idea.**
|
||||
**The examples in the repo are in ES6, either update your node or compile them down to babel yourself if you want to use them!**
|
||||
|
||||
### Installation
|
||||
`npm install --save discord.js`
|
||||
@@ -31,6 +35,33 @@ mybot.login("email", "password");
|
||||
```
|
||||
---
|
||||
|
||||
### What's new in 3.9.0?
|
||||
|
||||
Amongst some fixes to web distribution creation, you can now opt for easier string formatting! However, it does modify String globally so you'll have to run:
|
||||
|
||||
```js
|
||||
Discord.patchStrings()
|
||||
```
|
||||
|
||||
After you have run this, you can do:
|
||||
```
|
||||
|
||||
"message".bold.underline.italic
|
||||
// generates "*__**message**__*"
|
||||
|
||||
```
|
||||
|
||||
A full list of modifiers (all chainable):
|
||||
|
||||
* bold `**`
|
||||
* italic `*`
|
||||
* underline `__`
|
||||
* strike `~`
|
||||
* code ` ` `
|
||||
* codeblock` ``` `
|
||||
|
||||
---
|
||||
|
||||
### Related Projects
|
||||
|
||||
Here is a list of other Discord APIs:
|
||||
@@ -42,7 +73,7 @@ Here is a list of other Discord APIs:
|
||||
|
||||
[DiscordSharp](https://github.com/Luigifan/DiscordSharp)
|
||||
#### NodeJS
|
||||
[node-discord](https://github.com/izy521/node-discord) (similar to discord.js but lower level)
|
||||
[discord.io](https://github.com/izy521/node-discord) (similar to discord.js but lower level)
|
||||
|
||||
#### PHP
|
||||
[DiscordPHP](https://github.com/teamreflex/DiscordPHP)
|
||||
@@ -55,42 +86,8 @@ Here is a list of other Discord APIs:
|
||||
|
||||
---
|
||||
|
||||
### Changes in 3.1.4
|
||||
|
||||
No, not π. But instead, pseduo-synchronous messaging was added! This means that
|
||||
you can tell your Client to make a queue of "actions" per channel, and it will
|
||||
work through them one by one. This is a really useful tool if you need to send
|
||||
messages in a specific order without callback hell.
|
||||
|
||||
It also allows you to store responses - such as created messages - in the returned
|
||||
promise - named action. Example:
|
||||
|
||||
```js
|
||||
var mybot = new Discord.Client({
|
||||
queue : true //enable queueing, disabled by default
|
||||
});
|
||||
|
||||
mybot.on("message", function(msg){
|
||||
|
||||
mybot.sendMessage(msg.channel, "this is message 1");
|
||||
var action = mybot.sendMessage(msg.channel, "this is message 2");
|
||||
mybot.sendMessage(msg.channel, "this is message 3").then(rmv);
|
||||
|
||||
function rmv(){
|
||||
if(!action.error){
|
||||
mybot.deleteMessage(action.message);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
This is still in development, and will see many more enhancements in future.
|
||||
|
||||
---
|
||||
|
||||
### Links
|
||||
**[Documentation](https://github.com/discord-js/discord.js/wiki/Documentation)**
|
||||
**[Documentation](http://discordjs.readthedocs.org/en/latest/)**
|
||||
|
||||
**[GitHub](https://github.com/discord-js/discord.js)**
|
||||
|
||||
@@ -104,5 +101,8 @@ This is still in development, and will see many more enhancements in future.
|
||||
|
||||
### Contact
|
||||
|
||||
If you would like to contact me, you can create an issue on the GitHub repo
|
||||
or send a DM to **hydrabolt** in [Discord API](https://discord.gg/0SBTUU1wZTYd2XyW).
|
||||
If you have an issue or want to know if a feature exists, [read the documentation](http://discordjs.readthedocs.org/en/latest/) before contacting me about any issues! If it's badly/wrongly implemented, let me know!
|
||||
|
||||
|
||||
If you would like to contact me, you can create an issue on the GitHub repo, e-mail me via the one available on my NPM profile.
|
||||
Or you could just send a DM to **hydrabolt** in [**Discord API**](https://discord.gg/0SBTUU1wZTYd2XyW).
|
||||
|
||||
192
docs/Makefile
Normal file
192
docs/Makefile
Normal file
@@ -0,0 +1,192 @@
|
||||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
BUILDDIR = _build
|
||||
|
||||
# User-friendly check for sphinx-build
|
||||
ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
|
||||
$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
|
||||
endif
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " applehelp to make an Apple Help Book"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " xml to make Docutils-native XML files"
|
||||
@echo " pseudoxml to make pseudoxml-XML files for display purposes"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
@echo " coverage to run coverage check of the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/discordjs.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/discordjs.qhc"
|
||||
|
||||
applehelp:
|
||||
$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
|
||||
@echo
|
||||
@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
|
||||
@echo "N.B. You won't be able to view it unless you put it in" \
|
||||
"~/Library/Documentation/Help or install it in your application" \
|
||||
"bundle."
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/discordjs"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/discordjs"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
latexpdfja:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through platex and dvipdfmx..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
|
||||
coverage:
|
||||
$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
|
||||
@echo "Testing of coverage in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/coverage/python.txt."
|
||||
|
||||
xml:
|
||||
$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
|
||||
@echo
|
||||
@echo "Build finished. The XML files are in $(BUILDDIR)/xml."
|
||||
|
||||
pseudoxml:
|
||||
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
|
||||
@echo
|
||||
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
|
||||
284
docs/conf.py
Normal file
284
docs/conf.py
Normal file
@@ -0,0 +1,284 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# discord.js documentation build configuration file, created by
|
||||
# sphinx-quickstart on Fri Sep 25 17:25:49 2015.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
# source_suffix = ['.rst', '.md']
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'discord.js'
|
||||
copyright = u'2015, hydrabolt'
|
||||
author = u'hydrabolt'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '3.6'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '3.6.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all
|
||||
# documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = False
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# Add any extra paths that contain custom files (such as robots.txt or
|
||||
# .htaccess) here, relative to this directory. These files are copied
|
||||
# directly to the root of the documentation.
|
||||
#html_extra_path = []
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Language to be used for generating the HTML full-text search index.
|
||||
# Sphinx supports the following languages:
|
||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
||||
#html_search_language = 'en'
|
||||
|
||||
# A dictionary with options for the search language support, empty by default.
|
||||
# Now only 'ja' uses this config value
|
||||
#html_search_options = {'type': 'default'}
|
||||
|
||||
# The name of a javascript file (relative to the configuration directory) that
|
||||
# implements a search results scorer. If empty, the default will be used.
|
||||
#html_search_scorer = 'scorer.js'
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'discordjsdoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
|
||||
# Latex figure (float) alignment
|
||||
#'figure_align': 'htbp',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'discordjs.tex', u'discord.js Documentation',
|
||||
u'hydrabolt', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output ---------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'discordjs', u'discord.js Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'discordjs', u'discord.js Documentation',
|
||||
author, 'discordjs', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
132
docs/create_simple_bot.rst
Normal file
132
docs/create_simple_bot.rst
Normal file
@@ -0,0 +1,132 @@
|
||||
Creating a Simple Bot
|
||||
=====================
|
||||
|
||||
This page will walk you through writing a simple bot and will introduce you to some of the most important functions and objects you will encounter in the API.
|
||||
|
||||
Setting up a Project
|
||||
--------------------
|
||||
|
||||
Before you start creating your bot, you need to create a directory, for example *discordbot*.
|
||||
|
||||
After you've done that, open up the directory and have a look at how to `install the module`_. After you've installed the module, you can progress to the next step
|
||||
|
||||
Creating the Bot
|
||||
----------------
|
||||
|
||||
Now we can begin writing the bot. This bot will just server the user their avatar but at a higher resolution - assuming they have one.
|
||||
|
||||
Firstly, create a file named ``bot.js`` in the directory you made earlier. Open it up, and type the following lines of code:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
var Discord = require("discord.js");
|
||||
var bot = new Discord.Client();
|
||||
|
||||
This code firstly imports the discord.js module, which contains classes to help you create clients for Discord. The second line creates a new Discord Client, which we can manipulate later. Now, we want the client to be alerted when there is a new message and do something, so we can type this:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.on("message", function(message){
|
||||
|
||||
} )
|
||||
|
||||
This will simply get our client to listen out for new messages, but not yet do anything. Let's have a look at this:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.on("message", function(message){
|
||||
|
||||
if( message.content === "avatar me!" ){
|
||||
|
||||
}
|
||||
|
||||
} )
|
||||
|
||||
This code will now get our client to execute anything inside the if statement as long as the message sent was "avatar me!" We can now get it to see if the user has an avatar:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.on("message", function(message){
|
||||
|
||||
if( message.content === "avatar me!" ){
|
||||
|
||||
var usersAvatar = message.sender.avatarURL;
|
||||
|
||||
if(usersAvatar){
|
||||
// user has an avatar
|
||||
}else{
|
||||
// user doesn't have an avatar
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} )
|
||||
|
||||
This code will now see if the user has an avatar and then do something based on that, let's finalise it:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.on("message", function(message){
|
||||
|
||||
if( message.content === "avatar me!" ){
|
||||
|
||||
var usersAvatar = message.sender.avatarURL;
|
||||
|
||||
if(usersAvatar){
|
||||
// user has an avatar
|
||||
|
||||
bot.reply(message, "your avatar can be found at " + usersAvatar);
|
||||
|
||||
}else{
|
||||
// user doesn't have an avatar
|
||||
|
||||
bot.reply(message, "you don't have an avatar!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} )
|
||||
|
||||
Let's have a look at the function we used here; *bot.reply*. This function takes 2 necessary parameters, a message object to reply to and a message to send. The first parameter we already have, and it is the message we have received. The second parameter is what we want to send.
|
||||
|
||||
Now that we've finished the listener event, we need to log the client in:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.login("your discord email", "your discord password");
|
||||
|
||||
And that's it! Run the code with ``node bot.js`` and wait a few seconds, and then try sending *avatar me!* to any of the channels that the user you provided has details to.
|
||||
|
||||
Final Product
|
||||
-------------
|
||||
.. code-block:: js
|
||||
|
||||
var Discord = require("discord.js");
|
||||
var bot = new Discord.Client();
|
||||
|
||||
bot.on("message", function(message){
|
||||
|
||||
if( message.content === "avatar me!" ){
|
||||
|
||||
var usersAvatar = message.sender.avatarURL;
|
||||
|
||||
if(usersAvatar){
|
||||
// user has an avatar
|
||||
|
||||
bot.reply(message, "your avatar can be found at " + usersAvatar);
|
||||
|
||||
}else{
|
||||
// user doesn't have an avatar
|
||||
|
||||
bot.reply(message, "you don't have an avatar!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
bot.login("your discord email", "your discord password");
|
||||
|
||||
.. note:: This page is still a WIP, check back later for more documentation on it.
|
||||
|
||||
.. _install the module : http://discordjs.readthedocs.org/en/latest/get_started.html#installation
|
||||
75
docs/docs_channel.rst
Normal file
75
docs/docs_channel.rst
Normal file
@@ -0,0 +1,75 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
Channel Documentation
|
||||
=====================
|
||||
|
||||
The Channel Class is used to represent data about a Channel.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
client
|
||||
~~~~~~
|
||||
|
||||
The Discord Client_ that cached the channel
|
||||
|
||||
server
|
||||
~~~~~~
|
||||
|
||||
The Server_ that the channel belongs to
|
||||
|
||||
name
|
||||
~~~~
|
||||
|
||||
The channel's name, as a `String`.
|
||||
|
||||
id
|
||||
~~
|
||||
|
||||
The channel's id, as a `String`.
|
||||
|
||||
type
|
||||
~~~~
|
||||
|
||||
The type of the channel as a `String`, either ``text`` or ``voice``.
|
||||
|
||||
topic
|
||||
~~~~~
|
||||
|
||||
A `String` that is the topic of the channel, if the channel doesn't have a topic this will be `null`.
|
||||
|
||||
messages
|
||||
~~~~~~~~
|
||||
|
||||
An `Array` of Message_ objects received from the channel. There are up to a 1000 messages here, and the older messages will be deleted if necessary.
|
||||
|
||||
members
|
||||
~~~~~~~
|
||||
|
||||
**Aliases** : `users`
|
||||
|
||||
The members in the channel's server, an `Array` of User_ objects.
|
||||
|
||||
-----
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. note:: When concatenated with a String, the object will become the channel's embed code, e.g. ``"this is " + channel`` would be ``this is <#channelid>``
|
||||
|
||||
getMessage(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a Message_ from the channel that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
channel.getMessage("id", 1243987349) // returns a Message where message.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
|
||||
equals(object)
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Returns a `Boolean` depending on whether the Channel's ID (``channel.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare channels. **NEVER** do ``channel1 == channel2``.
|
||||
610
docs/docs_client.rst
Normal file
610
docs/docs_client.rst
Normal file
@@ -0,0 +1,610 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
Client Documentation
|
||||
====================
|
||||
|
||||
This page contains documentation on the `Discord.Client` class. This should be used when you want to start creating things with the API.
|
||||
|
||||
It might be beneficial to use CTRL+F to search for what you're looking for, or use the navigation provided by readthedocs on the left.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
options
|
||||
~~~~~~~
|
||||
An `Object` containing a configuration for the Client. Currently can only be configured like so:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
{
|
||||
queue : false // whether messages should be sent one after the other or
|
||||
// just send straight away.
|
||||
}
|
||||
|
||||
token
|
||||
~~~~~
|
||||
A `String` that is the token received after logging in. It is used to authorise the Client when joining WebSockets or making HTTP requests. Example token:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
ODAzTOc4MTA2BjQ2MjY4ODg.COmrCA.fEtD_Tc0JU6iZJU_11coEWBOQHE
|
||||
|
||||
state
|
||||
~~~~~
|
||||
An `Integer` representing what state of connection the Client is in.
|
||||
|
||||
- **0** is idle, meaning the Client has been created but no login attempts have been made.
|
||||
- **1** is logging in, meaning the Client is in the process of logging in.
|
||||
- **2** is logged in, meaning the Client is logged in but not necessarily ready.
|
||||
- **3** is ready, meaning the Client is ready to begin listening.
|
||||
- **4** is disconnected, meaning the Client was disconnected due to any reason.
|
||||
|
||||
See also ready_.
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
if( bot.state === 3 ) // ready to go
|
||||
|
||||
user
|
||||
~~~~
|
||||
A `User`_ object representing the account of the signed in client. This will only be available when the client is in the ready state (3).
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.user.username; // username of the account logged in
|
||||
|
||||
email
|
||||
~~~~~
|
||||
A `String` that is the email used to sign the client in.
|
||||
|
||||
password
|
||||
~~~~~~~~
|
||||
A `String` that is the password used to sign the client in.
|
||||
|
||||
readyTime
|
||||
~~~~~~~~~
|
||||
A `Number` representing the unix timestamp from when the client was ready. `Null` if not yet ready.
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.readyTime; // 1443378242464
|
||||
|
||||
uptime
|
||||
~~~~~~
|
||||
A `Number` representing how many milliseconds have passed since the client was ready. `Null` if not yet ready.
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
if( bot.uptime > 5000 ) // true if the client has been up for more than 5 seconds
|
||||
|
||||
ready
|
||||
~~~~~
|
||||
A `Boolean` that is true if the client is ready. A shortcut to checking if ``bot.state === 3``.
|
||||
|
||||
servers
|
||||
~~~~~~~
|
||||
An `Array` of Server_ objects that the client has access to.
|
||||
|
||||
channels
|
||||
~~~~~~~~
|
||||
An `Array` of Channel_ objects that the client has access to.
|
||||
|
||||
users
|
||||
~~~~~
|
||||
An `Array` of User_ objects that the client has access to.
|
||||
|
||||
PMChannels
|
||||
~~~~~~~~~~
|
||||
An `Array` of PMChannel_ objects the client has access to.
|
||||
|
||||
messages
|
||||
~~~~~~~~
|
||||
An `Array` of Message_ objects the client has received over its uptime.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. note :: Any functions used here that take callbacks as an optional parameter can also be used as Promises_. Promises take the exact same parameters for each use case, except errors are moved to catch statements instead of then. For example, you can do:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.login(email, password).then(success).catch(err);
|
||||
|
||||
function success(token){
|
||||
|
||||
}
|
||||
|
||||
function err(error){
|
||||
|
||||
}
|
||||
|
||||
// OR use callbacks:
|
||||
|
||||
bot.login(email, password, function(error, token){
|
||||
|
||||
});
|
||||
|
||||
-----
|
||||
|
||||
login(email, password, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Logs the client in to set it up. Use this after registering your event listeners to ensure they are called.
|
||||
|
||||
- **email** - A `String` which is the email you want to sign in with.
|
||||
- **password** - A `String` which is the password you want to sign in with.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **token** - if successful, it is the received authorisation token.
|
||||
|
||||
logout(`callback`)
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Logs the client out if it is logged in. If successful, ``bot.state == 4``.
|
||||
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
|
||||
createServer(name, region, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Creates a server with the specified name or region. See valid regions below:
|
||||
|
||||
- **name** - A `String` that will be the name of your server.
|
||||
- **region** - A `String` that is a valid Discord region. Currently **us-west**, **us-east**, **singapore**, **london**, **sydney** or **amsterdam**. Providing an invalid region will result in an error. To find the latest available regions, check the `official API here`_.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **server** - A Server_ that represents the created Server.
|
||||
|
||||
joinServer(invite, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Accepts a given invite to join a server. The server is automatically cached ASAP.
|
||||
|
||||
- **invite** - An `Invite Resolvable`_ which is the invite that should be accepted.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **server** - A Server_ that represents the joined Server.
|
||||
|
||||
leaveServer(server, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Leaves the given server.
|
||||
|
||||
- **server** - A `Server Resolvable`_ that represents the server you want to leave.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
|
||||
createInvite(channel, options, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Creates an invite for the given channel and returns an Invite_.
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ that is the channel you want to create an invite for.
|
||||
- **options** - An `object` containing configurable options for the invite. See below for possible configurations.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **invite** - An Invite_ object that contains the details about the created invite.
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
// default configuration of the options variable:
|
||||
|
||||
options = {
|
||||
max_age : 0, //A number signifying the expiry time for the invite. 0 means infinite.
|
||||
max_uses : 0, //A number signifying the amount of uses of the invite. 0 means infinite.
|
||||
temporary : false, //boolean - whether users who use it are kicked unless promoted within 24h.
|
||||
xkcd : false //boolean - whether the invite's URL should be human-readable
|
||||
}
|
||||
|
||||
createChannel(server, channelName, channelType, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Creates a channel in the given server.
|
||||
|
||||
- **server** - A `Server Resolvable`_ that will be the server the channel is created in.
|
||||
- **channelName** - A `String` that is the name of the channel.
|
||||
- **channelType** - A `String` that is the type of the channel, either **voice** or **text**.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **channel** - An Channel_ object that represents the created channel.
|
||||
|
||||
deleteChannel(channel, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Deletes the specified channel.
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ that will be the channel to delete.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
|
||||
getChannelLogs(channel, `amount`, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets previous messages from the specified channel.
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ to take logs from.
|
||||
- **amount** - A `Number` that defaults to **500**. This is the amount of messages to try and get.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **logs** - An `Array` of Message_ objects that represent the previous messages.
|
||||
|
||||
.. warning:: If the logs contain messages from a user who is no longer in the server, the user object *MAY* be malformed.
|
||||
|
||||
sendMessage(channel, message, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sends a message to the specified channel.
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ to send the message to.
|
||||
- **message** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **message** - A Message_ representing the sent message.
|
||||
|
||||
sendFile(channel, file, `fileName`, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sends a file to the specified channel. Note that **fileName is necessary in certain cases** for when a file other than an image is sent. For example, if you send a file containing JS code, fileName should be something like ``myCode.js``.
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ to send the file to.
|
||||
- **file** - The file to send, either a `Buffer` or `String` - if a String, it should be a relative (`./`) or absolute path to a file.
|
||||
- **fileName** - A `String` containing the file's name and extension, used by Discord (I didn't make this please don't shoot me :s) Examples include `picture.png`, `text.txt`, `wowanamazingscript.js`
|
||||
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **message** - A Message_ representing the sent file.
|
||||
|
||||
updateMessage(message, content, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Updates/edits a message with new content.
|
||||
|
||||
- **message** - A Message_ that should be updated.
|
||||
- **content** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **message** - A Message_ representing the updated message.
|
||||
|
||||
reply(message, yourMessage, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Alias for sendMessage, but prepends a mention to whoever sent the specified mention. Useful shortcut for directing a message at a user.
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
// example usage:
|
||||
|
||||
the user 'bob' sent a message
|
||||
|
||||
bot.reply(message, "hello");
|
||||
// will send the message '@bob, hello' to the channel the message that bob sent was in.
|
||||
|
||||
- **message** - A Message_ that should be replied to.
|
||||
- **yourMessage** - A `String` or an Array of strings. If an Array, the array will be joined with a new line as a delimiter and this will be the message to be sent.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
- **message** - A Message_ representing the sent message.
|
||||
|
||||
setUsername(newName, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sets the username of the logged in client.
|
||||
|
||||
- **newName** - The new name of the client, a `String`.
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
|
||||
startTyping(channel, *stopTime*)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Makes the client appear to be typing in the specified channel.
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ that should be the channel to start typing in
|
||||
- **stopTime** - A `Number` in ms which should make the client stop typing after. Allow 5 seconds.
|
||||
|
||||
stopTyping(channel)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Makes the client stop typing in a specified channel.
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ that should be the channel to stop typing in.
|
||||
|
||||
setStatusOnline()
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Aliases**: ``setStatusActive()`` and ``setStatusHere()``
|
||||
|
||||
Sets the client's status to online; green.
|
||||
|
||||
setStatusIdle()
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Aliases**: ``setStatusAway()``
|
||||
|
||||
Sets the client's status to idle; orange.
|
||||
|
||||
setTopic(channel, topic, `callback`)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sets the topic of the specified channel
|
||||
|
||||
- **channel** - A `Channel Resolvable`_ that is the channel you want to change the topic of
|
||||
- **topic** - A `String` that is the topic you want
|
||||
- **callback** - A `function` that can take the following parameters:
|
||||
|
||||
- **error** - An error if one occurred, otherwise it is null.
|
||||
|
||||
getUser(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a User_ that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.getUser("id", 1243987349) // returns a user where user.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
|
||||
getServer(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a Server_ that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.getServer("id", 1243987349) // returns a server where server.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
|
||||
|
||||
getChannel(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a Channel_ that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.getChannel("id", 1243987349) // returns a Channel where channel.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
|
||||
|
||||
getPMChannel(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a PMChannel_ that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.getPMChannel("id", 1243987349) // returns a PMChannel where pmchannel.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
|
||||
setPlayingGame(id)
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**Aliases** : `playGame`, `playingGame`
|
||||
|
||||
Sets the client as playing the specified game name/id.
|
||||
|
||||
- **id** - Either a `Number` or a `String`. If it's a Number, it's assumed that you are using a `Discord Game ID`_ and know what you want. If you supply a `String`, it will assume you are entering a game name and try resolving it to a Discord Game ID if it's available. Example:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
client.setPlayingGame(18);
|
||||
// sets the client as playing Minecraft, game ID 18
|
||||
|
||||
client.setPlayingGame("Minecraft");
|
||||
// sets the client as playing Minecraft by resolving the ID to 18
|
||||
|
||||
client.setPlayingGame("my magical made up game")
|
||||
// will stop the client from playing anything as it is unresolved, not a valid game.
|
||||
|
||||
-----
|
||||
|
||||
Event Management
|
||||
----------------
|
||||
|
||||
Events are a useful way of listening to events and are available in every API.
|
||||
|
||||
Registering Events
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.on("eventName", function(arg1, arg2...){
|
||||
// code here is called when eventName is emitted.
|
||||
})
|
||||
|
||||
.. note:: You can only have one listening function per event
|
||||
|
||||
Unregistering Events
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.off("eventName")
|
||||
// eventName is no longer listened for
|
||||
|
||||
Event Types
|
||||
-----------
|
||||
|
||||
ready
|
||||
~~~~~
|
||||
|
||||
Called when the bot is ready and you can begin working with it.
|
||||
|
||||
disconnected
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Called when the bot is disconnected for whatever reason.
|
||||
|
||||
error
|
||||
~~~~~
|
||||
|
||||
Called whenever there is an error.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **error** - the encountered error
|
||||
|
||||
.. note:: There may be more parameters supplied depending on the errors. Use the ``arguments`` variable to check for this for advanced debugging.
|
||||
|
||||
debug
|
||||
~~~~~
|
||||
|
||||
Called when the client debugs some information that might be useful for a developer but not for an end user.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **message** - the debug message as a `String`
|
||||
|
||||
message
|
||||
~~~~~~~
|
||||
|
||||
Called when a message has been received by the client.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **message** - the received Message_.
|
||||
|
||||
messageDelete
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Called when a message has been deleted.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **channel** - The Channel_ that the deleted message was in.
|
||||
- **message** - *May* be available. If the message wasn't previously cached, this will not be supplied and all you would know is that a message was deleted in the channel. If it is available, it will be in the format of a Message_.
|
||||
|
||||
messageUpdate
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Called when a message has been updated.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **newMessage** - The updated Message_.
|
||||
- **oldMessage** - The old Message_ before it was updated.
|
||||
|
||||
serverDelete
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Called when a server is deleted.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **server** - The deleted Server_.
|
||||
|
||||
channelDelete
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Called when a channel is deleted.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **channel** - The deleted Channel_.
|
||||
|
||||
serverCreate
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Called when a server is created/joined.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **server** - The created Server_.
|
||||
|
||||
channelCreate
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Called when a channel is created.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **channel** - The created Channel_.
|
||||
|
||||
serverNewMember
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Called when a new member is added to a server.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **user** - The User_ that was added.
|
||||
- **server** - The Server_ that the user was added to.
|
||||
|
||||
serverRemoveMember
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Called when a member of a server leaves or is kicked out.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **user** - The User_ that was removed.
|
||||
- **server** - The Server_ that the user was removed from.
|
||||
|
||||
userUpdate
|
||||
~~~~~~~~~~
|
||||
|
||||
Called when information about a user changes, such as their username.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **newUser** - A User_ object representing the changes to the old user (this will be in the cache)
|
||||
- **oldUser** - A User_ object representing the user before the update.
|
||||
|
||||
presence
|
||||
~~~~~~~~
|
||||
|
||||
Called when a user goes online/offline/away or starts/stops playing a game.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **dataObject** - Instead of separate arguments, presence update takes an object containing the following information:
|
||||
|
||||
- **user** - A User_ representing the User that had a presence update
|
||||
- **status** - The status change as a `String`.
|
||||
- **server** - The Server_ that the presence change occurred in.
|
||||
- **gameId** - A `Number` representing the game they are playing if any. Currently, discord.js has no internal support for converting this into a game name.
|
||||
|
||||
unknown
|
||||
~~~~~~~
|
||||
|
||||
Called when an unknown packet was received or there is no handler for it.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **data** - A `JSON Object` which is the message received over WebSocket.
|
||||
|
||||
raw
|
||||
~~~
|
||||
|
||||
Called when a WebSocket message is received and it gives you the message.
|
||||
|
||||
**Parameters**
|
||||
|
||||
- **data** - A `JSON Object` which is the message received over WebSocket.
|
||||
|
||||
.. _official API here : https://discordapp.com/api/voice/regions
|
||||
|
||||
.. _Discord Game ID : https://raw.githubusercontent.com/hydrabolt/discord.js/master/ref/gameMap.json
|
||||
64
docs/docs_invite.rst
Normal file
64
docs/docs_invite.rst
Normal file
@@ -0,0 +1,64 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
Invite Documentation
|
||||
====================
|
||||
|
||||
The Invite Class is used to represent data about an Invite.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
max_age
|
||||
~~~~~~~
|
||||
|
||||
A `Number` in minutes for how long the Invite should be valid for. E.g. a value of ``3600`` is equal to 30 minutes.
|
||||
|
||||
code
|
||||
~~~~
|
||||
|
||||
`String` an alphanumeric code for the Invite.
|
||||
|
||||
revoked
|
||||
~~~~~~~
|
||||
|
||||
`Boolean` that dictates whether the Invite has been cancelled or not
|
||||
|
||||
created_at
|
||||
~~~~~~~~~~
|
||||
|
||||
A unix timestamp as a `Number` which is the time that the invite was created.
|
||||
|
||||
temporary
|
||||
~~~~~~~~~
|
||||
|
||||
`Boolean` that dictates whether the invite is temporary.
|
||||
|
||||
uses
|
||||
~~~~
|
||||
|
||||
`Number` the number of uses of the Invite, a value of ``0`` is none.
|
||||
|
||||
max_uses
|
||||
~~~~~~~~
|
||||
|
||||
`Number` that is the maximum amount of uses of the invite, ``0`` is unlimited.
|
||||
|
||||
inviter
|
||||
~~~~~~~
|
||||
|
||||
The User_ that created the invite.
|
||||
|
||||
xkcd
|
||||
~~~~
|
||||
|
||||
`Boolean` that is true if the invite should be human-readable.
|
||||
|
||||
channel
|
||||
~~~~~~~
|
||||
|
||||
The Channel_ that the invite is inviting to.
|
||||
|
||||
URL
|
||||
~~~
|
||||
|
||||
A `String` that generates a clickable link to the invite.
|
||||
84
docs/docs_message.rst
Normal file
84
docs/docs_message.rst
Normal file
@@ -0,0 +1,84 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
Message Documentation
|
||||
=====================
|
||||
|
||||
The Message Class is used to represent data about a Message.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
tts
|
||||
~~~
|
||||
|
||||
A `Boolean` that is ``true`` if the sent message was text-to-speech, otherwise ``false``.
|
||||
|
||||
timestamp
|
||||
~~~~~~~~~
|
||||
|
||||
A `unix timestamp` as a `Number` representing when the message was sent.
|
||||
|
||||
mentions
|
||||
~~~~~~~~
|
||||
|
||||
An `Array` of User_ objects that represent the users mentioned in the message.
|
||||
|
||||
everyoneMentioned
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
A `Boolean` that is ``true`` if **@everyone** was used, otherwise ``false``.
|
||||
|
||||
id
|
||||
~~
|
||||
|
||||
A `String` UUID of the message, will never change.
|
||||
|
||||
.. note:: Currently, message IDs are totally unique. However, in the future they may only be unique within a channel. Make sure to check periodically whether this has changed.
|
||||
|
||||
embeds
|
||||
~~~~~~
|
||||
|
||||
A raw, unhandled `JSON object` that will contain embeds of the message - if any.
|
||||
|
||||
editedTimestamp
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
A `unix timestamp` as a `Number` that is when the message was last edited.
|
||||
|
||||
content
|
||||
~~~~~~~
|
||||
|
||||
The actual content of the message as a `String`.
|
||||
|
||||
channel
|
||||
~~~~~~~
|
||||
|
||||
The Channel_ that the message was sent in.
|
||||
|
||||
author
|
||||
~~~~~~
|
||||
|
||||
**Aliases** : `sender`
|
||||
|
||||
The User_ that sent the message.
|
||||
|
||||
attachments
|
||||
~~~~~~~~~~~
|
||||
|
||||
A raw, unhandled `JSON object` that will contain attachments of the message - if any.
|
||||
|
||||
isPrivate
|
||||
~~~~~~~~~
|
||||
|
||||
A `Boolean` that is ``true`` if the message was sent in a PM / DM chat, or if it was sent in a group chat it will be ``false``.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
isMentioned(user)
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
A `Boolean` that will return ``true`` if the specified user was mentioned in the message. If everyone is mentioned, this will be false - this function checks specifically for if they were mentioned.
|
||||
|
||||
|
||||
- **user** - The User_ that you want to see is mentioned or not.
|
||||
41
docs/docs_pmchannel.rst
Normal file
41
docs/docs_pmchannel.rst
Normal file
@@ -0,0 +1,41 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
PMChannel Documentation
|
||||
=======================
|
||||
|
||||
The PMChannel Class is used to represent data about a Private Message Channel.
|
||||
|
||||
.. note:: Beware! The PMChannel class does `not` extend the Channel_ class.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
user
|
||||
~~~~
|
||||
|
||||
The recipient User_ of the PM Channel.
|
||||
|
||||
id
|
||||
~~
|
||||
|
||||
`String` UUID of the PM Channel.
|
||||
|
||||
messages
|
||||
~~~~~~~~
|
||||
|
||||
An `Array` of Message_ objects. Contains all the cached messages sent in this channel up to a limit of 1000. If the limit is reached, the oldest message is removed first to make space for it.
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
getMessage(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a Message_ from the PM Channel that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
pmchannel.getMessage("id", 1243987349) // returns a Message where message.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
27
docs/docs_resolvable.rst
Normal file
27
docs/docs_resolvable.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
Resolvable Documentation
|
||||
========================
|
||||
|
||||
To be robust, discord.js needs to handle a wide amount of ambiguous data that is supplied to it. This means you can use functions much more easily. Anything that is resolvable means it can be normalised without you having to do it explicitly.
|
||||
|
||||
Resolvables are not objects or classes, they are just ways of expressing what type of data is expected.
|
||||
|
||||
Channel Resolvable
|
||||
------------------
|
||||
|
||||
A Channel Resolvable is data that can be resolved to a channel ID. Here is what is currently supported:
|
||||
|
||||
- A Channel_ object
|
||||
- A Server_ object (the #general channel of the server will be used)
|
||||
- A `String` representing the channel ID
|
||||
- A Message_ (the channel the message was sent in will be used)
|
||||
- A User_ (will get the PM channel with the specified user)
|
||||
|
||||
.. note:: A User cannot always be specified in certain cases. For example, if using `bot.setTopic`, a User or PM Channel can't be specified as these do not support channel topics.
|
||||
|
||||
Server Resolvable
|
||||
-----------------
|
||||
|
||||
Invite Resolvable
|
||||
-----------------
|
||||
107
docs/docs_server.rst
Normal file
107
docs/docs_server.rst
Normal file
@@ -0,0 +1,107 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
Server Documentation
|
||||
==================
|
||||
|
||||
The Server Class is used to represent data about a server.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
client
|
||||
~~~~~~
|
||||
|
||||
The Discord Client_ that the Server was cached by.
|
||||
|
||||
region
|
||||
~~~~~~
|
||||
|
||||
The region that the server is in, a `String`.
|
||||
|
||||
name
|
||||
~~~~
|
||||
|
||||
The server's name, as a `String`.
|
||||
|
||||
id
|
||||
~~
|
||||
|
||||
The server's id, as a `String`.
|
||||
|
||||
members
|
||||
~~~~~~~
|
||||
|
||||
**Aliases** : `users`
|
||||
|
||||
The members in a server, an `Array` of User_ objects.
|
||||
|
||||
channels
|
||||
~~~~~~~~
|
||||
|
||||
The channels in a server, an `Array` of Channel_ objects.
|
||||
|
||||
icon
|
||||
~~~~
|
||||
|
||||
The icon ID of the server if it has one as a `String`, otherwise it is `null`.
|
||||
|
||||
iconURL
|
||||
~~~~~~~
|
||||
|
||||
A `String` that is the URL of the server icon if it has one, otherwise it is `null`.
|
||||
|
||||
afkTimeout
|
||||
~~~~~~~~~~
|
||||
|
||||
A `Number` that is the AFK Timeout of the Server.
|
||||
|
||||
afkChannel
|
||||
~~~~~~~~~~
|
||||
|
||||
A Channel_ that represents the AFK Channel of the server if it has one, otherwise it is `null`.
|
||||
|
||||
defaultChannel
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The **#general** Channel_ of the server.
|
||||
|
||||
owner
|
||||
~~~~~
|
||||
|
||||
A User_ object representing the user that owns the server.
|
||||
|
||||
-----
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
.. note:: When concatenated with a String, the object will become the server's name, e.g. ``"this is " + server`` would be ``this is Discord API`` if the server was called `Discord API`.
|
||||
|
||||
getChannel(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a Channel_ that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
server.getChannel("id", 1243987349) // returns a Channel where channel.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
|
||||
getMember(key, value)
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Gets a User_ that matches the specified criteria. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
bot.getUser("id", 1243987349) // returns a user where user.id === 1243987349
|
||||
|
||||
- **key** - a `String` that is the key
|
||||
- **value** - a `String` that is the value
|
||||
|
||||
equals(object)
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Returns a `Boolean` depending on whether the Server's ID (``server.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare servers. **NEVER** do ``server1 == server2``.
|
||||
67
docs/docs_user.rst
Normal file
67
docs/docs_user.rst
Normal file
@@ -0,0 +1,67 @@
|
||||
.. include:: ./vars.rst
|
||||
|
||||
User Documentation
|
||||
==================
|
||||
|
||||
The User Class is used to represent data about users.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
username
|
||||
~~~~~~~~
|
||||
|
||||
A `String` that is the username of the user.
|
||||
|
||||
discriminator
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Used to differentiate users with the same username, provided by Discord. If you want to differentiate users, we'd recommend using the `id` attribute.
|
||||
|
||||
id
|
||||
~~
|
||||
|
||||
A `String` UUID of the user, will never change.
|
||||
|
||||
avatar
|
||||
~~~~~~
|
||||
|
||||
A `String` that is the user's avatar's ID, or if they don't have one this is `null`.
|
||||
|
||||
avatarURL
|
||||
~~~~~~~~~
|
||||
|
||||
A `String` that points to the user's avatar's URL, or if they don't have an avatar this is `null`.
|
||||
|
||||
status
|
||||
~~~~~~
|
||||
|
||||
The status of the user as a `String`; offline/online/idle.
|
||||
|
||||
-----
|
||||
|
||||
Functions
|
||||
---------
|
||||
|
||||
mention()
|
||||
~~~~~~~~~
|
||||
|
||||
Returns a `String`. This function will generate the mention string for the user, which when sent will preview as a mention. E.g:
|
||||
|
||||
.. code-block:: js
|
||||
|
||||
user.mention(); // something like <@3245982345035>
|
||||
|
||||
This is mainly used internally by the API to correct mentions when sending messages, however you can use it.
|
||||
|
||||
.. note:: You can also just concatenate a User object with strings to get the mention code, as the `toString()` method points to this. This is useful when sending messages.
|
||||
|
||||
equals(object)
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Returns a `Boolean` depending on whether the User's ID (``user.id``) equals the object's ID (``object.id``). You should **always**, always use this if you want to compare users. **NEVER** do ``user1 == user2``.
|
||||
|
||||
equalsStrict(object)
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sees if the supplied object has the same username, ID, avatar and discriminator of the user. Mainly used internally. Returns a `Boolean` depending on the result.
|
||||
37
docs/get_started.rst
Normal file
37
docs/get_started.rst
Normal file
@@ -0,0 +1,37 @@
|
||||
===========
|
||||
Get Started
|
||||
===========
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Linux / OS X
|
||||
~~~~~~~~~~~~
|
||||
Run ``npm install discord.js --save`` in your project's directory and you should be good to go!
|
||||
|
||||
Windows
|
||||
~~~~~~~~~~~~
|
||||
Unfortunately, the Windows installation process is a little more lengthy. You need to have `Visual Studio Express`_ (or any of the other distributions of it). This is necessary for build tools for the WebSocket dependency.
|
||||
|
||||
.. note:: If you are using another version of Visual Studio, such as 2012, replace the flag with ``--msvs_version=2012``
|
||||
|
||||
After you have obtained these tools, you need to run ``npm install discord.js --save --msvs_version=2015`` in your working directory. Hopefully this should all go well!
|
||||
|
||||
Cloning the Repo
|
||||
----------------
|
||||
If you want to try some examples or make your own changes to discord.js, you can `clone the repo`_. After that run ``npm install`` to install dependencies.
|
||||
|
||||
Running Examples
|
||||
~~~~~~~~~~~~~~~~
|
||||
If you've cloned the repo, you also have the option to run some examples. You can also do this by just copying the examples_ and then running them. I'd be more than happy to get some pull requests if you want to make any patches ;)
|
||||
|
||||
|
||||
Before you run them though, you need to configure the ``examples/auth.json`` file. This should contain valid Discord credentials and passwords.
|
||||
|
||||
After you've configured your credentials, just run ``node examples/pingpong.js`` to run the ping pong example.
|
||||
|
||||
|
||||
|
||||
.. _Visual Studio Express: https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx
|
||||
.. _clone the repo: https://github.com/hydrabolt/discord.js.git
|
||||
.. _examples: https://github.com/hydrabolt/discord.js/tree/master/examples
|
||||
49
docs/index.rst
Normal file
49
docs/index.rst
Normal file
@@ -0,0 +1,49 @@
|
||||
.. discord.js documentation master file, created by
|
||||
sphinx-quickstart on Fri Sep 25 17:25:49 2015.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to discord.js's documentation!
|
||||
======================================
|
||||
|
||||
discord.js is an easy-to-use and intuitive JavaScript API for Discord_. It should be able to
|
||||
run in node.js / io.js and in the browser.
|
||||
|
||||
.. note:: This documentation is still a work-in-progress, apologies if something isn't yet documented!
|
||||
|
||||
Contents:
|
||||
|
||||
.. _general-docs:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: General
|
||||
|
||||
get_started
|
||||
troubleshooting
|
||||
create_simple_bot
|
||||
|
||||
.. _docs:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Documentation
|
||||
|
||||
docs_resolvable
|
||||
docs_client
|
||||
docs_user
|
||||
docs_server
|
||||
docs_channel
|
||||
docs_pmchannel
|
||||
docs_message
|
||||
docs_invite
|
||||
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`search`
|
||||
|
||||
.. _Discord : https://discordapp.com/
|
||||
263
docs/make.bat
Normal file
263
docs/make.bat
Normal file
@@ -0,0 +1,263 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=sphinx-build
|
||||
)
|
||||
set BUILDDIR=_build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% .
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. xml to make Docutils-native XML files
|
||||
echo. pseudoxml to make pseudoxml-XML files for display purposes
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
echo. coverage to run coverage check of the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
|
||||
REM Check if sphinx-build is available and fallback to Python version if any
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 goto sphinx_python
|
||||
goto sphinx_ok
|
||||
|
||||
:sphinx_python
|
||||
|
||||
set SPHINXBUILD=python -m sphinx.__init__
|
||||
%SPHINXBUILD% 2> nul
|
||||
if errorlevel 9009 (
|
||||
echo.
|
||||
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||
echo.may add the Sphinx directory to PATH.
|
||||
echo.
|
||||
echo.If you don't have Sphinx installed, grab it from
|
||||
echo.http://sphinx-doc.org/
|
||||
exit /b 1
|
||||
)
|
||||
|
||||
:sphinx_ok
|
||||
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\discordjs.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\discordjs.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdf" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latexpdfja" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
cd %BUILDDIR%/latex
|
||||
make all-pdf-ja
|
||||
cd %~dp0
|
||||
echo.
|
||||
echo.Build finished; the PDF files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "coverage" (
|
||||
%SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of coverage in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/coverage/python.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "xml" (
|
||||
%SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The XML files are in %BUILDDIR%/xml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pseudoxml" (
|
||||
%SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
10
docs/troubleshooting.rst
Normal file
10
docs/troubleshooting.rst
Normal file
@@ -0,0 +1,10 @@
|
||||
Troubleshooting
|
||||
===============
|
||||
|
||||
Occasionally, the API can stop working for whatever reason. If it was working previously and it stopped working on the same version, it means that there's been a change to the Discord API. In this case, please `make an issue`_ if one relating to a similar issue doesn't exist. Please post a stacktrace if there is one, and be as detailed as possible - *"the API isn't working"* doesn't help at all.
|
||||
|
||||
If there is already an issue, feel free to comment that you're also experiencing the same thing. This helps to see how widespread the bug is.
|
||||
|
||||
You can try reconnecting before submitting an issue, as sometimes some of the servers may be slightly different.
|
||||
|
||||
.. _make an issue : https://github.com/hydrabolt/discord.js/issues
|
||||
11
docs/vars.rst
Normal file
11
docs/vars.rst
Normal file
@@ -0,0 +1,11 @@
|
||||
.. _Client : ./docs_client.html
|
||||
.. _User : ./docs_user.html
|
||||
.. _ready : #ready
|
||||
.. _Server : ./docs_server.html
|
||||
.. _Channel : ./docs_channel.html
|
||||
.. _Message : ./docs_message.html
|
||||
.. _PMChannel : ./docs_pmchannel.html
|
||||
.. _Invite : ./docs_invite.html
|
||||
.. _Channel Resolvable : ./docs_resolvable.html#channel-resolvable
|
||||
.. _Invite Resolvable : ./docs_resolvable.html#invite-resolvable
|
||||
.. _Promises : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise
|
||||
@@ -4,38 +4,28 @@
|
||||
|
||||
var Discord = require("../");
|
||||
|
||||
// Get the email and password
|
||||
var AuthDetails = require("./auth.json");
|
||||
|
||||
var bot = new Discord.Client();
|
||||
|
||||
bot.on("ready", function () {
|
||||
bot.on("ready", () => {
|
||||
console.log("Ready to begin! Serving in " + bot.channels.length + " channels");
|
||||
});
|
||||
|
||||
bot.on("disconnected", function () {
|
||||
bot.on("disconnected", () => {
|
||||
|
||||
console.log("Disconnected!");
|
||||
process.exit(1); //exit node.js with an error
|
||||
|
||||
});
|
||||
|
||||
bot.on("message", function (msg) {
|
||||
if (msg.content === "$avatar") {
|
||||
|
||||
//see if the user has an avatar
|
||||
if( msg.sender.avatarURL ){
|
||||
bot.reply(msg, msg.sender.avatarURL);
|
||||
}else{
|
||||
//using reply with a message automatically does:
|
||||
// '@sender, ' for you!
|
||||
bot.reply(msg, "you don't have an avatar!");
|
||||
}
|
||||
|
||||
//alert the console
|
||||
console.log("served " + msg.sender.username);
|
||||
|
||||
bot.on("message", (msg) => {
|
||||
|
||||
if( msg.content === "avatar" ){
|
||||
// if the message was avatar
|
||||
bot.reply( msg, msg.sender.avatarURL );
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
bot.login(AuthDetails.email, AuthDetails.password);
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
this bot will send an image of a cat to a channel.
|
||||
may be slow depending on your internet connection.
|
||||
*/
|
||||
|
||||
var Discord = require("../");
|
||||
|
||||
// Get the email and password
|
||||
var AuthDetails = require("./auth.json");
|
||||
|
||||
var bot = new Discord.Client();
|
||||
|
||||
bot.on("ready", function () {
|
||||
console.log("Ready to begin! Serving in " + bot.channels.length + " channels");
|
||||
});
|
||||
|
||||
bot.on("disconnected", function () {
|
||||
|
||||
console.log("Disconnected!");
|
||||
process.exit(1); //exit node.js with an error
|
||||
|
||||
});
|
||||
|
||||
bot.on("message", function (msg) {
|
||||
if (msg.content === "$cat") {
|
||||
|
||||
//send a message to the channel the ping message was sent in.
|
||||
bot.sendMessage(msg.channel, "pong!");
|
||||
|
||||
//alert the console
|
||||
console.log("pong-ed " + msg.sender.username);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
bot.login(AuthDetails.email, AuthDetails.password);
|
||||
41
examples/permissions.js
Normal file
41
examples/permissions.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/* this bot will see if a user can send TTS messages */
|
||||
|
||||
var Discord = require("../");
|
||||
|
||||
var AuthDetails = require("./auth.json");
|
||||
|
||||
var bot = new Discord.Client();
|
||||
|
||||
bot.on("ready", () => {
|
||||
console.log("Ready to begin!");
|
||||
});
|
||||
|
||||
bot.on("message", (msg) => {
|
||||
|
||||
if(msg.content === "can I tts?"){
|
||||
|
||||
var user = msg.sender;
|
||||
|
||||
// get the evaluated permissions for a user in the channel they asked
|
||||
var permissions = msg.channel.permissionsOf(user);
|
||||
|
||||
if(permissions.sendTTSMessages){
|
||||
|
||||
bot.reply(msg, "You *can* send TTS messages.");
|
||||
|
||||
}else{
|
||||
|
||||
bot.reply(msg, "You *can't* send TTS messages.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
for a list of more permissions, go to
|
||||
https://github.com/hydrabolt/discord.js/blob/master/src/EvaluatedPermissions.js
|
||||
*/
|
||||
|
||||
})
|
||||
|
||||
bot.login(AuthDetails.email, AuthDetails.password);
|
||||
33
examples/send-files.js
Normal file
33
examples/send-files.js
Normal file
@@ -0,0 +1,33 @@
|
||||
/* this bot will send an image to a channel */
|
||||
|
||||
var Discord = require("../");
|
||||
|
||||
var AuthDetails = require("./auth.json");
|
||||
|
||||
var bot = new Discord.Client();
|
||||
|
||||
bot.on("ready", () => {
|
||||
console.log("Ready to begin!");
|
||||
});
|
||||
|
||||
bot.on("message", (msg) => {
|
||||
|
||||
if (msg.content === "photos") {
|
||||
|
||||
bot.sendFile( msg.channel, "./test/image.png", "photo.png", (err, msg) => {
|
||||
if(err)
|
||||
console.log("couldn't send image:", err);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if( msg.content === "file" ) {
|
||||
bot.sendFile( msg.channel, new Buffer("Text in a file!"), "file.txt", (err, msg) => {
|
||||
if(err)
|
||||
console.log("couldn't send file:", err);
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
bot.login(AuthDetails.email, AuthDetails.password);
|
||||
11
gruntfile.js
11
gruntfile.js
@@ -3,9 +3,13 @@ module.exports = function (grunt) {
|
||||
require('load-grunt-tasks')(grunt);
|
||||
|
||||
grunt.initConfig({
|
||||
|
||||
pkg: grunt.file.readJSON("package.json"),
|
||||
// define source files and their destinations
|
||||
babel: {
|
||||
options: {
|
||||
loose: "all",
|
||||
compact: true
|
||||
},
|
||||
dist: {
|
||||
files: [{
|
||||
expand: true,
|
||||
@@ -19,7 +23,7 @@ module.exports = function (grunt) {
|
||||
browserify: {
|
||||
dist: {
|
||||
files: {
|
||||
'web-dist/discord.js': ["lib/index.js"],
|
||||
'web-dist/discord.<%= pkg.version %>.js': ["lib/index.js"],
|
||||
},
|
||||
options: {
|
||||
browserifyOptions: {
|
||||
@@ -31,7 +35,7 @@ module.exports = function (grunt) {
|
||||
uglify: {
|
||||
min: {
|
||||
files: {
|
||||
"./web-dist/discord.min.js": "./web-dist/discord.js"
|
||||
"./web-dist/discord.min.<%= pkg.version %>.js": "./web-dist/discord.<%= pkg.version %>.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,5 +48,6 @@ module.exports = function (grunt) {
|
||||
// register at least this one task
|
||||
grunt.registerTask('default', ['babel']);
|
||||
grunt.registerTask('web', ['browserify', "uglify"]);
|
||||
grunt.registerTask("dist", ["babel", "browserify", "uglify"])
|
||||
|
||||
};
|
||||
180
lib/ChannelPermissions.js
Normal file
180
lib/ChannelPermissions.js
Normal file
@@ -0,0 +1,180 @@
|
||||
"use strict";
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var ChannelPermissions = (function () {
|
||||
function ChannelPermissions(data, channel) {
|
||||
_classCallCheck(this, ChannelPermissions);
|
||||
|
||||
var self = this;
|
||||
|
||||
function getBit(x) {
|
||||
return (self.packed >>> x & 1) === 1;
|
||||
}
|
||||
|
||||
this.type = data.type; //either member or role
|
||||
this.id = data.id;
|
||||
|
||||
if (this.type === "member") {
|
||||
this.packed = channel.server.getMember("id", data.id).evalPerms.packed;
|
||||
} else {
|
||||
this.packed = channel.server.getRole(data.id).packed;
|
||||
}
|
||||
|
||||
this.packed = this.packed & ~data.deny;
|
||||
this.packed = this.packed | data.allow;
|
||||
|
||||
this.deny = data.deny;
|
||||
this.allow = data.allow;
|
||||
}
|
||||
|
||||
ChannelPermissions.prototype.getBit = function getBit(x) {
|
||||
return (this.packed >>> x & 1) === 1;
|
||||
};
|
||||
|
||||
ChannelPermissions.prototype.setBit = function setBit() {};
|
||||
|
||||
_createClass(ChannelPermissions, [{
|
||||
key: "createInstantInvite",
|
||||
get: function get() {
|
||||
return this.getBit(0);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(0, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageRoles",
|
||||
get: function get() {
|
||||
return this.getBit(3);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(3, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageChannels",
|
||||
get: function get() {
|
||||
return this.getBit(4);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(4, val);
|
||||
}
|
||||
}, {
|
||||
key: "readMessages",
|
||||
get: function get() {
|
||||
return this.getBit(10);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(10, val);
|
||||
}
|
||||
}, {
|
||||
key: "sendMessages",
|
||||
get: function get() {
|
||||
return this.getBit(11);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(11, val);
|
||||
}
|
||||
}, {
|
||||
key: "sendTTSMessages",
|
||||
get: function get() {
|
||||
return this.getBit(12);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(12, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageMessages",
|
||||
get: function get() {
|
||||
return this.getBit(13);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(13, val);
|
||||
}
|
||||
}, {
|
||||
key: "embedLinks",
|
||||
get: function get() {
|
||||
return this.getBit(14);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(14, val);
|
||||
}
|
||||
}, {
|
||||
key: "attachFiles",
|
||||
get: function get() {
|
||||
return this.getBit(15);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(15, val);
|
||||
}
|
||||
}, {
|
||||
key: "readMessageHistory",
|
||||
get: function get() {
|
||||
return this.getBit(16);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(16, val);
|
||||
}
|
||||
}, {
|
||||
key: "mentionEveryone",
|
||||
get: function get() {
|
||||
return this.getBit(17);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(17, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceConnect",
|
||||
get: function get() {
|
||||
return this.getBit(20);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(20, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceSpeak",
|
||||
get: function get() {
|
||||
return this.getBit(21);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(21, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceMuteMembers",
|
||||
get: function get() {
|
||||
return this.getBit(22);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(22, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceDeafenMembers",
|
||||
get: function get() {
|
||||
return this.getBit(23);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(23, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceMoveMembers",
|
||||
get: function get() {
|
||||
return this.getBit(24);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(24, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceUseVoiceActivation",
|
||||
get: function get() {
|
||||
return this.getBit(25);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(25, val);
|
||||
}
|
||||
}]);
|
||||
|
||||
return ChannelPermissions;
|
||||
})();
|
||||
|
||||
module.exports = ChannelPermissions;
|
||||
2930
lib/Client.js
2930
lib/Client.js
File diff suppressed because it is too large
Load Diff
187
lib/EvaluatedPermissions.js
Normal file
187
lib/EvaluatedPermissions.js
Normal file
@@ -0,0 +1,187 @@
|
||||
"use strict";
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var EvaluatedPermissions = (function () {
|
||||
function EvaluatedPermissions(data) {
|
||||
_classCallCheck(this, EvaluatedPermissions);
|
||||
|
||||
var self = this;
|
||||
|
||||
this.packed = data;
|
||||
|
||||
if (this.getBit(3)) this.packed = 4294967295;
|
||||
}
|
||||
|
||||
EvaluatedPermissions.prototype.serialise = function serialise() {
|
||||
return {
|
||||
createInstantInvite: this.createInstantInvite,
|
||||
manageRoles: this.manageRoles,
|
||||
manageChannels: this.manageChannels,
|
||||
readMessages: this.readMessages,
|
||||
sendMessages: this.sendMessage,
|
||||
sendTTSMessages: this.sendTTSMessages,
|
||||
manageMessages: this.manageMessages,
|
||||
embedLinks: this.embedLinks,
|
||||
attachFiles: this.attachFiles,
|
||||
readMessageHistory: this.readMessageHistory,
|
||||
mentionEveryone: this.mentionEveryone,
|
||||
voiceConnect: this.voiceConnect,
|
||||
voiceSpeak: this.voiceSpeak,
|
||||
voiceMuteMembers: this.voiceMuteMembers,
|
||||
voiceDeafenMembers: this.voiceDeafenMembers,
|
||||
voiceMoveMember: this.voiceMoveMembers,
|
||||
voiceUseVoiceActivation: this.voiceUseVoiceActivation
|
||||
};
|
||||
};
|
||||
|
||||
EvaluatedPermissions.prototype.getBit = function getBit(x) {
|
||||
return (this.packed >>> x & 1) === 1;
|
||||
};
|
||||
|
||||
EvaluatedPermissions.prototype.setBit = function setBit() {};
|
||||
|
||||
_createClass(EvaluatedPermissions, [{
|
||||
key: "createInstantInvite",
|
||||
get: function get() {
|
||||
return this.getBit(0);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(0, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageRoles",
|
||||
get: function get() {
|
||||
return this.getBit(3);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(3, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageChannels",
|
||||
get: function get() {
|
||||
return this.getBit(4);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(4, val);
|
||||
}
|
||||
}, {
|
||||
key: "readMessages",
|
||||
get: function get() {
|
||||
return this.getBit(10);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(10, val);
|
||||
}
|
||||
}, {
|
||||
key: "sendMessages",
|
||||
get: function get() {
|
||||
return this.getBit(11);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(11, val);
|
||||
}
|
||||
}, {
|
||||
key: "sendTTSMessages",
|
||||
get: function get() {
|
||||
return this.getBit(12);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(12, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageMessages",
|
||||
get: function get() {
|
||||
return this.getBit(13);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(13, val);
|
||||
}
|
||||
}, {
|
||||
key: "embedLinks",
|
||||
get: function get() {
|
||||
return this.getBit(14);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(14, val);
|
||||
}
|
||||
}, {
|
||||
key: "attachFiles",
|
||||
get: function get() {
|
||||
return this.getBit(15);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(15, val);
|
||||
}
|
||||
}, {
|
||||
key: "readMessageHistory",
|
||||
get: function get() {
|
||||
return this.getBit(16);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(16, val);
|
||||
}
|
||||
}, {
|
||||
key: "mentionEveryone",
|
||||
get: function get() {
|
||||
return this.getBit(17);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(17, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceConnect",
|
||||
get: function get() {
|
||||
return this.getBit(20);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(20, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceSpeak",
|
||||
get: function get() {
|
||||
return this.getBit(21);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(21, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceMuteMembers",
|
||||
get: function get() {
|
||||
return this.getBit(22);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(22, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceDeafenMembers",
|
||||
get: function get() {
|
||||
return this.getBit(23);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(23, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceMoveMembers",
|
||||
get: function get() {
|
||||
return this.getBit(24);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(24, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceUseVoiceActivation",
|
||||
get: function get() {
|
||||
return this.getBit(25);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(25, val);
|
||||
}
|
||||
}]);
|
||||
|
||||
return EvaluatedPermissions;
|
||||
})();
|
||||
|
||||
module.exports = EvaluatedPermissions;
|
||||
157
lib/Member.js
Normal file
157
lib/Member.js
Normal file
@@ -0,0 +1,157 @@
|
||||
"use strict";
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
var User = require("./user.js");
|
||||
var ServerPermissions = require("./ServerPermissions.js");
|
||||
var EvaluatedPermissions = require("./EvaluatedPermissions.js");
|
||||
|
||||
var Member = (function (_User) {
|
||||
_inherits(Member, _User);
|
||||
|
||||
function Member(user, server, roles) {
|
||||
_classCallCheck(this, Member);
|
||||
|
||||
_User.call(this, user); // should work, we are basically creating a Member that has the same properties as user and a few more
|
||||
this.server = server;
|
||||
this.rawRoles = roles;
|
||||
}
|
||||
|
||||
Member.prototype.permissionsIn = function permissionsIn(channel) {
|
||||
|
||||
if (channel.server.ownerID === this.id) {
|
||||
return new EvaluatedPermissions(4294967295); //all perms
|
||||
}
|
||||
|
||||
var affectingOverwrites = [];
|
||||
var affectingMemberOverwrites = [];
|
||||
|
||||
for (var _iterator = channel.roles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
|
||||
var overwrite = _ref;
|
||||
|
||||
if (overwrite.id === this.id && overwrite.type === "member") {
|
||||
affectingMemberOverwrites.push(overwrite);
|
||||
} else if (this.rawRoles.indexOf(overwrite.id) !== -1) {
|
||||
affectingOverwrites.push(overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
if (affectingOverwrites.length === 0 && affectingMemberOverwrites.length === 0) {
|
||||
return new EvaluatedPermissions(this.evalPerms.packed);
|
||||
}
|
||||
|
||||
var finalPacked = affectingOverwrites.length !== 0 ? affectingOverwrites[0].packed : affectingMemberOverwrites[0].packed;
|
||||
|
||||
for (var _iterator2 = affectingOverwrites, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
|
||||
var _ref2;
|
||||
|
||||
if (_isArray2) {
|
||||
if (_i2 >= _iterator2.length) break;
|
||||
_ref2 = _iterator2[_i2++];
|
||||
} else {
|
||||
_i2 = _iterator2.next();
|
||||
if (_i2.done) break;
|
||||
_ref2 = _i2.value;
|
||||
}
|
||||
|
||||
var overwrite = _ref2;
|
||||
|
||||
finalPacked = finalPacked & ~overwrite.deny;
|
||||
finalPacked = finalPacked | overwrite.allow;
|
||||
}
|
||||
|
||||
for (var _iterator3 = affectingMemberOverwrites, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
|
||||
var _ref3;
|
||||
|
||||
if (_isArray3) {
|
||||
if (_i3 >= _iterator3.length) break;
|
||||
_ref3 = _iterator3[_i3++];
|
||||
} else {
|
||||
_i3 = _iterator3.next();
|
||||
if (_i3.done) break;
|
||||
_ref3 = _i3.value;
|
||||
}
|
||||
|
||||
var overwrite = _ref3;
|
||||
|
||||
finalPacked = finalPacked & ~overwrite.deny;
|
||||
finalPacked = finalPacked | overwrite.allow;
|
||||
}
|
||||
|
||||
return new EvaluatedPermissions(finalPacked);
|
||||
};
|
||||
|
||||
_createClass(Member, [{
|
||||
key: "roles",
|
||||
get: function get() {
|
||||
|
||||
var ufRoles = [this.server.getRole(this.server.id)];
|
||||
|
||||
for (var _iterator4 = this.rawRoles, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
|
||||
var _ref4;
|
||||
|
||||
if (_isArray4) {
|
||||
if (_i4 >= _iterator4.length) break;
|
||||
_ref4 = _iterator4[_i4++];
|
||||
} else {
|
||||
_i4 = _iterator4.next();
|
||||
if (_i4.done) break;
|
||||
_ref4 = _i4.value;
|
||||
}
|
||||
|
||||
var rawRole = _ref4;
|
||||
|
||||
ufRoles.push(this.server.getRole(rawRole));
|
||||
}
|
||||
|
||||
return ufRoles;
|
||||
}
|
||||
}, {
|
||||
key: "evalPerms",
|
||||
get: function get() {
|
||||
var basePerms = this.roles,
|
||||
//cache roles as it can be slightly expensive
|
||||
basePerm = basePerms[0].packed;
|
||||
|
||||
for (var _iterator5 = basePerms, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
|
||||
var _ref5;
|
||||
|
||||
if (_isArray5) {
|
||||
if (_i5 >= _iterator5.length) break;
|
||||
_ref5 = _iterator5[_i5++];
|
||||
} else {
|
||||
_i5 = _iterator5.next();
|
||||
if (_i5.done) break;
|
||||
_ref5 = _i5.value;
|
||||
}
|
||||
|
||||
var perm = _ref5;
|
||||
|
||||
basePerm = basePerm | perm.packed;
|
||||
}
|
||||
|
||||
return new ServerPermissions({
|
||||
permissions: basePerm
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return Member;
|
||||
})(User);
|
||||
|
||||
module.exports = Member;
|
||||
@@ -11,47 +11,47 @@ var PMChannel = (function () {
|
||||
this.user = client.getUser("id", data.recipient.id);
|
||||
this.id = data.id;
|
||||
this.messages = [];
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
_createClass(PMChannel, [{
|
||||
key: "addMessage",
|
||||
value: function addMessage(data) {
|
||||
if (!this.getMessage("id", data.id)) {
|
||||
this.messages.push(data);
|
||||
}
|
||||
return this.getMessage("id", data.id);
|
||||
PMChannel.prototype.addMessage = function addMessage(data) {
|
||||
if (!this.getMessage("id", data.id)) {
|
||||
this.messages.push(data);
|
||||
}
|
||||
}, {
|
||||
key: "getMessage",
|
||||
value: function getMessage(key, value) {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
return this.getMessage("id", data.id);
|
||||
};
|
||||
|
||||
try {
|
||||
for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var message = _step.value;
|
||||
PMChannel.prototype.getMessage = function getMessage(key, value) {
|
||||
|
||||
if (message[key] === value) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator["return"]) {
|
||||
_iterator["return"]();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
if (this.messages.length > 1000) {
|
||||
this.messages.splice(0, 1);
|
||||
}
|
||||
|
||||
for (var _iterator = this.messages, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
|
||||
return null;
|
||||
var message = _ref;
|
||||
|
||||
if (message[key] === value) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
_createClass(PMChannel, [{
|
||||
key: "isPrivate",
|
||||
get: function get() {
|
||||
return true;
|
||||
}
|
||||
}]);
|
||||
|
||||
|
||||
48
lib/Permissions.js
Normal file
48
lib/Permissions.js
Normal file
@@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var Permission = (function () {
|
||||
function Permission(packedPermissions) {
|
||||
_classCallCheck(this, Permission);
|
||||
|
||||
function getBit(x) {
|
||||
return (this.packed >>> x & 1) === 1;
|
||||
}
|
||||
|
||||
this.packed = packedPermissions;
|
||||
|
||||
this.createInstantInvite = getBit(0);
|
||||
this.banMembers = getBit(1);
|
||||
this.kickMembers = getBit(2);
|
||||
this.manageRoles = getBit(3);
|
||||
this.manageChannels = getBit(4);
|
||||
this.manageServer = getBit(5);
|
||||
this.readMessages = getBit(10);
|
||||
this.sendMessages = getBit(11);
|
||||
this.sendTTSMessages = getBit(12);
|
||||
this.manageMessages = getBit(13);
|
||||
this.embedLinks = getBit(14);
|
||||
this.attachFiles = getBit(15);
|
||||
this.readMessageHistory = getBit(16);
|
||||
this.mentionEveryone = getBit(17);
|
||||
|
||||
this.voiceConnect = getBit(20);
|
||||
this.voiceSpeak = getBit(21);
|
||||
this.voiceMuteMembers = getBit(22);
|
||||
this.voiceDeafenMembers = getBit(23);
|
||||
this.voiceMoveMembers = getBit(24);
|
||||
this.voiceUseVoiceActivation = getBit(26);
|
||||
}
|
||||
|
||||
_createClass(Permission, [{
|
||||
key: "getBit",
|
||||
value: function getBit(x) {
|
||||
return (this.packed >>> x & 1) === 1;
|
||||
}
|
||||
}]);
|
||||
|
||||
return Permission;
|
||||
})();
|
||||
199
lib/ServerPermissions.js
Normal file
199
lib/ServerPermissions.js
Normal file
@@ -0,0 +1,199 @@
|
||||
"use strict";
|
||||
|
||||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var ServerPermissions = (function () {
|
||||
function ServerPermissions(data) {
|
||||
_classCallCheck(this, ServerPermissions);
|
||||
|
||||
var self = this;
|
||||
|
||||
function getBit(x) {
|
||||
return (self.packed >>> x & 1) === 1;
|
||||
}
|
||||
|
||||
this.packed = data.permissions;
|
||||
this.name = data.name;
|
||||
this.id = data.id;
|
||||
}
|
||||
|
||||
ServerPermissions.prototype.getBit = function getBit(x) {
|
||||
return (this.packed >>> x & 1) === 1;
|
||||
};
|
||||
|
||||
ServerPermissions.prototype.setBit = function setBit() {
|
||||
//dummy function for now
|
||||
};
|
||||
|
||||
ServerPermissions.prototype.toString = function toString() {
|
||||
return this.name;
|
||||
};
|
||||
|
||||
_createClass(ServerPermissions, [{
|
||||
key: "createInstantInvite",
|
||||
get: function get() {
|
||||
return this.getBit(0);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(0, val);
|
||||
}
|
||||
}, {
|
||||
key: "banMembers",
|
||||
get: function get() {
|
||||
return this.getBit(1);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(1, val);
|
||||
}
|
||||
}, {
|
||||
key: "kickMembers",
|
||||
get: function get() {
|
||||
return this.getBit(2);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(2, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageRoles",
|
||||
get: function get() {
|
||||
return this.getBit(3);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(3, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageChannels",
|
||||
get: function get() {
|
||||
return this.getBit(4);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(4, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageServer",
|
||||
get: function get() {
|
||||
return this.getBit(5);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(5, val);
|
||||
}
|
||||
}, {
|
||||
key: "readMessages",
|
||||
get: function get() {
|
||||
return this.getBit(10);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(10, val);
|
||||
}
|
||||
}, {
|
||||
key: "sendMessages",
|
||||
get: function get() {
|
||||
return this.getBit(11);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(11, val);
|
||||
}
|
||||
}, {
|
||||
key: "sendTTSMessages",
|
||||
get: function get() {
|
||||
return this.getBit(12);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(12, val);
|
||||
}
|
||||
}, {
|
||||
key: "manageMessages",
|
||||
get: function get() {
|
||||
return this.getBit(13);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(13, val);
|
||||
}
|
||||
}, {
|
||||
key: "embedLinks",
|
||||
get: function get() {
|
||||
return this.getBit(14);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(14, val);
|
||||
}
|
||||
}, {
|
||||
key: "attachFiles",
|
||||
get: function get() {
|
||||
return this.getBit(15);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(15, val);
|
||||
}
|
||||
}, {
|
||||
key: "readMessageHistory",
|
||||
get: function get() {
|
||||
return this.getBit(16);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(16, val);
|
||||
}
|
||||
}, {
|
||||
key: "mentionEveryone",
|
||||
get: function get() {
|
||||
return this.getBit(17);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(17, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceConnect",
|
||||
get: function get() {
|
||||
return this.getBit(20);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(20, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceSpeak",
|
||||
get: function get() {
|
||||
return this.getBit(21);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(21, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceMuteMembers",
|
||||
get: function get() {
|
||||
return this.getBit(22);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(22, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceDeafenMembers",
|
||||
get: function get() {
|
||||
return this.getBit(23);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(23, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceMoveMembers",
|
||||
get: function get() {
|
||||
return this.getBit(24);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(24, val);
|
||||
}
|
||||
}, {
|
||||
key: "voiceUseVoiceActivation",
|
||||
get: function get() {
|
||||
return this.getBit(25);
|
||||
},
|
||||
set: function set(val) {
|
||||
this.setBit(25, val);
|
||||
}
|
||||
}]);
|
||||
|
||||
return ServerPermissions;
|
||||
})();
|
||||
|
||||
module.exports = ServerPermissions;
|
||||
139
lib/channel.js
139
lib/channel.js
@@ -4,6 +4,8 @@ var _createClass = (function () { function defineProperties(target, props) { for
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var ChannelPermissions = require("./ChannelPermissions.js");
|
||||
|
||||
var Channel = (function () {
|
||||
function Channel(data, server) {
|
||||
_classCallCheck(this, Channel);
|
||||
@@ -11,66 +13,115 @@ var Channel = (function () {
|
||||
this.server = server;
|
||||
this.name = data.name;
|
||||
this.type = data.type;
|
||||
this.topic = data.topic;
|
||||
this.id = data.id;
|
||||
this.messages = [];
|
||||
this.roles = [];
|
||||
|
||||
if (data.permission_overwrites) for (var _iterator = data.permission_overwrites, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
|
||||
var role = _ref;
|
||||
|
||||
this.roles.push(new ChannelPermissions(role, this));
|
||||
}
|
||||
|
||||
//this.isPrivate = isPrivate; //not sure about the implementation of this...
|
||||
}
|
||||
|
||||
_createClass(Channel, [{
|
||||
key: "equals",
|
||||
value: function equals(object) {
|
||||
return object && object.id === this.id;
|
||||
}
|
||||
}, {
|
||||
key: "addMessage",
|
||||
value: function addMessage(data) {
|
||||
if (!this.getMessage("id", data.id)) {
|
||||
this.messages.push(data);
|
||||
}
|
||||
return this.getMessage("id", data.id);
|
||||
}
|
||||
}, {
|
||||
key: "getMessage",
|
||||
value: function getMessage(key, value) {
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
Channel.prototype.permissionsOf = function permissionsOf(member) {
|
||||
|
||||
try {
|
||||
for (var _iterator = this.messages[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var message = _step.value;
|
||||
|
||||
if (message[key] === value) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator["return"]) {
|
||||
_iterator["return"]();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
}
|
||||
var mem = this.server.getMember("id", member.id);
|
||||
|
||||
if (mem) {
|
||||
return mem.permissionsIn(this);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
Channel.prototype.equals = function equals(object) {
|
||||
return object && object.id === this.id;
|
||||
};
|
||||
|
||||
Channel.prototype.addMessage = function addMessage(data) {
|
||||
|
||||
if (this.messages.length > 1000) {
|
||||
this.messages.splice(0, 1);
|
||||
}
|
||||
|
||||
if (!this.getMessage("id", data.id)) {
|
||||
this.messages.push(data);
|
||||
}
|
||||
|
||||
return this.getMessage("id", data.id);
|
||||
};
|
||||
|
||||
Channel.prototype.getMessage = function getMessage(key, value) {
|
||||
for (var _iterator2 = this.messages, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
|
||||
var _ref2;
|
||||
|
||||
if (_isArray2) {
|
||||
if (_i2 >= _iterator2.length) break;
|
||||
_ref2 = _iterator2[_i2++];
|
||||
} else {
|
||||
_i2 = _iterator2.next();
|
||||
if (_i2.done) break;
|
||||
_ref2 = _i2.value;
|
||||
}
|
||||
|
||||
var message = _ref2;
|
||||
|
||||
if (message[key] === value) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
Channel.prototype.toString = function toString() {
|
||||
return "<#" + this.id + ">";
|
||||
};
|
||||
|
||||
_createClass(Channel, [{
|
||||
key: "permissionOverwrites",
|
||||
get: function get() {
|
||||
return this.roles;
|
||||
}
|
||||
}, {
|
||||
key: "toString",
|
||||
value: function toString() {
|
||||
return "#" + this.name;
|
||||
key: "permissions",
|
||||
get: function get() {
|
||||
return this.roles;
|
||||
}
|
||||
}, {
|
||||
key: "client",
|
||||
get: function get() {
|
||||
return this.server.client;
|
||||
}
|
||||
}, {
|
||||
key: "isPrivate",
|
||||
get: function get() {
|
||||
return false;
|
||||
}
|
||||
}, {
|
||||
key: "users",
|
||||
get: function get() {
|
||||
return this.server.members;
|
||||
}
|
||||
}, {
|
||||
key: "members",
|
||||
get: function get() {
|
||||
return this.server.members;
|
||||
}
|
||||
}]);
|
||||
|
||||
return Channel;
|
||||
|
||||
24
lib/index.js
24
lib/index.js
@@ -9,4 +9,28 @@ var Discord = {
|
||||
Client: Client
|
||||
};
|
||||
|
||||
Discord.patchStrings = function () {
|
||||
|
||||
defineProperty("bold", "**");
|
||||
defineProperty("underline", "__");
|
||||
defineProperty("strike", "~~");
|
||||
defineProperty("code", "`");
|
||||
defineProperty("codeblock", "```");
|
||||
defineProperty("newline", "\n");
|
||||
|
||||
Object.defineProperty(String.prototype, "italic", {
|
||||
get: function get() {
|
||||
return "*" + this + "*";
|
||||
}
|
||||
});
|
||||
|
||||
function defineProperty(name, joiner) {
|
||||
Object.defineProperty(String.prototype, name, {
|
||||
get: function get() {
|
||||
return joiner + this + joiner;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Discord;
|
||||
@@ -4,6 +4,8 @@ var _createClass = (function () { function defineProperties(target, props) { for
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var PMChannel = require("./PMChannel.js");
|
||||
|
||||
var Message = (function () {
|
||||
function Message(data, channel, mentions, author) {
|
||||
_classCallCheck(this, Message);
|
||||
@@ -18,7 +20,13 @@ var Message = (function () {
|
||||
this.editedTimestamp = data.edited_timestamp;
|
||||
this.content = data.content.trim();
|
||||
this.channel = channel;
|
||||
this.author = author;
|
||||
|
||||
if (this.isPrivate) {
|
||||
this.author = this.channel.client.getUser("id", author.id);
|
||||
} else {
|
||||
this.author = this.channel.server.getMember("id", author.id) || this.channel.client.getUser("id", author.id);
|
||||
}
|
||||
|
||||
this.attachments = data.attachments;
|
||||
}
|
||||
|
||||
@@ -26,44 +34,39 @@ var Message = (function () {
|
||||
return ( this.channel instanceof PMChannel );
|
||||
}*/
|
||||
|
||||
_createClass(Message, [{
|
||||
key: "isMentioned",
|
||||
value: function isMentioned(user) {
|
||||
var id = user.id ? user.id : user;
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
Message.prototype.isMentioned = function isMentioned(user) {
|
||||
var id = user.id ? user.id : user;
|
||||
for (var _iterator = this.mentions, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
|
||||
try {
|
||||
for (var _iterator = this.mentions[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var mention = _step.value;
|
||||
|
||||
if (mention.id === id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator["return"]) {
|
||||
_iterator["return"]();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
|
||||
return false;
|
||||
var mention = _ref;
|
||||
|
||||
if (mention.id === id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
return false;
|
||||
};
|
||||
|
||||
_createClass(Message, [{
|
||||
key: "sender",
|
||||
get: function get() {
|
||||
return this.author;
|
||||
}
|
||||
}, {
|
||||
key: "isPrivate",
|
||||
get: function get() {
|
||||
return this.channel.isPrivate;
|
||||
}
|
||||
}]);
|
||||
|
||||
return Message;
|
||||
|
||||
322
lib/server.js
322
lib/server.js
@@ -4,6 +4,9 @@ var _createClass = (function () { function defineProperties(target, props) { for
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var ServerPermissions = require("./ServerPermissions.js");
|
||||
var Member = require("./Member.js");
|
||||
|
||||
var Server = (function () {
|
||||
function Server(data, client) {
|
||||
_classCallCheck(this, Server);
|
||||
@@ -19,128 +22,224 @@ var Server = (function () {
|
||||
this.afkTimeout = data.afk_timeout;
|
||||
this.afkChannelId = data.afk_channel_id;
|
||||
|
||||
this.roles = [];
|
||||
|
||||
for (var _iterator = data.roles, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
|
||||
var _ref;
|
||||
|
||||
if (_isArray) {
|
||||
if (_i >= _iterator.length) break;
|
||||
_ref = _iterator[_i++];
|
||||
} else {
|
||||
_i = _iterator.next();
|
||||
if (_i.done) break;
|
||||
_ref = _i.value;
|
||||
}
|
||||
|
||||
var permissionGroup = _ref;
|
||||
|
||||
this.roles.push(new ServerPermissions(permissionGroup));
|
||||
}
|
||||
|
||||
if (!data.members) {
|
||||
data.members = [client.user];
|
||||
return;
|
||||
}
|
||||
|
||||
var _iteratorNormalCompletion = true;
|
||||
var _didIteratorError = false;
|
||||
var _iteratorError = undefined;
|
||||
for (var _iterator2 = data.members, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
|
||||
var _ref2;
|
||||
|
||||
try {
|
||||
for (var _iterator = data.members[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||
var member = _step.value;
|
||||
if (_isArray2) {
|
||||
if (_i2 >= _iterator2.length) break;
|
||||
_ref2 = _iterator2[_i2++];
|
||||
} else {
|
||||
_i2 = _iterator2.next();
|
||||
if (_i2.done) break;
|
||||
_ref2 = _i2.value;
|
||||
}
|
||||
|
||||
// first we cache the user in our Discord Client,
|
||||
// then we add it to our list. This way when we
|
||||
// get a user from this server's member list,
|
||||
// it will be identical (unless an async change occurred)
|
||||
// to the client's cache.
|
||||
if (member.user) this.members.push(client.addUser(member.user));
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError = true;
|
||||
_iteratorError = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion && _iterator["return"]) {
|
||||
_iterator["return"]();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError) {
|
||||
throw _iteratorError;
|
||||
}
|
||||
}
|
||||
var member = _ref2;
|
||||
|
||||
// first we cache the user in our Discord Client,
|
||||
// then we add it to our list. This way when we
|
||||
// get a user from this server's member list,
|
||||
// it will be identical (unless an async change occurred)
|
||||
// to the client's cache.
|
||||
if (member.user) this.addMember(client.addUser(member.user), member.roles);
|
||||
}
|
||||
}
|
||||
|
||||
// get/set
|
||||
|
||||
Server.prototype.getRole = function getRole(id) {
|
||||
for (var _iterator3 = this.roles, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
|
||||
var _ref3;
|
||||
|
||||
if (_isArray3) {
|
||||
if (_i3 >= _iterator3.length) break;
|
||||
_ref3 = _iterator3[_i3++];
|
||||
} else {
|
||||
_i3 = _iterator3.next();
|
||||
if (_i3.done) break;
|
||||
_ref3 = _i3.value;
|
||||
}
|
||||
|
||||
var role = _ref3;
|
||||
|
||||
if (role.id === id) {
|
||||
return role;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Server.prototype.updateRole = function updateRole(data) {
|
||||
|
||||
var oldRole = this.getRole(data.id);
|
||||
|
||||
if (oldRole) {
|
||||
|
||||
var index = this.roles.indexOf(oldRole);
|
||||
this.roles[index] = new ServerPermissions(data);
|
||||
|
||||
return this.roles[index];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Server.prototype.removeRole = function removeRole(id) {
|
||||
for (var roleId in this.roles) {
|
||||
if (this.roles[roleId].id === id) {
|
||||
this.roles.splice(roleId, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (var _iterator4 = this.members, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
|
||||
var _ref4;
|
||||
|
||||
if (_isArray4) {
|
||||
if (_i4 >= _iterator4.length) break;
|
||||
_ref4 = _iterator4[_i4++];
|
||||
} else {
|
||||
_i4 = _iterator4.next();
|
||||
if (_i4.done) break;
|
||||
_ref4 = _i4.value;
|
||||
}
|
||||
|
||||
var member = _ref4;
|
||||
|
||||
for (var roleId in member.rawRoles) {
|
||||
if (member.rawRoles[roleId] === id) {
|
||||
member.rawRoles.splice(roleId, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Server.prototype.getChannel = function getChannel(key, value) {
|
||||
for (var _iterator5 = this.channels, _isArray5 = Array.isArray(_iterator5), _i5 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
|
||||
var _ref5;
|
||||
|
||||
if (_isArray5) {
|
||||
if (_i5 >= _iterator5.length) break;
|
||||
_ref5 = _iterator5[_i5++];
|
||||
} else {
|
||||
_i5 = _iterator5.next();
|
||||
if (_i5.done) break;
|
||||
_ref5 = _i5.value;
|
||||
}
|
||||
|
||||
var channel = _ref5;
|
||||
|
||||
if (channel[key] === value) {
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Server.prototype.getMember = function getMember(key, value) {
|
||||
for (var _iterator6 = this.members, _isArray6 = Array.isArray(_iterator6), _i6 = 0, _iterator6 = _isArray6 ? _iterator6 : _iterator6[Symbol.iterator]();;) {
|
||||
var _ref6;
|
||||
|
||||
if (_isArray6) {
|
||||
if (_i6 >= _iterator6.length) break;
|
||||
_ref6 = _iterator6[_i6++];
|
||||
} else {
|
||||
_i6 = _iterator6.next();
|
||||
if (_i6.done) break;
|
||||
_ref6 = _i6.value;
|
||||
}
|
||||
|
||||
var member = _ref6;
|
||||
|
||||
if (member[key] === value) {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Server.prototype.removeMember = function removeMember(key, value) {
|
||||
for (var _iterator7 = this.members, _isArray7 = Array.isArray(_iterator7), _i7 = 0, _iterator7 = _isArray7 ? _iterator7 : _iterator7[Symbol.iterator]();;) {
|
||||
var _ref7;
|
||||
|
||||
if (_isArray7) {
|
||||
if (_i7 >= _iterator7.length) break;
|
||||
_ref7 = _iterator7[_i7++];
|
||||
} else {
|
||||
_i7 = _iterator7.next();
|
||||
if (_i7.done) break;
|
||||
_ref7 = _i7.value;
|
||||
}
|
||||
|
||||
var member = _ref7;
|
||||
|
||||
if (member[key] === value) {
|
||||
this.members.splice(key, 1);
|
||||
return member;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
Server.prototype.addChannel = function addChannel(chann) {
|
||||
if (!this.getChannel("id", chann.id)) {
|
||||
this.channels.push(chann);
|
||||
}
|
||||
return chann;
|
||||
};
|
||||
|
||||
Server.prototype.addMember = function addMember(user, roles) {
|
||||
if (!this.getMember("id", user.id)) {
|
||||
var mem = new Member(user, this, roles);
|
||||
this.members.push(mem);
|
||||
}
|
||||
return mem;
|
||||
};
|
||||
|
||||
Server.prototype.toString = function toString() {
|
||||
return this.name;
|
||||
};
|
||||
|
||||
Server.prototype.equals = function equals(object) {
|
||||
return object.id === this.id;
|
||||
};
|
||||
|
||||
_createClass(Server, [{
|
||||
key: "getChannel",
|
||||
|
||||
// get/set
|
||||
value: function getChannel(key, value) {
|
||||
var _iteratorNormalCompletion2 = true;
|
||||
var _didIteratorError2 = false;
|
||||
var _iteratorError2 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator2 = this.channels[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
||||
var channel = _step2.value;
|
||||
|
||||
if (channel[key] === value) {
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError2 = true;
|
||||
_iteratorError2 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion2 && _iterator2["return"]) {
|
||||
_iterator2["return"]();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError2) {
|
||||
throw _iteratorError2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
key: "permissionGroups",
|
||||
get: function get() {
|
||||
return this.roles;
|
||||
}
|
||||
}, {
|
||||
key: "getMember",
|
||||
value: function getMember(key, value) {
|
||||
var _iteratorNormalCompletion3 = true;
|
||||
var _didIteratorError3 = false;
|
||||
var _iteratorError3 = undefined;
|
||||
|
||||
try {
|
||||
for (var _iterator3 = this.members[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
|
||||
var member = _step3.value;
|
||||
|
||||
if (member[key] === value) {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
_didIteratorError3 = true;
|
||||
_iteratorError3 = err;
|
||||
} finally {
|
||||
try {
|
||||
if (!_iteratorNormalCompletion3 && _iterator3["return"]) {
|
||||
_iterator3["return"]();
|
||||
}
|
||||
} finally {
|
||||
if (_didIteratorError3) {
|
||||
throw _iteratorError3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}, {
|
||||
key: "addChannel",
|
||||
value: function addChannel(chann) {
|
||||
if (!this.getChannel("id", chann.id)) {
|
||||
this.channels.push(chann);
|
||||
}
|
||||
return chann;
|
||||
}
|
||||
}, {
|
||||
key: "addMember",
|
||||
value: function addMember(member) {
|
||||
if (!this.getMember("id", member.id)) {
|
||||
this.members.push(member);
|
||||
}
|
||||
return member;
|
||||
}
|
||||
}, {
|
||||
key: "toString",
|
||||
value: function toString() {
|
||||
return this.name;
|
||||
key: "permissions",
|
||||
get: function get() {
|
||||
return this.roles;
|
||||
}
|
||||
}, {
|
||||
key: "iconURL",
|
||||
@@ -165,6 +264,11 @@ var Server = (function () {
|
||||
get: function get() {
|
||||
return this.client.getUser("id", this.ownerID);
|
||||
}
|
||||
}, {
|
||||
key: "users",
|
||||
get: function get() {
|
||||
return this.members;
|
||||
}
|
||||
}]);
|
||||
|
||||
return Server;
|
||||
|
||||
50
lib/user.js
50
lib/user.js
@@ -12,37 +12,35 @@ var User = (function () {
|
||||
this.discriminator = data.discriminator;
|
||||
this.id = data.id;
|
||||
this.avatar = data.avatar;
|
||||
this.status = data.status || "offline";
|
||||
this.gameId = data.game_id || null;
|
||||
}
|
||||
|
||||
// access using user.avatarURL;
|
||||
|
||||
User.prototype.mention = function mention() {
|
||||
return "<@" + this.id + ">";
|
||||
};
|
||||
|
||||
User.prototype.toString = function toString() {
|
||||
/*
|
||||
if we embed a user in a String - like so:
|
||||
"Yo " + user + " what's up?"
|
||||
It would generate something along the lines of:
|
||||
"Yo @hydrabolt what's up?"
|
||||
*/
|
||||
return this.mention();
|
||||
};
|
||||
|
||||
User.prototype.equals = function equals(object) {
|
||||
return object.id === this.id;
|
||||
};
|
||||
|
||||
User.prototype.equalsStrict = function equalsStrict(object) {
|
||||
return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
|
||||
};
|
||||
|
||||
_createClass(User, [{
|
||||
key: "mention",
|
||||
value: function mention() {
|
||||
return "<@" + this.id + ">";
|
||||
}
|
||||
}, {
|
||||
key: "toString",
|
||||
value: function toString() {
|
||||
/*
|
||||
if we embed a user in a String - like so:
|
||||
"Yo " + user + " what's up?"
|
||||
It would generate something along the lines of:
|
||||
"Yo @hydrabolt what's up?"
|
||||
*/
|
||||
return this.mention();
|
||||
}
|
||||
}, {
|
||||
key: "equals",
|
||||
value: function equals(object) {
|
||||
return object.id === this.id;
|
||||
}
|
||||
}, {
|
||||
key: "equalsStrict",
|
||||
value: function equalsStrict(object) {
|
||||
return object.id === this.id && object.avatar === this.avatar && object.username === this.username && object.discriminator === this.discriminator;
|
||||
}
|
||||
}, {
|
||||
key: "avatarURL",
|
||||
get: function get() {
|
||||
if (!this.avatar) return null;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "discord.js",
|
||||
"version": "3.1.5",
|
||||
"version": "3.9.1",
|
||||
"description": "A way to interface with the Discord API",
|
||||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
|
||||
1
ref/gameMap.json
Normal file
1
ref/gameMap.json
Normal file
File diff suppressed because one or more lines are too long
87
src/ChannelPermissions.js
Normal file
87
src/ChannelPermissions.js
Normal file
@@ -0,0 +1,87 @@
|
||||
class ChannelPermissions{
|
||||
constructor(data, channel){
|
||||
|
||||
var self = this;
|
||||
|
||||
function getBit(x) {
|
||||
return ((self.packed >>> x) & 1) === 1;
|
||||
}
|
||||
|
||||
this.type = data.type; //either member or role
|
||||
this.id = data.id;
|
||||
|
||||
if(this.type === "member"){
|
||||
this.packed = channel.server.getMember("id", data.id).evalPerms.packed;
|
||||
}else{
|
||||
this.packed = channel.server.getRole(data.id).packed;
|
||||
}
|
||||
|
||||
this.packed = this.packed & ~data.deny;
|
||||
this.packed = this.packed | data.allow;
|
||||
|
||||
this.deny = data.deny;
|
||||
this.allow = data.allow;
|
||||
|
||||
}
|
||||
|
||||
get createInstantInvite(){return this.getBit(0);}
|
||||
set createInstantInvite(val){this.setBit(0, val);}
|
||||
|
||||
get manageRoles(){return this.getBit(3);}
|
||||
set manageRoles(val){this.setBit(3, val);}
|
||||
|
||||
get manageChannels(){return this.getBit(4);}
|
||||
set manageChannels(val){this.setBit(4, val);}
|
||||
|
||||
get readMessages(){return this.getBit(10);}
|
||||
set readMessages(val){this.setBit(10, val);}
|
||||
|
||||
get sendMessages(){return this.getBit(11);}
|
||||
set sendMessages(val){this.setBit(11, val);}
|
||||
|
||||
get sendTTSMessages(){return this.getBit(12);}
|
||||
set sendTTSMessages(val){this.setBit(12, val);}
|
||||
|
||||
get manageMessages(){return this.getBit(13);}
|
||||
set manageMessages(val){this.setBit(13, val);}
|
||||
|
||||
get embedLinks(){return this.getBit(14);}
|
||||
set embedLinks(val){this.setBit(14, val);}
|
||||
|
||||
get attachFiles(){return this.getBit(15);}
|
||||
set attachFiles(val){this.setBit(15, val);}
|
||||
|
||||
get readMessageHistory(){return this.getBit(16);}
|
||||
set readMessageHistory(val){this.setBit(16, val);}
|
||||
|
||||
get mentionEveryone(){return this.getBit(17);}
|
||||
set mentionEveryone(val){this.setBit(17, val);}
|
||||
|
||||
get voiceConnect(){return this.getBit(20);}
|
||||
set voiceConnect(val){this.setBit(20, val);}
|
||||
|
||||
get voiceSpeak(){return this.getBit(21);}
|
||||
set voiceSpeak(val){this.setBit(21, val);}
|
||||
|
||||
get voiceMuteMembers(){return this.getBit(22);}
|
||||
set voiceMuteMembers(val){this.setBit(22, val);}
|
||||
|
||||
get voiceDeafenMembers(){return this.getBit(23);}
|
||||
set voiceDeafenMembers(val){this.setBit(23, val);}
|
||||
|
||||
get voiceMoveMembers(){return this.getBit(24);}
|
||||
set voiceMoveMembers(val){this.setBit(24, val);}
|
||||
|
||||
get voiceUseVoiceActivation(){return this.getBit(25);}
|
||||
set voiceUseVoiceActivation(val){this.setBit(25, val);}
|
||||
|
||||
getBit(x) {
|
||||
return ((this.packed >>> x) & 1) === 1;
|
||||
}
|
||||
|
||||
setBit() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChannelPermissions;
|
||||
612
src/Client.js
612
src/Client.js
@@ -7,6 +7,8 @@ var Message = require("./message.js");
|
||||
var Invite = require("./invite.js");
|
||||
var PMChannel = require("./PMChannel.js");
|
||||
|
||||
var gameMap = require("../ref/gameMap.json");
|
||||
|
||||
//node modules
|
||||
var request = require("superagent");
|
||||
var WebSocket = require("ws");
|
||||
@@ -29,11 +31,11 @@ class Client {
|
||||
this.token = token;
|
||||
this.state = 0;
|
||||
this.websocket = null;
|
||||
this.events = new Map();
|
||||
this.events = {};
|
||||
this.user = null;
|
||||
this.alreadySentData = false;
|
||||
this.serverCreateListener = new Map();
|
||||
|
||||
this.serverCreateListener = {};
|
||||
this.typingIntervals = {};
|
||||
this.email = "abc";
|
||||
this.password = "abc";
|
||||
|
||||
@@ -52,7 +54,11 @@ class Client {
|
||||
this.pmChannelCache = [];
|
||||
this.readyTime = null;
|
||||
this.checkingQueue = {};
|
||||
this.userTypingListener = {};
|
||||
this.queue = {};
|
||||
|
||||
this.__idleTime = null;
|
||||
this.__gameId = null;
|
||||
}
|
||||
|
||||
get uptime() {
|
||||
@@ -103,11 +109,11 @@ class Client {
|
||||
}
|
||||
|
||||
on(event, fn) {
|
||||
this.events.set(event, fn);
|
||||
this.events[event] = fn;
|
||||
}
|
||||
|
||||
off(event, fn) {
|
||||
this.events.delete(event);
|
||||
off(event) {
|
||||
this.events[event] = null;
|
||||
}
|
||||
|
||||
keepAlive() {
|
||||
@@ -124,7 +130,7 @@ class Client {
|
||||
for (var arg in arguments) {
|
||||
args.push(arguments[arg]);
|
||||
}
|
||||
var evt = this.events.get(event);
|
||||
var evt = this.events[event];
|
||||
if (evt) {
|
||||
evt.apply(this, args.slice(1));
|
||||
}
|
||||
@@ -153,14 +159,16 @@ class Client {
|
||||
if (err) {
|
||||
self.state = 4; //set state to disconnected
|
||||
self.trigger("disconnected");
|
||||
self.websocket.close();
|
||||
if (self.websocket) {
|
||||
self.websocket.close();
|
||||
}
|
||||
callback(err);
|
||||
reject(err);
|
||||
} else {
|
||||
self.state = 2; //set state to logged in (not yet ready)
|
||||
self.token = res.body.token; //set our token
|
||||
|
||||
getGateway().then(function (url) {
|
||||
self.getGateway().then(function (url) {
|
||||
self.createws(url);
|
||||
callback(null, self.token);
|
||||
resolve(self.token);
|
||||
@@ -225,7 +233,7 @@ class Client {
|
||||
// potentially redundant in future
|
||||
// creating here does NOT give us the channels of the server
|
||||
// so we must wait for the guild_create event.
|
||||
self.serverCreateListener.set(res.body.id, [resolve, callback]);
|
||||
self.serverCreateListener[res.body.id] = [resolve, callback];
|
||||
/*var srv = self.addServer(res.body);
|
||||
callback(null, srv);
|
||||
resolve(srv);*/
|
||||
@@ -359,14 +367,20 @@ class Client {
|
||||
|
||||
}
|
||||
|
||||
reply(destination, message, callback = function (err, msg) { }) {
|
||||
reply(destination, message, tts, callback = function (err, msg) { }) {
|
||||
|
||||
var self = this;
|
||||
|
||||
return new Promise(function (response, reject) {
|
||||
|
||||
if (typeof tts === "function") {
|
||||
// tts is a function, which means the developer wants this to be the callback
|
||||
callback = tts;
|
||||
tts = false;
|
||||
}
|
||||
|
||||
var user = destination.sender;
|
||||
self.sendMessage(destination, message, callback, user + ", ").then(response).catch(reject);
|
||||
self.sendMessage(destination, message, tts, callback, user + ", ").then(response).catch(reject);
|
||||
|
||||
});
|
||||
|
||||
@@ -375,8 +389,8 @@ class Client {
|
||||
deleteMessage(message, timeout, callback = function (err, msg) { }) {
|
||||
|
||||
var self = this;
|
||||
|
||||
var prom = new Promise(function (resolve, reject) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (timeout) {
|
||||
setTimeout(remove, timeout)
|
||||
} else {
|
||||
@@ -384,37 +398,29 @@ class Client {
|
||||
}
|
||||
|
||||
function remove() {
|
||||
if(self.options.queue){
|
||||
if (!self.queue[message.channel.id]) {
|
||||
self.queue[message.channel.id] = [];
|
||||
}
|
||||
self.queue[message.channel.id].push({
|
||||
action: "deleteMessage",
|
||||
message: message,
|
||||
then: good,
|
||||
error: bad
|
||||
request
|
||||
.del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`)
|
||||
.set("authorization", self.token)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
bad();
|
||||
} else {
|
||||
good();
|
||||
}
|
||||
});
|
||||
|
||||
self.checkQueue(message.channel.id);
|
||||
}else{
|
||||
self._deleteMessage(message).then(good).catch(bad);
|
||||
}
|
||||
}
|
||||
|
||||
function good(){
|
||||
prom.success = true;
|
||||
callback(null);
|
||||
|
||||
function good() {
|
||||
callback();
|
||||
resolve();
|
||||
}
|
||||
|
||||
function bad(err){
|
||||
prom.error = err;
|
||||
|
||||
function bad(err) {
|
||||
callback(err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
|
||||
return prom;
|
||||
|
||||
}
|
||||
|
||||
updateMessage(message, content, callback = function (err, msg) { }) {
|
||||
@@ -425,7 +431,7 @@ class Client {
|
||||
|
||||
content = (content instanceof Array ? content.join("\n") : content);
|
||||
|
||||
if(self.options.queue){
|
||||
if (self.options.queue) {
|
||||
if (!self.queue[message.channel.id]) {
|
||||
self.queue[message.channel.id] = [];
|
||||
}
|
||||
@@ -436,26 +442,26 @@ class Client {
|
||||
then: good,
|
||||
error: bad
|
||||
});
|
||||
|
||||
|
||||
self.checkQueue(message.channel.id);
|
||||
}else{
|
||||
} else {
|
||||
self._updateMessage(message, content).then(good).catch(bad);
|
||||
}
|
||||
|
||||
function good(msg){
|
||||
prom.message = msg;
|
||||
callback(null, msg);
|
||||
resolve(msg);
|
||||
}
|
||||
|
||||
function bad(error){
|
||||
prom.error = error;
|
||||
callback(error);
|
||||
reject(error);
|
||||
}
|
||||
|
||||
function good(msg) {
|
||||
prom.message = msg;
|
||||
callback(null, msg);
|
||||
resolve(msg);
|
||||
}
|
||||
|
||||
function bad(error) {
|
||||
prom.error = error;
|
||||
callback(error);
|
||||
reject(error);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
return prom;
|
||||
}
|
||||
|
||||
@@ -576,7 +582,7 @@ class Client {
|
||||
if (self.getServer("id", res.body.guild.id)) {
|
||||
resolve(self.getServer("id", res.body.guild.id));
|
||||
} else {
|
||||
self.serverCreateListener.set(res.body.guild.id, [resolve, callback]);
|
||||
self.serverCreateListener[res.body.guild.id] = [resolve, callback];
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -585,6 +591,38 @@ class Client {
|
||||
|
||||
}
|
||||
|
||||
setAvatar(resource, callback = function (err) { }) {
|
||||
|
||||
var self = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (resource instanceof Buffer) {
|
||||
resource = resource.toString("base64");
|
||||
resource = "data:image/jpg;base64," + resource;
|
||||
}
|
||||
|
||||
request
|
||||
.patch(`${Endpoints.API}/users/@me`)
|
||||
.set("authorization", self.token)
|
||||
.send({
|
||||
avatar: resource,
|
||||
email: self.email,
|
||||
new_password: null,
|
||||
password: self.password,
|
||||
username: self.user.username
|
||||
})
|
||||
.end(function (err) {
|
||||
callback(err);
|
||||
if (err)
|
||||
reject(err);
|
||||
else
|
||||
resolve();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
sendFile(destination, file, fileName = "image.png", callback = function (err, msg) { }) {
|
||||
|
||||
var self = this;
|
||||
@@ -603,7 +641,7 @@ class Client {
|
||||
self.resolveDestination(destination).then(send).catch(bad);
|
||||
|
||||
function send(destination) {
|
||||
if(self.options.queue){
|
||||
if (self.options.queue) {
|
||||
//queue send file too
|
||||
if (!self.queue[destination]) {
|
||||
self.queue[destination] = [];
|
||||
@@ -611,14 +649,14 @@ class Client {
|
||||
|
||||
self.queue[destination].push({
|
||||
action: "sendFile",
|
||||
attachment : fstream,
|
||||
attachmentName : fileName,
|
||||
attachment: fstream,
|
||||
attachmentName: fileName,
|
||||
then: good,
|
||||
error: bad
|
||||
});
|
||||
|
||||
self.checkQueue(destination);
|
||||
}else{
|
||||
} else {
|
||||
//not queue
|
||||
self._sendFile(destination, fstream, fileName).then(good).catch(bad);
|
||||
}
|
||||
@@ -637,17 +675,23 @@ class Client {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
return prom;
|
||||
|
||||
}
|
||||
|
||||
sendMessage(destination, message, callback = function (err, msg) { }, premessage = "") {
|
||||
sendMessage(destination, message, tts, callback = function (err, msg) { }, premessage = "") {
|
||||
|
||||
var self = this;
|
||||
|
||||
var prom = new Promise(function (resolve, reject) {
|
||||
|
||||
if (typeof tts === "function") {
|
||||
// tts is a function, which means the developer wants this to be the callback
|
||||
callback = tts;
|
||||
tts = false;
|
||||
}
|
||||
|
||||
message = premessage + resolveMessage(message);
|
||||
var mentions = resolveMentions();
|
||||
self.resolveDestination(destination).then(send).catch(error);
|
||||
@@ -668,13 +712,14 @@ class Client {
|
||||
action: "sendMessage",
|
||||
content: message,
|
||||
mentions: mentions,
|
||||
tts: !!tts, //incase it's not a boolean
|
||||
then: mgood,
|
||||
error: mbad
|
||||
});
|
||||
|
||||
self.checkQueue(destination);
|
||||
} else {
|
||||
self._sendMessage(destination, message, mentions).then(mgood).catch(mbad);
|
||||
self._sendMessage(destination, message, tts, mentions).then(mgood).catch(mbad);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -708,7 +753,7 @@ class Client {
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
return prom;
|
||||
}
|
||||
|
||||
@@ -744,6 +789,8 @@ class Client {
|
||||
self.trigger("error", err, e);
|
||||
return;
|
||||
}
|
||||
|
||||
self.trigger("raw", dat);
|
||||
|
||||
//valid message
|
||||
switch (dat.t) {
|
||||
@@ -888,11 +935,11 @@ class Client {
|
||||
|
||||
}*/
|
||||
|
||||
if (self.serverCreateListener.get(data.id)) {
|
||||
var cbs = self.serverCreateListener.get(data.id);
|
||||
if (self.serverCreateListener[data.id]) {
|
||||
var cbs = self.serverCreateListener[data.id];
|
||||
cbs[0](server); //promise then callback
|
||||
cbs[1](null, server); //legacy callback
|
||||
self.serverCreateListener.delete(data.id);
|
||||
self.serverCreateListener[data.id] = null;
|
||||
}
|
||||
|
||||
self.trigger("serverCreate", server);
|
||||
@@ -905,7 +952,12 @@ class Client {
|
||||
|
||||
if (!channel) {
|
||||
|
||||
var chann = self.addChannel(data, data.guild_id);
|
||||
var chann;
|
||||
if (data.is_private) {
|
||||
chann = self.addPMChannel(data);
|
||||
} else {
|
||||
chann = self.addChannel(data, data.guild_id);
|
||||
}
|
||||
var srv = self.getServer("id", data.guild_id);
|
||||
if (srv) {
|
||||
srv.addChannel(chann);
|
||||
@@ -923,12 +975,8 @@ class Client {
|
||||
if (server) {
|
||||
|
||||
var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
|
||||
|
||||
if (!~server.members.indexOf(user)) {
|
||||
server.members.push(user);
|
||||
}
|
||||
|
||||
self.trigger("serverNewMember", user);
|
||||
self.trigger("serverNewMember", server.addMember(user, data.roles), server);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -941,11 +989,9 @@ class Client {
|
||||
|
||||
var user = self.addUser(data.user); //if for whatever reason it doesn't exist..
|
||||
|
||||
if (~server.members.indexOf(user)) {
|
||||
server.members.splice(server.members.indexOf(user), 1);
|
||||
}
|
||||
server.removeMember("id", user.id);
|
||||
|
||||
self.trigger("serverRemoveMember", user);
|
||||
self.trigger("serverRemoveMember", user, server);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -974,24 +1020,95 @@ class Client {
|
||||
|
||||
if (userInCache) {
|
||||
//user exists
|
||||
|
||||
data.user.username = data.user.username || userInCache.username;
|
||||
data.user.id = data.user.id || userInCache.id;
|
||||
data.user.discriminator = data.user.discriminator || userInCache.discriminator;
|
||||
data.user.avatar = data.user.avatar || userInCache.avatar;
|
||||
|
||||
var presenceUser = new User(data.user);
|
||||
if (presenceUser.equalsStrict(userInCache)) {
|
||||
//they're exactly the same, an actual presence update
|
||||
self.trigger("presence", {
|
||||
user: userInCache,
|
||||
oldStatus: userInCache.status,
|
||||
status: data.status,
|
||||
server: self.getServer("id", data.guild_id),
|
||||
gameId: data.game_id
|
||||
});
|
||||
userInCache.status = data.status;
|
||||
userInCache.gameId = data.game_id;
|
||||
} else {
|
||||
//one of their details changed.
|
||||
self.trigger("userUpdate", userInCache, presenceUser);
|
||||
self.userCache[self.userCache.indexOf(userInCache)] = presenceUser;
|
||||
self.trigger("userUpdate", userInCache, presenceUser);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "CHANNEL_UPDATE":
|
||||
|
||||
var channelInCache = self.getChannel("id", data.id),
|
||||
serverInCache = self.getServer("id", data.guild_id);
|
||||
|
||||
if (channelInCache && serverInCache) {
|
||||
|
||||
var newChann = new Channel(data, serverInCache);
|
||||
newChann.messages = channelInCache.messages;
|
||||
|
||||
self.trigger("channelUpdate", channelInCache, newChann);
|
||||
|
||||
self.channelCache[self.channelCache.indexOf(channelInCache)] = newChann;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "TYPING_START":
|
||||
|
||||
var userInCache = self.getUser("id", data.user_id);
|
||||
var channelInCache = self.getChannel("id", data.channel_id);
|
||||
|
||||
if (!self.userTypingListener[data.user_id] || self.userTypingListener[data.user_id] === -1) {
|
||||
self.trigger("startTyping", userInCache, channelInCache);
|
||||
}
|
||||
|
||||
self.userTypingListener[data.user_id] = Date.now();
|
||||
|
||||
setTimeout(function () {
|
||||
if (self.userTypingListener[data.user_id] === -1) {
|
||||
return;
|
||||
}
|
||||
if (Date.now() - self.userTypingListener[data.user_id] > 6000) {
|
||||
// stopped typing
|
||||
self.trigger("stopTyping", userInCache, channelInCache);
|
||||
self.userTypingListener[data.user_id] = -1;
|
||||
}
|
||||
}, 6000);
|
||||
|
||||
break;
|
||||
|
||||
case "GUILD_ROLE_DELETE":
|
||||
|
||||
var server = self.getServer("id", data.guild_id);
|
||||
var role = server.getRole(data.role_id);
|
||||
|
||||
self.trigger("serverRoleDelete", server, role);
|
||||
|
||||
server.removeRole(role.id);
|
||||
|
||||
break;
|
||||
|
||||
case "GUILD_ROLE_UPDATE":
|
||||
|
||||
var server = self.getServer("id", data.guild_id);
|
||||
var role = server.getRole(data.role.id);
|
||||
var newRole = server.updateRole(data.role);
|
||||
|
||||
self.trigger("serverRoleUpdate", server, role, newRole);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
self.debug("received unknown packet");
|
||||
self.trigger("unknown", dat);
|
||||
@@ -1025,12 +1142,59 @@ class Client {
|
||||
}
|
||||
return this.getPMChannel("id", data.id);
|
||||
}
|
||||
|
||||
setTopic(channel, topic, callback = function (err) { }) {
|
||||
|
||||
var self = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
self.resolveDestination(channel).then(next).catch(error);
|
||||
|
||||
function error(e) {
|
||||
callback(e);
|
||||
reject(e);
|
||||
}
|
||||
|
||||
function next(destination) {
|
||||
|
||||
var asChan = self.getChannel("id", destination);
|
||||
|
||||
request
|
||||
.patch(`${Endpoints.CHANNELS}/${destination}`)
|
||||
.set("authorization", self.token)
|
||||
.send({
|
||||
name: asChan.name,
|
||||
position: 0,
|
||||
topic: topic
|
||||
})
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
error(err);
|
||||
} else {
|
||||
asChan.topic = res.body.topic;
|
||||
resolve();
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//def addServer
|
||||
addServer(data) {
|
||||
|
||||
var self = this;
|
||||
var server = this.getServer("id", data.id);
|
||||
|
||||
if (data.unavailable) {
|
||||
self.trigger("unavailable", data);
|
||||
self.debug("Server ID " + data.id + " has been marked unavailable by Discord. It was not cached.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!server) {
|
||||
server = new Server(data, this);
|
||||
this.serverCache.push(server);
|
||||
@@ -1041,6 +1205,12 @@ class Client {
|
||||
}
|
||||
}
|
||||
|
||||
for (var presence of data.presences) {
|
||||
var user = self.getUser("id", presence.user.id);
|
||||
user.status = presence.status;
|
||||
user.gameId = presence.game_id;
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
@@ -1094,7 +1264,7 @@ class Client {
|
||||
op: 2,
|
||||
d: {
|
||||
token: this.token,
|
||||
v: 2,
|
||||
v: 3,
|
||||
properties: {
|
||||
"$os": "discord.js",
|
||||
"$browser": "discord.js",
|
||||
@@ -1129,12 +1299,15 @@ class Client {
|
||||
channId = destination.id;
|
||||
} else if (destination instanceof Message) {
|
||||
channId = destination.channel.id;
|
||||
} else if (destination instanceof PMChannel) {
|
||||
channId = destination.id;
|
||||
} else if (destination instanceof User) {
|
||||
|
||||
//check if we have a PM
|
||||
for (var pmc of self.pmChannelCache) {
|
||||
if (pmc.user.equals(destination)) {
|
||||
return pmc.id;
|
||||
if (pmc.user && pmc.user.equals(destination)) {
|
||||
resolve(pmc.id);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,10 +1321,12 @@ class Client {
|
||||
}
|
||||
if (channId)
|
||||
resolve(channId);
|
||||
else
|
||||
reject();
|
||||
});
|
||||
}
|
||||
|
||||
_sendMessage(destination, content, mentions) {
|
||||
_sendMessage(destination, content, tts, mentions) {
|
||||
|
||||
var self = this;
|
||||
|
||||
@@ -1161,7 +1336,8 @@ class Client {
|
||||
.set("authorization", self.token)
|
||||
.send({
|
||||
content: content,
|
||||
mentions: mentions
|
||||
mentions: mentions,
|
||||
tts: tts
|
||||
})
|
||||
.end(function (err, res) {
|
||||
|
||||
@@ -1189,39 +1365,39 @@ class Client {
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
_sendFile(destination, attachment, attachmentName = "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png"){
|
||||
|
||||
|
||||
_sendFile(destination, attachment, attachmentName = "DEFAULT BECAUSE YOU DIDN'T SPECIFY WHY.png") {
|
||||
|
||||
var self = this;
|
||||
|
||||
return new Promise(function(resolve, reject){
|
||||
request
|
||||
.post(`${Endpoints.CHANNELS}/${destination}/messages`)
|
||||
.set("authorization", self.token)
|
||||
.attach("file", attachment, attachmentName)
|
||||
.end(function (err, res) {
|
||||
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
|
||||
var chann = self.getChannel("id", destination);
|
||||
if (chann) {
|
||||
var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
|
||||
resolve(msg);
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
request
|
||||
.post(`${Endpoints.CHANNELS}/${destination}/messages`)
|
||||
.set("authorization", self.token)
|
||||
.attach("file", attachment, attachmentName)
|
||||
.end(function (err, res) {
|
||||
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
|
||||
var chann = self.getChannel("id", destination);
|
||||
if (chann) {
|
||||
var msg = chann.addMessage(new Message(res.body, chann, [], self.user));
|
||||
resolve(msg);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
_updateMessage(message, content){
|
||||
|
||||
_updateMessage(message, content) {
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject){
|
||||
return new Promise(function (resolve, reject) {
|
||||
request
|
||||
.patch(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`)
|
||||
.set("authorization", self.token)
|
||||
@@ -1240,125 +1416,149 @@ class Client {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_deleteMessage(message){
|
||||
|
||||
getGateway() {
|
||||
var self = this;
|
||||
return new Promise(function(resolve, reject){
|
||||
return new Promise(function (resolve, reject) {
|
||||
request
|
||||
.del(`${Endpoints.CHANNELS}/${message.channel.id}/messages/${message.id}`)
|
||||
.set("authorization", self.token)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
.get(`${Endpoints.API}/gateway`)
|
||||
.set("authorization", self.token)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(res.body.url);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
checkQueue(channelID) {
|
||||
setStatusIdle() {
|
||||
this.setStatus("idle");
|
||||
}
|
||||
|
||||
setStatusOnline() {
|
||||
this.setStatus("online");
|
||||
}
|
||||
|
||||
setStatusActive() {
|
||||
this.setStatusOnline();
|
||||
}
|
||||
|
||||
setStatusHere() {
|
||||
this.setStatusOnline();
|
||||
}
|
||||
|
||||
setStatusAway() {
|
||||
this.setStatusIdle();
|
||||
}
|
||||
|
||||
startTyping(chann, stopTypeTime) {
|
||||
var self = this;
|
||||
|
||||
if (!this.checkingQueue[channelID]) {
|
||||
//if we aren't already checking this queue.
|
||||
this.checkingQueue[channelID] = true;
|
||||
doNext();
|
||||
|
||||
function doNext() {
|
||||
if (self.queue[channelID].length === 0) {
|
||||
done();
|
||||
return;
|
||||
}
|
||||
var queuedEvent = self.queue[channelID][0];
|
||||
switch (queuedEvent.action) {
|
||||
case "sendMessage":
|
||||
var msgToSend = queuedEvent;
|
||||
self._sendMessage(channelID, msgToSend.content, msgToSend.mentions)
|
||||
.then(function (msg) {
|
||||
msgToSend.then(msg);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
})
|
||||
.catch(function (err) {
|
||||
msgToSend.error(err);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
});
|
||||
break;
|
||||
case "sendFile":
|
||||
var fileToSend = queuedEvent;
|
||||
self._sendFile(channelID, fileToSend.attachment, fileToSend.attachmentName)
|
||||
.then(function (msg){
|
||||
fileToSend.then(msg);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
})
|
||||
.catch(function(err){
|
||||
fileToSend.error(err);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
});
|
||||
break;
|
||||
case "updateMessage":
|
||||
var msgToUpd = queuedEvent;
|
||||
self._updateMessage(msgToUpd.message, msgToUpd.content)
|
||||
.then(function(msg){
|
||||
msgToUpd.then(msg);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
})
|
||||
.catch(function(err){
|
||||
msgToUpd.error(err);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
});
|
||||
break;
|
||||
case "deleteMessage":
|
||||
var msgToDel = queuedEvent;
|
||||
self._deleteMessage(msgToDel.message)
|
||||
.then(function(msg){
|
||||
msgToDel.then(msg);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
})
|
||||
.catch(function(err){
|
||||
msgToDel.error(err);
|
||||
self.queue[channelID].shift();
|
||||
doNext();
|
||||
});
|
||||
break;
|
||||
default:
|
||||
done();
|
||||
break;
|
||||
}
|
||||
this.resolveDestination(chann).then(next);
|
||||
|
||||
function next(channel) {
|
||||
if (self.typingIntervals[channel]) {
|
||||
return;
|
||||
}
|
||||
|
||||
function done() {
|
||||
self.checkingQueue[channelID] = false;
|
||||
return;
|
||||
var fn = function () {
|
||||
request
|
||||
.post(`${Endpoints.CHANNELS}/${channel}/typing`)
|
||||
.set("authorization", self.token)
|
||||
.end();
|
||||
};
|
||||
|
||||
fn();
|
||||
|
||||
var interval = setInterval(fn, 3000);
|
||||
|
||||
self.typingIntervals[channel] = interval;
|
||||
|
||||
if (stopTypeTime) {
|
||||
setTimeout(function () {
|
||||
self.stopTyping(channel);
|
||||
}, stopTypeTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getGateway() {
|
||||
stopTyping(chann) {
|
||||
var self = this;
|
||||
|
||||
var self = this;
|
||||
this.resolveDestination(chann).then(next);
|
||||
|
||||
function next(channel) {
|
||||
if (!self.typingIntervals[channel]) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearInterval(self.typingIntervals[channel]);
|
||||
|
||||
delete self.typingIntervals[channel];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
setStatus(stat) {
|
||||
|
||||
var idleTime = (stat === "online" ? null : Date.now());
|
||||
|
||||
this.__idleTime = idleTime;
|
||||
|
||||
this.websocket.send(JSON.stringify({
|
||||
op: 3,
|
||||
d: {
|
||||
idle_since: this.__idleTime,
|
||||
game_id: this.__gameId
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
setPlayingGame(id) {
|
||||
|
||||
if (id instanceof String || typeof id === `string`) {
|
||||
|
||||
// working on names
|
||||
var gid = id.trim().toUpperCase();
|
||||
|
||||
id = null;
|
||||
|
||||
for (var game of gameMap) {
|
||||
|
||||
if (game.name.trim().toUpperCase() === gid) {
|
||||
|
||||
id = game.id;
|
||||
break;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
request
|
||||
.get(`${Endpoints.API}/gateway`)
|
||||
.end(function (err, res) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(res.body.url);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.__gameId = id;
|
||||
|
||||
this.websocket.send(JSON.stringify({
|
||||
op: 3,
|
||||
d: {
|
||||
idle_since: this.__idleTime,
|
||||
game_id: this.__gameId
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
playGame(id) {
|
||||
this.setPlayingGame(id);
|
||||
}
|
||||
|
||||
playingGame(id) {
|
||||
|
||||
this.setPlayingGame(id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Client;
|
||||
94
src/EvaluatedPermissions.js
Normal file
94
src/EvaluatedPermissions.js
Normal file
@@ -0,0 +1,94 @@
|
||||
class EvaluatedPermissions {
|
||||
constructor(data) {
|
||||
|
||||
var self = this;
|
||||
|
||||
this.packed = data;
|
||||
|
||||
if(this.getBit(3))
|
||||
this.packed = 4294967295;
|
||||
}
|
||||
|
||||
serialise() {
|
||||
return {
|
||||
createInstantInvite : this.createInstantInvite,
|
||||
manageRoles : this.manageRoles,
|
||||
manageChannels : this.manageChannels,
|
||||
readMessages : this.readMessages,
|
||||
sendMessages : this.sendMessage,
|
||||
sendTTSMessages : this.sendTTSMessages,
|
||||
manageMessages : this.manageMessages,
|
||||
embedLinks : this.embedLinks,
|
||||
attachFiles : this.attachFiles,
|
||||
readMessageHistory : this.readMessageHistory,
|
||||
mentionEveryone : this.mentionEveryone,
|
||||
voiceConnect : this.voiceConnect,
|
||||
voiceSpeak : this.voiceSpeak,
|
||||
voiceMuteMembers : this.voiceMuteMembers,
|
||||
voiceDeafenMembers : this.voiceDeafenMembers,
|
||||
voiceMoveMember : this.voiceMoveMembers,
|
||||
voiceUseVoiceActivation : this.voiceUseVoiceActivation
|
||||
}
|
||||
}
|
||||
|
||||
get createInstantInvite() { return this.getBit(0); }
|
||||
set createInstantInvite(val) { this.setBit(0, val); }
|
||||
|
||||
get manageRoles() { return this.getBit(3); }
|
||||
set manageRoles(val) { this.setBit(3, val); }
|
||||
|
||||
get manageChannels() { return this.getBit(4); }
|
||||
set manageChannels(val) { this.setBit(4, val); }
|
||||
|
||||
get readMessages() { return this.getBit(10); }
|
||||
set readMessages(val) { this.setBit(10, val); }
|
||||
|
||||
get sendMessages() { return this.getBit(11); }
|
||||
set sendMessages(val) { this.setBit(11, val); }
|
||||
|
||||
get sendTTSMessages() { return this.getBit(12); }
|
||||
set sendTTSMessages(val) { this.setBit(12, val); }
|
||||
|
||||
get manageMessages() { return this.getBit(13); }
|
||||
set manageMessages(val) { this.setBit(13, val); }
|
||||
|
||||
get embedLinks() { return this.getBit(14); }
|
||||
set embedLinks(val) { this.setBit(14, val); }
|
||||
|
||||
get attachFiles() { return this.getBit(15); }
|
||||
set attachFiles(val) { this.setBit(15, val); }
|
||||
|
||||
get readMessageHistory() { return this.getBit(16); }
|
||||
set readMessageHistory(val) { this.setBit(16, val); }
|
||||
|
||||
get mentionEveryone() { return this.getBit(17); }
|
||||
set mentionEveryone(val) { this.setBit(17, val); }
|
||||
|
||||
get voiceConnect() { return this.getBit(20); }
|
||||
set voiceConnect(val) { this.setBit(20, val); }
|
||||
|
||||
get voiceSpeak() { return this.getBit(21); }
|
||||
set voiceSpeak(val) { this.setBit(21, val); }
|
||||
|
||||
get voiceMuteMembers() { return this.getBit(22); }
|
||||
set voiceMuteMembers(val) { this.setBit(22, val); }
|
||||
|
||||
get voiceDeafenMembers() { return this.getBit(23); }
|
||||
set voiceDeafenMembers(val) { this.setBit(23, val); }
|
||||
|
||||
get voiceMoveMembers() { return this.getBit(24); }
|
||||
set voiceMoveMembers(val) { this.setBit(24, val); }
|
||||
|
||||
get voiceUseVoiceActivation() { return this.getBit(25); }
|
||||
set voiceUseVoiceActivation(val) { this.setBit(25, val); }
|
||||
|
||||
getBit(x) {
|
||||
return ((this.packed >>> x) & 1) === 1;
|
||||
}
|
||||
|
||||
setBit() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EvaluatedPermissions;
|
||||
78
src/Member.js
Normal file
78
src/Member.js
Normal file
@@ -0,0 +1,78 @@
|
||||
var User = require("./user.js");
|
||||
var ServerPermissions = require("./ServerPermissions.js");
|
||||
var EvaluatedPermissions = require("./EvaluatedPermissions.js");
|
||||
|
||||
class Member extends User{
|
||||
|
||||
constructor(user, server, roles){
|
||||
super(user); // should work, we are basically creating a Member that has the same properties as user and a few more
|
||||
this.server = server;
|
||||
this.rawRoles = roles;
|
||||
}
|
||||
|
||||
get roles(){
|
||||
|
||||
var ufRoles = [ this.server.getRole(this.server.id) ];
|
||||
|
||||
for(var rawRole of this.rawRoles){
|
||||
ufRoles.push( this.server.getRole(rawRole) );
|
||||
}
|
||||
|
||||
return ufRoles;
|
||||
|
||||
}
|
||||
|
||||
get evalPerms(){
|
||||
var basePerms = this.roles, //cache roles as it can be slightly expensive
|
||||
basePerm = basePerms[0].packed;
|
||||
|
||||
for(var perm of basePerms){
|
||||
basePerm = basePerm | perm.packed;
|
||||
}
|
||||
|
||||
return new ServerPermissions({
|
||||
permissions : basePerm
|
||||
});
|
||||
}
|
||||
|
||||
permissionsIn(channel){
|
||||
|
||||
if(channel.server.ownerID === this.id){
|
||||
return new EvaluatedPermissions(4294967295); //all perms
|
||||
}
|
||||
|
||||
var affectingOverwrites = [];
|
||||
var affectingMemberOverwrites = [];
|
||||
|
||||
for(var overwrite of channel.roles){
|
||||
if(overwrite.id === this.id && overwrite.type === "member"){
|
||||
affectingMemberOverwrites.push(overwrite);
|
||||
}else if( this.rawRoles.indexOf(overwrite.id) !== -1 ){
|
||||
affectingOverwrites.push(overwrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(affectingOverwrites.length === 0 && affectingMemberOverwrites.length === 0){
|
||||
return new EvaluatedPermissions(this.evalPerms.packed);
|
||||
}
|
||||
|
||||
var finalPacked = (affectingOverwrites.length !== 0 ? affectingOverwrites[0].packed : affectingMemberOverwrites[0].packed);
|
||||
|
||||
for(var overwrite of affectingOverwrites){
|
||||
finalPacked = finalPacked & ~overwrite.deny;
|
||||
finalPacked = finalPacked | overwrite.allow;
|
||||
}
|
||||
|
||||
for(var overwrite of affectingMemberOverwrites){
|
||||
finalPacked = finalPacked & ~overwrite.deny;
|
||||
finalPacked = finalPacked | overwrite.allow;
|
||||
}
|
||||
|
||||
return new EvaluatedPermissions(finalPacked);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Member;
|
||||
@@ -3,6 +3,7 @@ class PMChannel {
|
||||
this.user = client.getUser("id", data.recipient.id);
|
||||
this.id = data.id;
|
||||
this.messages = [];
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
addMessage(data){
|
||||
@@ -13,6 +14,11 @@ class PMChannel {
|
||||
}
|
||||
|
||||
getMessage(key, value){
|
||||
|
||||
if(this.messages.length > 1000){
|
||||
this.messages.splice(0,1);
|
||||
}
|
||||
|
||||
for(var message of this.messages){
|
||||
if(message[key] === value){
|
||||
return message;
|
||||
@@ -20,6 +26,10 @@ class PMChannel {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
get isPrivate(){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PMChannel;
|
||||
90
src/ServerPermissions.js
Normal file
90
src/ServerPermissions.js
Normal file
@@ -0,0 +1,90 @@
|
||||
class ServerPermissions {
|
||||
|
||||
constructor(data) {
|
||||
|
||||
var self = this;
|
||||
|
||||
function getBit(x) {
|
||||
return ((self.packed >>> x) & 1) === 1;
|
||||
}
|
||||
|
||||
this.packed = data.permissions;
|
||||
this.name = data.name;
|
||||
this.id = data.id;
|
||||
|
||||
}
|
||||
|
||||
get createInstantInvite(){return this.getBit(0);}
|
||||
set createInstantInvite(val){this.setBit(0, val);}
|
||||
|
||||
get banMembers(){return this.getBit(1);}
|
||||
set banMembers(val){this.setBit(1, val);}
|
||||
|
||||
get kickMembers(){return this.getBit(2);}
|
||||
set kickMembers(val){this.setBit(2, val);}
|
||||
|
||||
get manageRoles(){return this.getBit(3);}
|
||||
set manageRoles(val){this.setBit(3, val);}
|
||||
|
||||
get manageChannels(){return this.getBit(4);}
|
||||
set manageChannels(val){this.setBit(4, val);}
|
||||
|
||||
get manageServer(){return this.getBit(5);}
|
||||
set manageServer(val){this.setBit(5, val);}
|
||||
|
||||
get readMessages(){return this.getBit(10);}
|
||||
set readMessages(val){this.setBit(10, val);}
|
||||
|
||||
get sendMessages(){return this.getBit(11);}
|
||||
set sendMessages(val){this.setBit(11, val);}
|
||||
|
||||
get sendTTSMessages(){return this.getBit(12);}
|
||||
set sendTTSMessages(val){this.setBit(12, val);}
|
||||
|
||||
get manageMessages(){return this.getBit(13);}
|
||||
set manageMessages(val){this.setBit(13, val);}
|
||||
|
||||
get embedLinks(){return this.getBit(14);}
|
||||
set embedLinks(val){this.setBit(14, val);}
|
||||
|
||||
get attachFiles(){return this.getBit(15);}
|
||||
set attachFiles(val){this.setBit(15, val);}
|
||||
|
||||
get readMessageHistory(){return this.getBit(16);}
|
||||
set readMessageHistory(val){this.setBit(16, val);}
|
||||
|
||||
get mentionEveryone(){return this.getBit(17);}
|
||||
set mentionEveryone(val){this.setBit(17, val);}
|
||||
|
||||
get voiceConnect(){return this.getBit(20);}
|
||||
set voiceConnect(val){this.setBit(20, val);}
|
||||
|
||||
get voiceSpeak(){return this.getBit(21);}
|
||||
set voiceSpeak(val){this.setBit(21, val);}
|
||||
|
||||
get voiceMuteMembers(){return this.getBit(22);}
|
||||
set voiceMuteMembers(val){this.setBit(22, val);}
|
||||
|
||||
get voiceDeafenMembers(){return this.getBit(23);}
|
||||
set voiceDeafenMembers(val){this.setBit(23, val);}
|
||||
|
||||
get voiceMoveMembers(){return this.getBit(24);}
|
||||
set voiceMoveMembers(val){this.setBit(24, val);}
|
||||
|
||||
get voiceUseVoiceActivation(){return this.getBit(25);}
|
||||
set voiceUseVoiceActivation(val){this.setBit(25, val);}
|
||||
|
||||
getBit(x) {
|
||||
return ((this.packed >>> x) & 1) === 1;
|
||||
}
|
||||
|
||||
setBit(){
|
||||
//dummy function for now
|
||||
}
|
||||
|
||||
toString(){
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ServerPermissions;
|
||||
@@ -1,40 +1,88 @@
|
||||
var ChannelPermissions = require("./ChannelPermissions.js");
|
||||
|
||||
class Channel {
|
||||
|
||||
constructor(data, server) {
|
||||
this.server = server;
|
||||
this.name = data.name;
|
||||
this.type = data.type;
|
||||
this.topic = data.topic;
|
||||
this.id = data.id;
|
||||
this.messages = [];
|
||||
this.roles = [];
|
||||
|
||||
if(data.permission_overwrites)
|
||||
for (var role of data.permission_overwrites) {
|
||||
this.roles.push( new ChannelPermissions(role, this) );
|
||||
}
|
||||
|
||||
//this.isPrivate = isPrivate; //not sure about the implementation of this...
|
||||
}
|
||||
|
||||
get permissionOverwrites() {
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
get permissions() {
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
get client() {
|
||||
return this.server.client;
|
||||
}
|
||||
|
||||
permissionsOf(member){
|
||||
|
||||
var mem = this.server.getMember("id", member.id);
|
||||
|
||||
if(mem){
|
||||
return mem.permissionsIn(this);
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
equals(object) {
|
||||
return (object && object.id === this.id);
|
||||
}
|
||||
|
||||
addMessage(data){
|
||||
if(!this.getMessage("id", data.id)){
|
||||
this.messages.push(data);
|
||||
}
|
||||
return this.getMessage("id", data.id);
|
||||
}
|
||||
|
||||
getMessage(key, value){
|
||||
for(var message of this.messages){
|
||||
if(message[key] === value){
|
||||
return message;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
toString(){
|
||||
return "#" + this.name;
|
||||
addMessage(data) {
|
||||
|
||||
if (this.messages.length > 1000) {
|
||||
this.messages.splice(0, 1);
|
||||
}
|
||||
|
||||
if (!this.getMessage("id", data.id)) {
|
||||
this.messages.push(data);
|
||||
}
|
||||
|
||||
return this.getMessage("id", data.id);
|
||||
}
|
||||
|
||||
getMessage(key, value) {
|
||||
for (var message of this.messages) {
|
||||
if (message[key] === value) {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return "<#" + this.id + ">";
|
||||
}
|
||||
|
||||
get isPrivate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get users() {
|
||||
return this.server.members;
|
||||
}
|
||||
|
||||
get members() {
|
||||
return this.server.members;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
src/index.js
24
src/index.js
@@ -7,4 +7,28 @@ var Discord = {
|
||||
Client : Client
|
||||
}
|
||||
|
||||
Discord.patchStrings = function () {
|
||||
|
||||
defineProperty("bold", "**");
|
||||
defineProperty("underline", "__");
|
||||
defineProperty("strike", "~~");
|
||||
defineProperty("code", "`");
|
||||
defineProperty("codeblock", "```");
|
||||
defineProperty("newline", "\n");
|
||||
|
||||
Object.defineProperty(String.prototype, "italic", {
|
||||
get: function () {
|
||||
return "*" + this + "*";
|
||||
}
|
||||
});
|
||||
|
||||
function defineProperty(name, joiner) {
|
||||
Object.defineProperty(String.prototype, name, {
|
||||
get: function () {
|
||||
return joiner + this + joiner;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Discord;
|
||||
@@ -1,3 +1,5 @@
|
||||
var PMChannel = require("./PMChannel.js");
|
||||
|
||||
class Message{
|
||||
constructor(data, channel, mentions, author){
|
||||
this.tts = data.tts;
|
||||
@@ -10,7 +12,13 @@ class Message{
|
||||
this.editedTimestamp = data.edited_timestamp;
|
||||
this.content = data.content.trim();
|
||||
this.channel = channel;
|
||||
this.author = author;
|
||||
|
||||
if(this.isPrivate){
|
||||
this.author = this.channel.client.getUser("id", author.id);
|
||||
}else{
|
||||
this.author = this.channel.server.getMember("id", author.id) || this.channel.client.getUser("id", author.id);
|
||||
}
|
||||
|
||||
this.attachments = data.attachments;
|
||||
}
|
||||
|
||||
@@ -27,6 +35,10 @@ class Message{
|
||||
get sender(){
|
||||
return this.author;
|
||||
}
|
||||
|
||||
get isPrivate(){
|
||||
return this.channel.isPrivate;
|
||||
}
|
||||
}
|
||||
|
||||
/*exports.Message.prototype.isPM = function() {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
var ServerPermissions = require("./ServerPermissions.js");
|
||||
var Member = require("./Member.js");
|
||||
|
||||
class Server {
|
||||
constructor(data, client) {
|
||||
this.client = client;
|
||||
@@ -10,6 +13,12 @@ class Server {
|
||||
this.icon = data.icon;
|
||||
this.afkTimeout = data.afk_timeout;
|
||||
this.afkChannelId = data.afk_channel_id;
|
||||
|
||||
this.roles = [];
|
||||
|
||||
for(var permissionGroup of data.roles){
|
||||
this.roles.push( new ServerPermissions(permissionGroup) );
|
||||
}
|
||||
|
||||
if(!data.members){
|
||||
data.members = [ client.user ];
|
||||
@@ -24,10 +33,18 @@ class Server {
|
||||
// it will be identical (unless an async change occurred)
|
||||
// to the client's cache.
|
||||
if(member.user)
|
||||
this.members.push(client.addUser(member.user));
|
||||
this.addMember(client.addUser(member.user), member.roles);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
get permissionGroups(){
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
get permissions(){
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
get iconURL() {
|
||||
if (!this.icon)
|
||||
@@ -50,7 +67,56 @@ class Server {
|
||||
return this.client.getUser("id", this.ownerID);
|
||||
}
|
||||
|
||||
get users() {
|
||||
return this.members;
|
||||
}
|
||||
|
||||
// get/set
|
||||
|
||||
getRole(id){
|
||||
for (var role of this.roles) {
|
||||
if (role.id === id) {
|
||||
return role;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
updateRole(data){
|
||||
|
||||
var oldRole = this.getRole(data.id);
|
||||
|
||||
if(oldRole){
|
||||
|
||||
var index = this.roles.indexOf(oldRole);
|
||||
this.roles[index] = new ServerPermissions(data);
|
||||
|
||||
|
||||
return this.roles[index];
|
||||
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
removeRole(id){
|
||||
for (var roleId in this.roles) {
|
||||
if (this.roles[roleId].id === id) {
|
||||
this.roles.splice(roleId, 1);
|
||||
}
|
||||
}
|
||||
|
||||
for(var member of this.members){
|
||||
for(var roleId in member.rawRoles){
|
||||
if(member.rawRoles[roleId] === id){
|
||||
member.rawRoles.splice(roleId, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getChannel(key, value) {
|
||||
for (var channel of this.channels) {
|
||||
if (channel[key] === value) {
|
||||
@@ -71,6 +137,17 @@ class Server {
|
||||
return null;
|
||||
}
|
||||
|
||||
removeMember(key, value){
|
||||
for (var member of this.members) {
|
||||
if (member[key] === value) {
|
||||
this.members.splice(key, 1);
|
||||
return member;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
addChannel(chann) {
|
||||
if (!this.getChannel("id", chann.id)) {
|
||||
this.channels.push(chann);
|
||||
@@ -78,16 +155,21 @@ class Server {
|
||||
return chann;
|
||||
}
|
||||
|
||||
addMember(member){
|
||||
if (!this.getMember("id", member.id)){
|
||||
this.members.push(member);
|
||||
addMember(user, roles){
|
||||
if (!this.getMember("id", user.id)){
|
||||
var mem = new Member(user, this, roles);
|
||||
this.members.push(mem);
|
||||
}
|
||||
return member;
|
||||
return mem;
|
||||
}
|
||||
|
||||
toString(){
|
||||
return this.name;
|
||||
}
|
||||
|
||||
equals(object){
|
||||
return object.id === this.id;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Server;
|
||||
@@ -4,6 +4,8 @@ class User{
|
||||
this.discriminator = data.discriminator;
|
||||
this.id = data.id;
|
||||
this.avatar = data.avatar;
|
||||
this.status = data.status || "offline";
|
||||
this.gameId = data.game_id || null;
|
||||
}
|
||||
|
||||
// access using user.avatarURL;
|
||||
|
||||
@@ -1,32 +1,67 @@
|
||||
var Discord = require("../");
|
||||
var mybot = new Discord.Client({
|
||||
queue: true
|
||||
});
|
||||
var mybot = new Discord.Client();
|
||||
var fs = require("fs");
|
||||
var request = require("request").defaults({ encoding: null });
|
||||
|
||||
Discord.patchStrings();
|
||||
|
||||
var server, channel, message, sentMessage = false;
|
||||
|
||||
counter = 1;
|
||||
|
||||
mybot.on("message", function (message) {
|
||||
|
||||
if (mybot.user.equals(message.sender)) {
|
||||
|
||||
console.log("Everyone mentioned? " + message.everyoneMentioned);
|
||||
if (message.content.substr(0,3) !== "$$$") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (message.content !== "$$$") {
|
||||
return;
|
||||
}
|
||||
|
||||
var action1 = mybot.sendMessage(message.channel, "this is message " + 1);
|
||||
var action2 = mybot.sendMessage(message.channel, "this is message " + 2).then(log);
|
||||
|
||||
function log() {
|
||||
mybot.updateMessage(action1.message, "blurg");
|
||||
mybot.sendMessage(message.channel, "This is message 3 million minus the million so basically just 3");
|
||||
mybot.deleteMessage(action1.message);
|
||||
mybot.sendMessage(message.channel, "This is message RJNGEIKGNER").then(log2);
|
||||
// we can go ahead :)
|
||||
|
||||
var user;
|
||||
if(message.mentions.length > 0){
|
||||
user = message.mentions[0];
|
||||
}else{
|
||||
user = message.sender;
|
||||
}
|
||||
|
||||
console.log( mybot.getUser("username", "meew0") );
|
||||
|
||||
var perms = JSON.stringify(message.channel.permissionsOf(user).serialise(), null, 4);
|
||||
perms = JSON.parse(perms);
|
||||
|
||||
request.get(message.sender.avatarURL, function(err, resp, body){
|
||||
mybot.setAvatar( new Buffer(body) ).catch(error).then(() => {
|
||||
mybot.reply(message, "I have your avatar now!");
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
mybot.on("ready", function () {
|
||||
console.log("im ready");
|
||||
|
||||
for(var server of mybot.servers){
|
||||
if(server.name === "test-server"){
|
||||
mybot.leaveServer(server);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
mybot.on("debug", function(info){
|
||||
|
||||
})
|
||||
|
||||
mybot.on("unknown", function(info){
|
||||
console.log("warning!", info);
|
||||
})
|
||||
|
||||
mybot.on("channelUpdate", function(oldChan, newChan){
|
||||
|
||||
});
|
||||
|
||||
|
||||
function dump(msg) {
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
10
web-dist/README.md
Normal file
10
web-dist/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## Web Distributions
|
||||
|
||||
Here you can find the latest web-ready distributions of discord.js. These distributions will allow you to run discord.js
|
||||
in your browser, which is very useful for making on-the-go bots or clients. For some reason, request times are also much
|
||||
shorter in browsers, so your bots will reply much faster.
|
||||
|
||||
Web Distributions aren't always fully functional, and sometimes catching errors is a pain. As discord.js's support for
|
||||
browserifying is still maturing, please don't expect that it will work out of the box just yet.
|
||||
|
||||
Also, if the versions in this folder are out-dated, you can always run `grunt web` to generate the latest library.
|
||||
File diff suppressed because it is too large
Load Diff
3590
web-dist/discord.3.3.1.js
Normal file
3590
web-dist/discord.3.3.1.js
Normal file
File diff suppressed because it is too large
Load Diff
3593
web-dist/discord.3.3.2.js
Normal file
3593
web-dist/discord.3.3.2.js
Normal file
File diff suppressed because it is too large
Load Diff
3641
web-dist/discord.3.4.0.js
Normal file
3641
web-dist/discord.3.4.0.js
Normal file
File diff suppressed because it is too large
Load Diff
3879
web-dist/discord.3.6.3.js
Normal file
3879
web-dist/discord.3.6.3.js
Normal file
File diff suppressed because one or more lines are too long
3879
web-dist/discord.3.7.1.js
Normal file
3879
web-dist/discord.3.7.1.js
Normal file
File diff suppressed because one or more lines are too long
1534
web-dist/discord.3.8.4.js
Normal file
1534
web-dist/discord.3.8.4.js
Normal file
File diff suppressed because one or more lines are too long
1534
web-dist/discord.3.9.0.js
Normal file
1534
web-dist/discord.3.9.0.js
Normal file
File diff suppressed because one or more lines are too long
2
web-dist/discord.min.3.3.0.js
Normal file
2
web-dist/discord.min.3.3.0.js
Normal file
File diff suppressed because one or more lines are too long
2
web-dist/discord.min.3.3.1.js
Normal file
2
web-dist/discord.min.3.3.1.js
Normal file
File diff suppressed because one or more lines are too long
2
web-dist/discord.min.3.3.2.js
Normal file
2
web-dist/discord.min.3.3.2.js
Normal file
File diff suppressed because one or more lines are too long
2
web-dist/discord.min.3.4.0.js
Normal file
2
web-dist/discord.min.3.4.0.js
Normal file
File diff suppressed because one or more lines are too long
2
web-dist/discord.min.3.6.3.js
Normal file
2
web-dist/discord.min.3.6.3.js
Normal file
File diff suppressed because one or more lines are too long
2
web-dist/discord.min.3.7.1.js
Normal file
2
web-dist/discord.min.3.7.1.js
Normal file
File diff suppressed because one or more lines are too long
3
web-dist/discord.min.3.8.4.js
Normal file
3
web-dist/discord.min.3.8.4.js
Normal file
File diff suppressed because one or more lines are too long
3
web-dist/discord.min.3.9.0.js
Normal file
3
web-dist/discord.min.3.9.0.js
Normal file
File diff suppressed because one or more lines are too long
2
web-dist/discord.min.js
vendored
2
web-dist/discord.min.js
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user