"use strict"; exports.__esModule = true; 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var _superagent = require("superagent"); var _superagent2 = _interopRequireDefault(_superagent); var _ws = require("ws"); var _ws2 = _interopRequireDefault(_ws); var _ConnectionState = require("./ConnectionState"); var _ConnectionState2 = _interopRequireDefault(_ConnectionState); var _querystring = require("querystring"); var _querystring2 = _interopRequireDefault(_querystring); var _Constants = require("../Constants"); var _UtilCache = require("../Util/Cache"); var _UtilCache2 = _interopRequireDefault(_UtilCache); var _ResolverResolver = require("./Resolver/Resolver"); var _ResolverResolver2 = _interopRequireDefault(_ResolverResolver); var _StructuresUser = require("../Structures/User"); var _StructuresUser2 = _interopRequireDefault(_StructuresUser); var _StructuresChannel = require("../Structures/Channel"); var _StructuresChannel2 = _interopRequireDefault(_StructuresChannel); var _StructuresServerChannel = require("../Structures/ServerChannel"); var _StructuresServerChannel2 = _interopRequireDefault(_StructuresServerChannel); var _StructuresTextChannel = require("../Structures/TextChannel"); var _StructuresTextChannel2 = _interopRequireDefault(_StructuresTextChannel); var _StructuresVoiceChannel = require("../Structures/VoiceChannel"); var _StructuresVoiceChannel2 = _interopRequireDefault(_StructuresVoiceChannel); var _StructuresPMChannel = require("../Structures/PMChannel"); var _StructuresPMChannel2 = _interopRequireDefault(_StructuresPMChannel); var _StructuresServer = require("../Structures/Server"); var _StructuresServer2 = _interopRequireDefault(_StructuresServer); var _StructuresMessage = require("../Structures/Message"); var _StructuresMessage2 = _interopRequireDefault(_StructuresMessage); var _StructuresRole = require("../Structures/Role"); var _StructuresRole2 = _interopRequireDefault(_StructuresRole); var _StructuresInvite = require("../Structures/Invite"); var _StructuresInvite2 = _interopRequireDefault(_StructuresInvite); var _VoiceVoiceConnection = require("../Voice/VoiceConnection"); var _VoiceVoiceConnection2 = _interopRequireDefault(_VoiceVoiceConnection); var _UtilTokenCacher = require("../Util/TokenCacher"); var _UtilTokenCacher2 = _interopRequireDefault(_UtilTokenCacher); var zlib; var libVersion = require('../../package.json').version; function waitFor(condition) { var value = arguments.length <= 1 || arguments[1] === undefined ? condition : arguments[1]; var interval = arguments.length <= 2 || arguments[2] === undefined ? 20 : arguments[2]; return (function () { return new Promise(function (resolve) { var int = setInterval(function () { var isDone = condition(); if (isDone) { if (condition === value) { resolve(isDone); } else { resolve(value(isDone)); } return clearInterval(int); } }, interval); }); })(); } function delay(ms) { return new Promise(function (resolve) { return setTimeout(resolve, ms); }); } var InternalClient = (function () { function InternalClient(discordClient) { _classCallCheck(this, InternalClient); this.setup(discordClient); } InternalClient.prototype.apiRequest = function apiRequest(method, url, useAuth, data, file) { var _this = this, _arguments = arguments; var endpoint = url.replace(/\/[0-9]+/g, "/:id"); if (this.retryAfters[endpoint]) { if (this.retryAfters[endpoint] < Date.now()) { delete this.retryAfters[endpoint]; } else { return new Promise(function (resolve, reject) { setTimeout(function () { _this.apiRequest.apply(_this, _arguments).then(resolve)["catch"](reject); }, _this.retryAfters[endpoint] - Date.now()); }); } } var ret = _superagent2["default"][method](url); if (useAuth) { ret.set("authorization", this.token); } if (file) { ret.attach("file", file.file, file.name); if (data) { for (var i in data) { if (data[i] !== undefined) { ret.field(i, data[i]); } } } } else if (data) { ret.send(data); } ret.set('User-Agent', this.userAgentInfo.full); return new Promise(function (resolve, reject) { ret.end(function (error, data) { if (error) { if (!_this.client.options.rateLimitAsError && error.response && error.response.error && error.response.error.status && error.response.error.status === 429) { if (data.headers["retry-after"] || data.headers["Retry-After"]) { var toWait = data.headers["retry-after"] || data.headers["Retry-After"]; if (!_this.retryAfters[endpoint]) _this.retryAfters[endpoint] = Date.now() + parseInt(toWait); setTimeout(function () { _this.apiRequest.apply(_this, _arguments).then(resolve)["catch"](reject); }, _this.retryAfters[endpoint] - Date.now()); } else { return reject(error); } } else { return reject(error); } } else { resolve(data.body); } }); }); }; InternalClient.prototype.setup = function setup(discordClient) { discordClient = discordClient || this.client; this.client = discordClient; this.state = _ConnectionState2["default"].IDLE; this.websocket = null; this.userAgent = { url: 'https://github.com/hydrabolt/discord.js', version: require('../../package.json').version }; if (this.client.options.compress) { zlib = require("zlib"); } // creates 4 caches with discriminators based on ID this.users = new _UtilCache2["default"](); this.friends = new _UtilCache2["default"](); this.blocked_users = new _UtilCache2["default"](); this.outgoing_friend_requests = new _UtilCache2["default"](); this.incoming_friend_requests = new _UtilCache2["default"](); this.channels = new _UtilCache2["default"](); this.servers = new _UtilCache2["default"](); this.unavailableServers = new _UtilCache2["default"](); this.private_channels = new _UtilCache2["default"](); this.autoReconnectInterval = 1000; this.intervals = { typing: [], kai: null, misc: [] }; this.voiceConnections = new _UtilCache2["default"](); this.resolver = new _ResolverResolver2["default"](this); this.readyTime = null; this.messageAwaits = {}; this.retryAfters = {}; this.tokenCacher = new _UtilTokenCacher2["default"](this.client); this.tokenCacher.init(0); }; InternalClient.prototype.cleanIntervals = function cleanIntervals() { for (var _iterator = this.intervals.typing.concat(this.intervals.misc).concat(this.intervals.kai), _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 interval = _ref; if (interval) { clearInterval(interval); } } }; InternalClient.prototype.disconnected = function disconnected() { var _this2 = this; var autoReconnect = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; this.cleanIntervals(); this.voiceConnections.forEach(function (vc) { _this2.leaveVoiceChannel(vc); }); if (autoReconnect) { this.autoReconnectInterval = Math.min(this.autoReconnectInterval * (Math.random() + 1), 60000); setTimeout(function () { if (!_this2.email && !_this2.token) { return; } _this2.setup(); // Check whether the email is set (if not, only a token has been used for login) _this2.loginWithToken(_this2.token, _this2.email, _this2.password)["catch"](function () { return _this2.disconnected(true); }); }, this.autoReconnectInterval); } this.client.emit("disconnected"); }; //def leaveVoiceChannel InternalClient.prototype.leaveVoiceChannel = function leaveVoiceChannel(chann) { var _this3 = this; if (this.user.bot) { var leave = function leave(connection) { return new Promise(function (resolve, reject) { connection.destroy(); resolve(); }); }; if (chann instanceof _StructuresVoiceChannel2["default"]) { return this.resolver.resolveChannel(chann).then(function (channel) { if (!channel) { return Promise.reject(new Error("voice channel does not exist")); } if (channel.type !== 'voice') { return Promise.reject(new Error("channel is not a voice channel!")); } var connection = _this3.voiceConnections.get("voiceChannel", channel); if (!connection) { return Promise.reject(new Error("not connected to that voice channel")); } return leave(connection); }); } else if (chann instanceof _VoiceVoiceConnection2["default"]) { return leave(chann); } else { return Promise.reject(new Error("invalid voice channel/connection to leave")); } } else { // preserve old functionality for non-bots if (this.voiceConnections[0]) { this.voiceConnections[0].destroy(); } return Promise.resolve(); } }; //def awaitResponse InternalClient.prototype.awaitResponse = function awaitResponse(msg) { var _this4 = this; return new Promise(function (resolve, reject) { msg = _this4.resolver.resolveMessage(msg); if (!msg) { reject(new Error("message undefined")); return; } var awaitID = msg.channel.id + msg.author.id; if (!_this4.messageAwaits[awaitID]) { _this4.messageAwaits[awaitID] = []; } _this4.messageAwaits[awaitID].push(resolve); }); }; //def joinVoiceChannel InternalClient.prototype.joinVoiceChannel = function joinVoiceChannel(chann) { var _this5 = this; return this.resolver.resolveChannel(chann).then(function (channel) { if (!channel) { return Promise.reject(new Error("voice channel does not exist")); } if (channel.type !== 'voice') { return Promise.reject(new Error("channel is not a voice channel!")); } var joinSendWS = function joinSendWS() { _this5.sendWS({ op: 4, d: { "guild_id": channel.server.id, "channel_id": channel.id, "self_mute": false, "self_deaf": false } }); }; var joinVoice = function joinVoice() { return new Promise(function (resolve, reject) { var session = _this5.sessionID, token, server = channel.server, endpoint; var check = function check(m) { var data = JSON.parse(m); if (data.d.guild_id !== server.id) return; // ensure it is the right server if (data.t === "VOICE_SERVER_UPDATE") { token = data.d.token; endpoint = data.d.endpoint; var chan = new _VoiceVoiceConnection2["default"](channel, _this5.client, session, token, server, endpoint); _this5.voiceConnections.add(chan); chan.on("ready", function () { return resolve(chan); }); chan.on("error", reject); chan.on("close", reject); _this5.client.emit("debug", "removed temporary voice websocket listeners"); _this5.websocket.removeListener("message", check); } }; _this5.websocket.on("message", check); joinSendWS(); }); }; var existingServerConn = _this5.voiceConnections.get("server", channel.server); // same server connection if (existingServerConn) { joinSendWS(); // Just needs to update by sending via WS, movement in cache will be handled by global handler return Promise.resolve(existingServerConn); } if (!_this5.user.bot && _this5.voiceConnections.length > 0) { // nonbot, one voiceconn only, just like last time just disconnect return _this5.leaveVoiceChannel().then(joinVoice); } return joinVoice(); }); }; // Backwards-compatible utility getter method for the first voice connection // Thanks to #q (@qeled) for suggesting this InternalClient.prototype.getGuildMembers = function getGuildMembers(serverID, chunkCount) { this.forceFetchCount[serverID] = chunkCount; if (this.forceFetchLength + 3 + serverID.length > 4082) { // 4096 - '{"op":8,"d":[]}'.length + 1 for lazy comma offset this.requestGuildMembers(this.forceFetchQueue); this.forceFetchQueue = [serverID]; this.forceFetchLength = 1 + serverID.length + 3; } else { this.forceFetchQueue.push(serverID); this.forceFetchLength += serverID.length + 3; } }; InternalClient.prototype.requestGuildMembers = function requestGuildMembers(serverID, query, limit) { this.sendWS({ op: 8, d: { guild_id: serverID, query: query || "", limit: limit || 0 } }); }; InternalClient.prototype.checkReady = function checkReady() { if (!this.readyTime) { if (this.forceFetchQueue.length > 0) { this.requestGuildMembers(this.forceFetchQueue); this.forceFetchQueue = []; this.forceFetchLength = 1; } else { for (var key in this.forceFetchCount) { if (this.forceFetchCount.hasOwnProperty(key)) { return; } } this.readyTime = Date.now(); this.client.emit("ready"); } } }; InternalClient.prototype.restartServerCreateTimeout = function restartServerCreateTimeout() { var _this6 = this; if (this.guildCreateTimeout) { clearTimeout(this.guildCreateTimeout); this.guildCreateTimeout = null; } if (!this.readyTime) { this.guildCreateTimeout = setTimeout(function () { _this6.checkReady(); }, this.client.options.guildCreateTimeout); } }; // def createServer InternalClient.prototype.createServer = function createServer(name) { var _this7 = this; var region = arguments.length <= 1 || arguments[1] === undefined ? "london" : arguments[1]; name = this.resolver.resolveString(name); return this.apiRequest('post', _Constants.Endpoints.SERVERS, true, { name: name, region: region }).then(function (res) { // valid server, wait until it is cached return waitFor(function () { return _this7.servers.get("id", res.id); }); }); }; //def joinServer InternalClient.prototype.joinServer = function joinServer(invite) { var _this8 = this; invite = this.resolver.resolveInviteID(invite); if (!invite) { return Promise.reject(new Error("Not a valid invite")); } return this.apiRequest("post", _Constants.Endpoints.INVITE(invite), true).then(function (res) { // valid server, wait until it is received via ws and cached return waitFor(function () { return _this8.servers.get("id", res.guild.id); }); }); }; //def updateServer InternalClient.prototype.updateServer = function updateServer(server, options) { var _this9 = this; var server = this.resolver.resolveServer(server); if (!server) { return Promise.reject(new Error("server did not resolve")); } var newOptions = { name: options.name || server.name, region: options.region || server.region }; if (options.icon) { newOptions.icon = this.resolver.resolveToBase64(options.icon); } if (options.splash) { newOptions.splash = this.resolver.resolveToBase64(options.splash); } if (options.owner) { var user = this.resolver.resolveUser(options.owner); if (!user) { return Promise.reject(new Error("owner could not be resolved")); } options.owner_id = user.id; } if (options.verificationLevel) { options.verification_level = user.verificationLevel; } if (options.afkChannel) { var channel = this.resolver.resolveUser(options.afkChannel); if (!channel) { return Promise.reject(new Error("afkChannel could not be resolved")); } options.afk_channel_id = channel.id; } if (options.afkTimeout) { options.afk_timeout = user.afkTimeout; } return this.apiRequest("patch", _Constants.Endpoints.SERVER(server.id), true, options).then(function (res) { // wait until the name and region are updated return waitFor(function () { return _this9.servers.get("name", res.name) ? _this9.servers.get("name", res.name).region === res.region ? _this9.servers.get("id", res.id) : false : false; }); }); }; //def leaveServer InternalClient.prototype.leaveServer = function leaveServer(srv) { var _this10 = this; var server = this.resolver.resolveServer(srv); if (!server) { return Promise.reject(new Error("server did not resolve")); } return this.apiRequest("del", _Constants.Endpoints.ME_SERVER(server.id), true).then(function () { // remove channels of server then the server for (var _iterator2 = server.channels, _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 chan = _ref2; _this10.channels.remove(chan); } // remove server _this10.servers.remove(server); }); }; //def deleteServer InternalClient.prototype.deleteServer = function deleteServer(srv) { var _this11 = this; var server = this.resolver.resolveServer(srv); if (!server) { return Promise.reject(new Error("server did not resolve")); } return this.apiRequest("del", _Constants.Endpoints.SERVER(server.id), true).then(function () { // remove channels of server then the server for (var _iterator3 = server.channels, _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 chan = _ref3; _this11.channels.remove(chan); } // remove server _this11.servers.remove(server); }); }; // def loginWithToken // email and password are optional InternalClient.prototype.loginWithToken = function loginWithToken(token, email, password) { var _this12 = this; this.state = _ConnectionState2["default"].LOGGED_IN; this.token = token; this.email = email; this.password = password; return this.getGateway().then(function (url) { _this12.createWS(url); return token; }); }; // def login InternalClient.prototype.login = function login(email, password) { var _this13 = this; var client = this.client; if (!this.tokenCacher.done) { return new Promise(function (resolve, reject) { setTimeout(function () { _this13.login(email, password).then(resolve)["catch"](reject); }, 20); }); } else { var tk = this.tokenCacher.getToken(email, password); if (tk) { this.client.emit("debug", "bypassed direct API login, used cached token"); return this.loginWithToken(tk, email, password); } } if (this.state !== _ConnectionState2["default"].DISCONNECTED && this.state !== _ConnectionState2["default"].IDLE) { return Promise.reject(new Error("already logging in/logged in/ready!")); } this.state = _ConnectionState2["default"].LOGGING_IN; return this.apiRequest("post", _Constants.Endpoints.LOGIN, false, { email: email, password: password }).then(function (res) { _this13.client.emit("debug", "direct API login, cached token was unavailable"); var token = res.token; _this13.tokenCacher.setToken(email, password, token); return _this13.loginWithToken(token, email, password); }, function (error) { _this13.websocket = null; throw error; })["catch"](function (error) { _this13.websocket = null; _this13.state = _ConnectionState2["default"].DISCONNECTED; client.emit("disconnected"); throw error; }); }; // def logout InternalClient.prototype.logout = function logout() { var _this14 = this; if (this.state === _ConnectionState2["default"].DISCONNECTED || this.state === _ConnectionState2["default"].IDLE) { return Promise.reject(new Error("Client is not logged in!")); } return this.apiRequest("post", _Constants.Endpoints.LOGOUT, true).then(function () { if (_this14.websocket) { _this14.websocket.close(1000); _this14.websocket = null; } _this14.token = null; _this14.email = null; _this14.password = null; _this14.state = _ConnectionState2["default"].DISCONNECTED; }); }; // def startPM InternalClient.prototype.startPM = function startPM(resUser) { var _this15 = this; var user = this.resolver.resolveUser(resUser); if (!user) { return Promise.reject(new Error("Unable to resolve resUser to a User")); } // start the PM return this.apiRequest("post", _Constants.Endpoints.ME_CHANNELS, true, { recipient_id: user.id }).then(function (res) { return _this15.private_channels.add(new _StructuresPMChannel2["default"](res, _this15.client)); }); }; // def getGateway InternalClient.prototype.getGateway = function getGateway() { var _this16 = this; if (this.gatewayURL) { return Promise.resolve(this.gatewayURL); } return this.apiRequest("get", _Constants.Endpoints.GATEWAY, true).then(function (res) { return _this16.gatewayURL = res.url; }); }; // def sendMessage InternalClient.prototype.sendMessage = function sendMessage(where, _content) { var _this17 = this; var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; if (options.file) { if (typeof options.file !== "object") { options.file = { file: options.file }; } if (!options.file.name) { if (options.file.file instanceof String || typeof options.file.file === "string") { options.file.name = require("path").basename(options.file.file); } else if (options.file.file.path) { // fs.createReadStream()'s have .path that give the path. Not sure about other streams though. options.file.name = require("path").basename(options.file.file.path); } else { options.file.name = "default.png"; // Just have to go with default filenames. } } } return this.resolver.resolveChannel(where).then(function (destination) { var content = _this17.resolver.resolveString(_content); if (options.file) { return _this17.resolver.resolveFile(options.file.file).then(function (file) { return _this17.apiRequest("post", _Constants.Endpoints.CHANNEL_MESSAGES(destination.id), true, { content: content, tts: options.tts }, { name: options.file.name, file: file }).then(function (res) { return destination.messages.add(new _StructuresMessage2["default"](res, destination, _this17.client)); }); }); } else { return _this17.apiRequest("post", _Constants.Endpoints.CHANNEL_MESSAGES(destination.id), true, { content: content, tts: options.tts }).then(function (res) { return destination.messages.add(new _StructuresMessage2["default"](res, destination, _this17.client)); }); } }); }; // def sendFile InternalClient.prototype.sendFile = function sendFile(where, _file, name, content) { var _this18 = this; if (!name) { if (_file instanceof String || typeof _file === "string") { name = require("path").basename(_file); } else if (_file && _file.path) { // fs.createReadStream()'s have .path that give the path. Not sure about other streams though. name = require("path").basename(_file.path); } else { name = "default.png"; // Just have to go with default filenames. } } if (content) { content = { content: this.resolver.resolveString(content) }; } return this.resolver.resolveChannel(where).then(function (channel) { return _this18.resolver.resolveFile(_file).then(function (file) { return _this18.apiRequest("post", _Constants.Endpoints.CHANNEL_MESSAGES(channel.id), true, content, { name: name, file: file }).then(function (res) { return channel.messages.add(new _StructuresMessage2["default"](res, channel, _this18.client)); }); }); }); }; // def deleteMessage InternalClient.prototype.deleteMessage = function deleteMessage(_message) { var _this19 = this; var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var message = this.resolver.resolveMessage(_message); if (!message) { return Promise.reject(new Error("Supplied message did not resolve to a message!")); } var chain = options.wait ? delay(options.wait) : Promise.resolve(); return chain.then(function () { return _this19.apiRequest("del", _Constants.Endpoints.CHANNEL_MESSAGE(message.channel.id, message.id), true); }).then(function () { return message.channel.messages.remove(message); }); }; // def deleteMessages InternalClient.prototype.deleteMessages = function deleteMessages(_messages) { if (!_messages instanceof Array) return Promise.reject(new Error("Messages provided must be in an array")); if (_messages.length < 1) return Promise.reject(new Error("You must provide at least one message to delete")); var messages = []; var channel; for (var _iterator4 = _messages, _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 _message = _ref4; var message = this.resolver.resolveMessage(_message); if (!message) return Promise.reject(new Error("Something other than a message could not be resolved in the array...")); // ensure same channel if (!channel) { channel = message.channel; } else { if (message.channel.id !== channel.id) return Promise.reject(new Error("You can only bulk delete messages from the same channel at one time...")); } messages.push(message); } return this.apiRequest("post", _Constants.Endpoints.CHANNEL_MESSAGES(channel.id) + "/bulk_delete", true, { messages: messages.map(function (m) { return m.id; }) }).then(function () { return messages.forEach(function (m) { return channel.messages.remove(m); }); }); }; // def updateMessage InternalClient.prototype.updateMessage = function updateMessage(msg, _content) { var _this20 = this; var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; var message = this.resolver.resolveMessage(msg); if (!message) { return Promise.reject(new Error("Supplied message did not resolve to a message!")); } var content = this.resolver.resolveString(_content); return this.apiRequest("patch", _Constants.Endpoints.CHANNEL_MESSAGE(message.channel.id, message.id), true, { content: content, tts: options.tts }).then(function (res) { return message.channel.messages.update(message, new _StructuresMessage2["default"](res, message.channel, _this20.client)); }); }; // def getChannelLogs InternalClient.prototype.getChannelLogs = function getChannelLogs(_channel) { var _this21 = this; var limit = arguments.length <= 1 || arguments[1] === undefined ? 50 : arguments[1]; var options = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2]; return this.resolver.resolveChannel(_channel).then(function (channel) { var qsObject = { limit: limit }; if (options.before) { var res = _this21.resolver.resolveMessage(options.before); if (res) { qsObject.before = res.id; } } if (options.after) { var res = _this21.resolver.resolveMessage(options.after); if (res) { qsObject.after = res.id; } } return _this21.apiRequest("get", _Constants.Endpoints.CHANNEL_MESSAGES(channel.id) + "?" + _querystring2["default"].stringify(qsObject), true).then(function (res) { return res.map(function (msg) { return channel.messages.add(new _StructuresMessage2["default"](msg, channel, _this21.client)); }); }); }); }; // def getBans InternalClient.prototype.getBans = function getBans(server) { var _this22 = this; server = this.resolver.resolveServer(server); return this.apiRequest("get", _Constants.Endpoints.SERVER_BANS(server.id), true).then(function (res) { return res.map(function (ban) { return _this22.users.add(new _StructuresUser2["default"](ban.user, _this22.client)); }); }); }; // def createChannel InternalClient.prototype.createChannel = function createChannel(server, name) { var _this23 = this; var type = arguments.length <= 2 || arguments[2] === undefined ? "text" : arguments[2]; server = this.resolver.resolveServer(server); return this.apiRequest("post", _Constants.Endpoints.SERVER_CHANNELS(server.id), true, { name: name, type: type }).then(function (res) { var channel; if (res.type === "text") { channel = new _StructuresTextChannel2["default"](res, _this23.client, server); } else { channel = new _StructuresVoiceChannel2["default"](res, _this23.client, server); } return server.channels.add(_this23.channels.add(channel)); }); }; // def deleteChannel InternalClient.prototype.deleteChannel = function deleteChannel(_channel) { var _this24 = this; return this.resolver.resolveChannel(_channel).then(function (channel) { return _this24.apiRequest("del", _Constants.Endpoints.CHANNEL(channel.id), true).then(function () { channel.server.channels.remove(channel); _this24.channels.remove(channel); }); }); }; // def banMember InternalClient.prototype.banMember = function banMember(user, server) { var length = arguments.length <= 2 || arguments[2] === undefined ? 1 : arguments[2]; user = this.resolver.resolveUser(user); server = this.resolver.resolveServer(server); return this.apiRequest("put", _Constants.Endpoints.SERVER_BANS(server.id) + "/" + user.id + "?delete-message-days=" + length, true); }; // def unbanMember InternalClient.prototype.unbanMember = function unbanMember(user, server) { server = this.resolver.resolveServer(server); user = this.resolver.resolveUser(user); return this.apiRequest("del", _Constants.Endpoints.SERVER_BANS(server.id) + "/" + user.id, true); }; // def kickMember InternalClient.prototype.kickMember = function kickMember(user, server) { user = this.resolver.resolveUser(user); server = this.resolver.resolveServer(server); return this.apiRequest("del", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true); }; // def moveMember InternalClient.prototype.moveMember = function moveMember(user, channel) { var _this25 = this; user = this.resolver.resolveUser(user); return this.resolver.resolveChannel(channel).then(function (channel) { var server = channel.server; // Make sure `channel` is a voice channel if (channel.type !== "voice") { throw new Error("Can't moveMember into a non-voice channel"); } else { return _this25.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true, { channel_id: channel.id }).then(function (res) { user.voiceChannel = channel; return res; }); } }); }; // def muteMember InternalClient.prototype.muteMember = function muteMember(user, server) { user = this.resolver.resolveUser(user); server = this.resolver.resolveServer(server); return this.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true, { mute: true }); }; // def unmuteMember InternalClient.prototype.unmuteMember = function unmuteMember(user, server) { user = this.resolver.resolveUser(user); server = this.resolver.resolveServer(server); return this.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true, { mute: false }); }; // def deafenMember InternalClient.prototype.deafenMember = function deafenMember(user, server) { user = this.resolver.resolveUser(user); server = this.resolver.resolveServer(server); return this.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true, { deaf: true }); }; // def undeafenMember InternalClient.prototype.undeafenMember = function undeafenMember(user, server) { user = this.resolver.resolveUser(user); server = this.resolver.resolveServer(server); return this.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + user.id, true, { deaf: false }); }; // def setNickname InternalClient.prototype.setNickname = function setNickname(server, nick, user) { nick = nick || ""; user = this.resolver.resolveUser(user); server = this.resolver.resolveServer(server); return this.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(server.id) + "/" + (user.id === this.user.id ? "@me/nick" : user.id), true, { nick: nick }); }; // def createRole InternalClient.prototype.createRole = function createRole(server, data) { var _this26 = this; server = this.resolver.resolveServer(server); return this.apiRequest("post", _Constants.Endpoints.SERVER_ROLES(server.id), true).then(function (res) { var role = server.roles.add(new _StructuresRole2["default"](res, server, _this26.client)); if (data) { return _this26.updateRole(role, data); } return role; }); }; // def updateRole InternalClient.prototype.updateRole = function updateRole(role, data) { var _this27 = this; role = this.resolver.resolveRole(role); var server = this.resolver.resolveServer(role.server); var newData = { color: data.color || role.color, hoist: data.hoist || role.hoist, name: data.name || role.name, position: data.position || role.position, permissions: role.permissions || 0 }; if (data.permissions) { newData.permissions = 0; for (var _iterator5 = data.permissions, _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; if (perm instanceof String || typeof perm === "string") { newData.permissions |= _Constants.Permissions[perm] || 0; } else { newData.permissions |= perm; } } } return this.apiRequest("patch", _Constants.Endpoints.SERVER_ROLES(server.id) + "/" + role.id, true, newData).then(function (res) { return server.roles.update(role, new _StructuresRole2["default"](res, server, _this27.client)); }); }; // def deleteRole InternalClient.prototype.deleteRole = function deleteRole(role) { if (role.server.id === role.id) { return Promise.reject(new Error("Stop trying to delete the @everyone role. It is futile")); } else { return this.apiRequest("del", _Constants.Endpoints.SERVER_ROLES(role.server.id) + "/" + role.id, true); } }; //def addMemberToRole InternalClient.prototype.addMemberToRole = function addMemberToRole(member, roles) { var _this28 = this; member = this.resolver.resolveUser(member); if (!member) { return Promise.reject(new Error("user not found")); } if (!Array.isArray(roles) || roles.length === 0) { roles = this.resolver.resolveRole(roles); if (roles) { roles = [roles]; } else { return Promise.reject(new Error("invalid array of roles")); } } else { roles = roles.map(function (r) { return _this28.resolver.resolveRole(r); }); } if (roles.some(function (role) { return !role.server.memberMap[member.id]; })) { return Promise.reject(new Error("Role does not exist on same server as member")); } var roleIDs = roles[0].server.memberMap[member.id].roles.map(function (r) { return r && r.id || r; }); for (var i = 0; i < roles.length; i++) { if (! ~roleIDs.indexOf(roles[i].id)) { roleIDs.push(roles[i].id); }; }; return this.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(roles[0].server.id) + "/" + member.id, true, { roles: roleIDs }); }; InternalClient.prototype.memberHasRole = function memberHasRole(member, role) { role = this.resolver.resolveRole(role); member = this.resolver.resolveUser(member); if (!role) { throw new Error("invalid role"); } if (!member) { throw new Error("user not found"); } var roledata = role.server.rolesOf(member); if (roledata) { for (var _iterator6 = roledata, _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 r = _ref6; if (r.id == role.id) { return r; } } } return null; }; //def removeMemberFromRole InternalClient.prototype.removeMemberFromRole = function removeMemberFromRole(member, roles) { var _this29 = this; member = this.resolver.resolveUser(member); if (!member) { return Promise.reject(new Error("user not found")); } if (!Array.isArray(roles) || roles.length === 0) { roles = this.resolver.resolveRole(roles); if (roles) { roles = [roles]; } else { return Promise.reject(new Error("invalid array of roles")); } } else { roles = roles.map(function (r) { return _this29.resolver.resolveRole(r); }); } var roleIDs = roles[0].server.memberMap[member.id].roles.map(function (r) { return r && r.id || r; }); for (var _iterator7 = roles, _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 role = _ref7; if (!role.server.memberMap[member.id]) { return Promise.reject(new Error("member not in server")); } for (var item in roleIDs) { if (roleIDs[item] === role.id) { roleIDs.splice(item, 1); break; } } } return this.apiRequest("patch", _Constants.Endpoints.SERVER_MEMBERS(roles[0].server.id) + "/" + member.id, true, { roles: roleIDs }); }; // def createInvite InternalClient.prototype.createInvite = function createInvite(chanServ, options) { var _this30 = this; return this.resolver.resolveChannel(chanServ).then(function (channel) { if (!options) { options = { validate: null }; } else { options.max_age = options.maxAge || 0; options.max_uses = options.maxUses || 0; options.temporary = options.temporary || false; options.xkcdpass = options.xkcd || false; } return _this30.apiRequest("post", _Constants.Endpoints.CHANNEL_INVITES(channel.id), true, options).then(function (res) { return new _StructuresInvite2["default"](res, _this30.channels.get("id", res.channel.id), _this30.client); }); }); }; //def deleteInvite InternalClient.prototype.deleteInvite = function deleteInvite(invite) { invite = this.resolver.resolveInviteID(invite); if (!invite) { throw new Error("Not a valid invite"); } return this.apiRequest("del", _Constants.Endpoints.INVITE(invite), true); }; //def getInvite InternalClient.prototype.getInvite = function getInvite(invite) { var _this31 = this; invite = this.resolver.resolveInviteID(invite); if (!invite) { return Promise.reject(new Error("Not a valid invite")); } return this.apiRequest("get", _Constants.Endpoints.INVITE(invite), true).then(function (res) { if (!_this31.channels.has("id", res.channel.id)) { return new _StructuresInvite2["default"](res, null, _this31.client); } return _this31.apiRequest("post", _Constants.Endpoints.CHANNEL_INVITES(res.channel.id), true, { validate: invite }).then(function (res2) { return new _StructuresInvite2["default"](res2, _this31.channels.get("id", res.channel.id), _this31.client); }); }); }; //def getInvites InternalClient.prototype.getInvites = function getInvites(channel) { var _this32 = this; if (!(channel instanceof _StructuresChannel2["default"])) { var server = this.resolver.resolveServer(channel); if (server) { return this.apiRequest("get", _Constants.Endpoints.SERVER_INVITES(server.id), true).then(function (res) { return res.map(function (data) { return new _StructuresInvite2["default"](data, _this32.channels.get("id", data.channel.id), _this32.client); }); }); } } return this.resolver.resolveChannel(channel).then(function (channel) { return _this32.apiRequest("get", _Constants.Endpoints.CHANNEL_INVITES(channel.id), true).then(function (res) { return res.map(function (data) { return new _StructuresInvite2["default"](data, _this32.channels.get("id", data.channel.id), _this32.client); }); }); }); }; //def overwritePermissions InternalClient.prototype.overwritePermissions = function overwritePermissions(channel, role, updated) { var _this33 = this; return this.resolver.resolveChannel(channel).then(function (channel) { if (!channel instanceof _StructuresServerChannel2["default"]) { return Promise.reject(new Error("Not a server channel")); } var data = { allow: 0, deny: 0 }; if (role instanceof String || typeof role === "string") { role = _this33.resolver.resolveUser(role) || _this33.resolver.resolveRole(role); } if (role instanceof _StructuresUser2["default"]) { data.id = role.id; data.type = "member"; } else if (role instanceof _StructuresRole2["default"]) { data.id = role.id; data.type = "role"; } else { return Promise.reject(new Error("Role could not be resolved")); } var previousOverwrite = channel.permissionOverwrites.get("id", data.id); if (previousOverwrite) { data.allow |= previousOverwrite.allow; data.deny |= previousOverwrite.deny; } for (var perm in updated) { if (updated[perm] === true) { data.allow |= _Constants.Permissions[perm] || 0; data.deny &= ~(_Constants.Permissions[perm] || 0); } else if (updated[perm] === false) { data.allow &= ~(_Constants.Permissions[perm] || 0); data.deny |= _Constants.Permissions[perm] || 0; } else { data.allow &= ~(_Constants.Permissions[perm] || 0); data.deny &= ~(_Constants.Permissions[perm] || 0); } } return _this33.apiRequest("put", _Constants.Endpoints.CHANNEL_PERMISSIONS(channel.id) + "/" + data.id, true, data); }); }; //def setStatus InternalClient.prototype.setStatus = function setStatus(idleStatus, game) { if (idleStatus === "online" || idleStatus === "here" || idleStatus === "available") { this.idleStatus = null; } else if (idleStatus === "idle" || idleStatus === "away") { this.idleStatus = Date.now(); } else { this.idleStatus = this.idleStatus || null; //undefined } this.game = game === null ? null : !game ? this.game || null : typeof game === "string" ? { name: game } : game; var packet = { op: 3, d: { idle_since: this.idleStatus, game: this.game } }; this.sendWS(packet); this.user.status = this.idleStatus ? "idle" : "online"; this.user.game = this.game; return Promise.resolve(); }; //def sendTyping InternalClient.prototype.sendTyping = function sendTyping(channel) { var _this34 = this; return this.resolver.resolveChannel(channel).then(function (channel) { return _this34.apiRequest("post", _Constants.Endpoints.CHANNEL(channel.id) + "/typing", true); }); }; //def startTyping InternalClient.prototype.startTyping = function startTyping(channel) { var _this35 = this; return this.resolver.resolveChannel(channel).then(function (channel) { if (_this35.intervals.typing[channel.id]) { // typing interval already exists, leave it alone throw new Error("Already typing in that channel"); } _this35.intervals.typing[channel.id] = setInterval(function () { return _this35.sendTyping(channel)["catch"](function (error) { return _this35.emit("error", error); }); }, 4000); return _this35.sendTyping(channel); }); }; //def stopTyping InternalClient.prototype.stopTyping = function stopTyping(channel) { var _this36 = this; return this.resolver.resolveChannel(channel).then(function (channel) { if (!_this36.intervals.typing[channel.id]) { // typing interval doesn"t exist throw new Error("Not typing in that channel"); } clearInterval(_this36.intervals.typing[channel.id]); _this36.intervals.typing[channel.id] = false; }); }; //def updateDetails InternalClient.prototype.updateDetails = function updateDetails(data) { if (!this.user.bot && !(this.email || data.email)) { throw new Error("Must provide email since a token was used to login"); } var options = { avatar: this.resolver.resolveToBase64(data.avatar) || this.user.avatar, username: data.username || this.user.username }; if (this.email || data.email) { options.email = data.email || this.email; options.new_password = data.newPassword || null; options.password = data.password || this.password; } return this.apiRequest("patch", _Constants.Endpoints.ME, true, options); }; //def setAvatar InternalClient.prototype.setAvatar = function setAvatar(avatar) { return this.updateDetails({ avatar: avatar }); }; //def setUsername InternalClient.prototype.setUsername = function setUsername(username) { return this.updateDetails({ username: username }); }; //def setChannelTopic InternalClient.prototype.setChannelTopic = function setChannelTopic(chann) { var _this37 = this; var topic = arguments.length <= 1 || arguments[1] === undefined ? "" : arguments[1]; return this.resolver.resolveChannel(chann).then(function (channel) { return _this37.apiRequest("patch", _Constants.Endpoints.CHANNEL(channel.id), true, { name: channel.name, position: channel.position, topic: topic }).then(function (res) { return channel.topic = res.topic; }); }); }; //def setChannelName InternalClient.prototype.setChannelName = function setChannelName(chann) { var _this38 = this; var name = arguments.length <= 1 || arguments[1] === undefined ? "discordjs_is_the_best" : arguments[1]; return this.resolver.resolveChannel(chann).then(function (channel) { return _this38.apiRequest("patch", _Constants.Endpoints.CHANNEL(channel.id), true, { name: name, position: channel.position, topic: channel.topic }).then(function (res) { return channel.name = res.name; }); }); }; //def setChannelNameAndTopic InternalClient.prototype.setChannelNameAndTopic = function setChannelNameAndTopic(chann) { var _this39 = this; var name = arguments.length <= 1 || arguments[1] === undefined ? "discordjs_is_the_best" : arguments[1]; var topic = arguments.length <= 2 || arguments[2] === undefined ? "" : arguments[2]; return this.resolver.resolveChannel(chann).then(function (channel) { return _this39.apiRequest("patch", _Constants.Endpoints.CHANNEL(channel.id), true, { name: name, position: channel.position, topic: topic }).then(function (res) { channel.name = res.name; channel.topic = res.topic; }); }); }; //def setTopic InternalClient.prototype.setChannelPosition = function setChannelPosition(chann) { var _this40 = this; var position = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1]; return this.resolver.resolveChannel(chann).then(function (channel) { return _this40.apiRequest("patch", _Constants.Endpoints.CHANNEL(channel.id), true, { name: channel.name, position: position, topic: channel.topic }).then(function (res) { return channel.position = res.position; }); }); }; //def updateChannel InternalClient.prototype.updateChannel = function updateChannel(chann, data) { return this.setChannelNameAndTopic(chann, data.name, data.topic); }; //def addFriend InternalClient.prototype.addFriend = function addFriend(user) { if (this.user.bot) return Promise.reject(new Error("user is a bot, bot's do not have friends support")); var id; if (user instanceof String || typeof user === "string") id = user;else if (user instanceof _StructuresUser2["default"]) { user = this.resolver.resolveUser(user); id = user.id; } else { if (user.username && user.discriminator) // add by username and discriminator (pass in an object) return this.apiRequest("put", _Constants.Endpoints.FRIENDS, true, user);else return Promise.reject("invalid user"); } return this.apiRequest("put", _Constants.Endpoints.FRIENDS + "/" + id, true, {}); }; //def removeFriend InternalClient.prototype.removeFriend = function removeFriend(user) { if (this.user.bot) return Promise.reject(new Error("user is a bot, bot's do not have friends support")); user = this.resolver.resolveUser(user); return this.apiRequest("delete", _Constants.Endpoints.FRIENDS + "/" + user.id, true); }; //def ack InternalClient.prototype.ack = function ack(msg) { msg = this.resolver.resolveMessage(msg); if (!msg) { Promise.reject(new Error("Message does not exist")); } return this.apiRequest("post", _Constants.Endpoints.CHANNEL_MESSAGE(msg.channel.id, msg.id) + "/ack", true); }; InternalClient.prototype.sendWS = function sendWS(object) { if (this.websocket) { this.websocket.send(JSON.stringify(object)); } }; InternalClient.prototype.createWS = function createWS(url) { var _this41 = this; var self = this; var client = self.client; if (this.websocket) { return false; } this.websocket = new _ws2["default"](url); this.websocket.onopen = function () { self.sendWS({ op: 2, d: { token: self.token, v: 3, compress: self.client.options.compress, large_threshold: self.client.options.largeThreshold, properties: { "$os": "discord.js", "$browser": "", "$device": "discord.js", "$referrer": "discord.js", "$referring_domain": "discord.js" } } }); }; this.websocket.onclose = function (code) { self.websocket = null; self.state = _ConnectionState2["default"].DISCONNECTED; self.disconnected(_this41.client.options.autoReconnect); }; this.websocket.onerror = function (e) { client.emit("error", e); self.websocket = null; self.state = _ConnectionState2["default"].DISCONNECTED; self.disconnected(_this41.client.options.autoReconnect); }; this.websocket.onmessage = function (e) { if (e.data instanceof Buffer) { if (!zlib) zlib = require("zlib"); e.data = zlib.inflateSync(e.data).toString(); } var packet, data; try { packet = JSON.parse(e.data); data = packet.d; } catch (e) { client.emit("error", e); return; } client.emit("raw", packet); switch (packet.t) { case _Constants.PacketType.READY: var startTime = Date.now(); self.intervals.kai = setInterval(function () { return self.sendWS({ op: 1, d: Date.now() }); }, data.heartbeat_interval); self.user = self.users.add(new _StructuresUser2["default"](data.user, client)); _this41.forceFetchCount = {}; _this41.forceFetchQueue = []; _this41.forceFetchLength = 1; _this41.autoReconnectInterval = 1000; _this41.sessionID = data.session_id; data.guilds.forEach(function (server) { if (!server.unavailable) { server = self.servers.add(new _StructuresServer2["default"](server, client)); if (self.client.options.forceFetchUsers && server.members && server.members.length < server.memberCount) { self.getGuildMembers(server.id, Math.ceil(server.memberCount / 1000)); } } else { client.emit("debug", "server " + server.id + " was unavailable, could not create (ready)"); self.unavailableServers.add(server); } }); data.private_channels.forEach(function (pm) { self.private_channels.add(new _StructuresPMChannel2["default"](pm, client)); }); if (!data.user.bot) { // bots dont have friends data.relationships.forEach(function (friend) { if (friend.type === 1) { // is a friend self.friends.add(new _StructuresUser2["default"](friend.user, client)); } else if (friend.type === 2) { // incoming friend requests self.blocked_users.add(new _StructuresUser2["default"](friend.user, client)); } else if (friend.type === 3) { // incoming friend requests self.incoming_friend_requests.add(new _StructuresUser2["default"](friend.user, client)); } else if (friend.type === 4) { // outgoing friend requests self.outgoing_friend_requests.add(new _StructuresUser2["default"](friend.user, client)); } else { client.emit("warn", "unknown friend type " + friend.type); } }); } else { self.friends = null; self.blocked_users = null; self.incoming_friend_requests = null; self.outgoing_friend_requests = null; } self.state = _ConnectionState2["default"].READY; client.emit("debug", "ready packet took " + (Date.now() - startTime) + "ms to process"); client.emit("debug", "ready with " + self.servers.length + " servers, " + self.unavailableServers.length + " unavailable servers, " + self.channels.length + " channels and " + self.users.length + " users cached."); self.restartServerCreateTimeout(); break; case _Constants.PacketType.MESSAGE_CREATE: // format: https://discordapi.readthedocs.org/en/latest/reference/channels/messages.html#message-format var channel = self.channels.get("id", data.channel_id) || self.private_channels.get("id", data.channel_id); if (channel) { var msg = channel.messages.add(new _StructuresMessage2["default"](data, channel, client)); channel.lastMessageID = msg.id; if (self.messageAwaits[channel.id + msg.author.id]) { self.messageAwaits[channel.id + msg.author.id].map(function (fn) { return fn(msg); }); self.messageAwaits[channel.id + msg.author.id] = null; client.emit("message", msg, true); //2nd param is isAwaitedMessage } else { client.emit("message", msg); } } else { client.emit("warn", "message created but channel is not cached"); } break; case _Constants.PacketType.MESSAGE_DELETE: var channel = self.channels.get("id", data.channel_id) || self.private_channels.get("id", data.channel_id); if (channel) { // potentially blank var msg = channel.messages.get("id", data.id); client.emit("messageDeleted", msg, channel); if (msg) { channel.messages.remove(msg); } else { client.emit("debug", "message was deleted but message is not cached"); } } else { client.emit("warn", "message was deleted but channel is not cached"); } break; case _Constants.PacketType.MESSAGE_UPDATE: // format https://discordapi.readthedocs.org/en/latest/reference/channels/messages.html#message-format var channel = self.channels.get("id", data.channel_id) || self.private_channels.get("id", data.channel_id); if (channel) { // potentially blank var msg = channel.messages.get("id", data.id); if (msg) { // old message exists data.nonce = data.nonce || msg.nonce; data.attachments = data.attachments || msg.attachments; data.tts = data.tts || msg.tts; data.embeds = data.embeds || msg.embeds; data.timestamp = data.timestamp || msg.timestamp; data.mention_everyone = data.mention_everyone || msg.everyoneMentioned; data.content = data.content || msg.content; data.mentions = data.mentions || msg.mentions; data.author = data.author || msg.author; var nmsg = new _StructuresMessage2["default"](data, channel, client); client.emit("messageUpdated", new _StructuresMessage2["default"](msg, channel, client), nmsg); channel.messages.update(msg, nmsg); } } else { client.emit("warn", "message was updated but channel is not cached"); } break; case _Constants.PacketType.SERVER_CREATE: var server = self.servers.get("id", data.id); if (!server) { if (!data.unavailable) { server = self.servers.add(new _StructuresServer2["default"](data, client)); if (client.readyTime) { client.emit("serverCreated", server); } if (self.client.options.forceFetchUsers && server.large && server.members.length < server.memberCount) { self.getGuildMembers(server.id, Math.ceil(server.memberCount / 1000)); } var unavailable = self.unavailableServers.get("id", server.id); if (unavailable) { self.unavailableServers.remove(unavailable); } self.restartServerCreateTimeout(); } else { client.emit("debug", "server was unavailable, could not create"); } } break; case _Constants.PacketType.SERVER_DELETE: var server = self.servers.get("id", data.id); if (server) { if (!data.unavailable) { client.emit("serverDeleted", server); for (var _iterator8 = server.channels, _isArray8 = Array.isArray(_iterator8), _i8 = 0, _iterator8 = _isArray8 ? _iterator8 : _iterator8[Symbol.iterator]();;) { var _ref8; if (_isArray8) { if (_i8 >= _iterator8.length) break; _ref8 = _iterator8[_i8++]; } else { _i8 = _iterator8.next(); if (_i8.done) break; _ref8 = _i8.value; } var channel = _ref8; self.channels.remove(channel); } self.servers.remove(server); for (var _iterator9 = server.members, _isArray9 = Array.isArray(_iterator9), _i9 = 0, _iterator9 = _isArray9 ? _iterator9 : _iterator9[Symbol.iterator]();;) { var _ref9; if (_isArray9) { if (_i9 >= _iterator9.length) break; _ref9 = _iterator9[_i9++]; } else { _i9 = _iterator9.next(); if (_i9.done) break; _ref9 = _i9.value; } var user = _ref9; var found = false; for (var _iterator10 = self.servers, _isArray10 = Array.isArray(_iterator10), _i10 = 0, _iterator10 = _isArray10 ? _iterator10 : _iterator10[Symbol.iterator]();;) { var _ref10; if (_isArray10) { if (_i10 >= _iterator10.length) break; _ref10 = _iterator10[_i10++]; } else { _i10 = _iterator10.next(); if (_i10.done) break; _ref10 = _i10.value; } var s = _ref10; if (s.members.get("id", user.id)) { found = true; break; } } if (!found) { self.users.remove(user); } } } else { client.emit("debug", "server was unavailable, could not update"); } } else { client.emit("warn", "server was deleted but it was not in the cache"); } break; case _Constants.PacketType.SERVER_UPDATE: var server = self.servers.get("id", data.id); if (server) { // server exists data.members = data.members || []; data.channels = data.channels || []; var newserver = new _StructuresServer2["default"](data, client); newserver.members = server.members; newserver.memberMap = server.memberMap; newserver.channels = server.channels; if (newserver.equalsStrict(server)) { // already the same don't do anything client.emit("debug", "received server update but server already updated"); } else { client.emit("serverUpdated", new _StructuresServer2["default"](server, client), newserver); self.servers.update(server, newserver); } } else if (!server) { client.emit("warn", "server was updated but it was not in the cache"); self.servers.add(new _StructuresServer2["default"](data, client)); client.emit("serverCreated", server); } break; case _Constants.PacketType.CHANNEL_CREATE: var channel = self.channels.get("id", data.id); if (!channel) { var server = self.servers.get("id", data.guild_id); if (server) { var chan = null; if (data.type === "text") { chan = self.channels.add(new _StructuresTextChannel2["default"](data, client, server)); } else { chan = self.channels.add(new _StructuresVoiceChannel2["default"](data, client, server)); } client.emit("channelCreated", server.channels.add(chan)); } else if (data.is_private) { client.emit("channelCreated", self.private_channels.add(new _StructuresPMChannel2["default"](data, client))); } else { client.emit("warn", "channel created but server does not exist"); } } else { client.emit("warn", "channel created but already in cache"); } break; case _Constants.PacketType.CHANNEL_DELETE: var channel = self.channels.get("id", data.id) || self.private_channels.get("id", data.id); if (channel) { if (channel.server) { // accounts for PMs channel.server.channels.remove(channel); self.channels.remove(channel); } else { self.private_channels.remove(channel); } client.emit("channelDeleted", channel); } else { client.emit("warn", "channel deleted but already out of cache?"); } break; case _Constants.PacketType.CHANNEL_UPDATE: var channel = self.channels.get("id", data.id) || self.private_channels.get("id", data.id); if (channel) { if (channel instanceof _StructuresPMChannel2["default"]) { //PM CHANNEL client.emit("channelUpdated", new _StructuresPMChannel2["default"](channel, client), self.private_channels.update(channel, new _StructuresPMChannel2["default"](data, client))); } else { if (channel.server) { if (channel.type === "text") { //TEXT CHANNEL var chan = new _StructuresTextChannel2["default"](data, client, channel.server); chan.messages = channel.messages; client.emit("channelUpdated", channel, chan); channel.server.channels.update(channel, chan); self.channels.update(channel, chan); } else { //VOICE CHANNEL data.members = channel.members; var chan = new _StructuresVoiceChannel2["default"](data, client, channel.server); client.emit("channelUpdated", channel, chan); channel.server.channels.update(channel, chan); self.channels.update(channel, chan); } } else { client.emit("warn", "channel updated but server non-existant"); } } } else { client.emit("warn", "channel updated but not in cache"); } break; case _Constants.PacketType.SERVER_ROLE_CREATE: var server = self.servers.get("id", data.guild_id); if (server) { client.emit("serverRoleCreated", server.roles.add(new _StructuresRole2["default"](data.role, server, client)), server); } else { client.emit("warn", "server role made but server not in cache"); } break; case _Constants.PacketType.SERVER_ROLE_DELETE: var server = self.servers.get("id", data.guild_id); if (server) { var role = server.roles.get("id", data.role_id); if (role) { server.roles.remove(role); client.emit("serverRoleDeleted", role); } else { client.emit("warn", "server role deleted but role not in cache"); } } else { client.emit("warn", "server role deleted but server not in cache"); } break; case _Constants.PacketType.SERVER_ROLE_UPDATE: var server = self.servers.get("id", data.guild_id); if (server) { var role = server.roles.get("id", data.role.id); if (role) { var newRole = new _StructuresRole2["default"](data.role, server, client); client.emit("serverRoleUpdated", new _StructuresRole2["default"](role, server, client), newRole); server.roles.update(role, newRole); } else { client.emit("warn", "server role updated but role not in cache"); } } else { client.emit("warn", "server role updated but server not in cache"); } break; case _Constants.PacketType.SERVER_MEMBER_ADD: var server = self.servers.get("id", data.guild_id); if (server) { server.memberMap[data.user.id] = { roles: data.roles, mute: false, selfMute: false, deaf: false, selfDeaf: false, joinedAt: Date.parse(data.joined_at), nick: data.nick || null }; server.memberCount++; client.emit("serverNewMember", server, server.members.add(self.users.add(new _StructuresUser2["default"](data.user, client)))); } else { client.emit("warn", "server member added but server doesn't exist in cache"); } break; case _Constants.PacketType.SERVER_MEMBER_REMOVE: var server = self.servers.get("id", data.guild_id); if (server) { var user = self.users.get("id", data.user.id); if (user) { client.emit("serverMemberRemoved", server, user); server.memberMap[data.user.id] = null; server.members.remove(user); server.memberCount--; } else { client.emit("warn", "server member removed but user doesn't exist in cache"); } } else { client.emit("warn", "server member removed but server doesn't exist in cache"); } break; case _Constants.PacketType.SERVER_MEMBER_UPDATE: var server = self.servers.get("id", data.guild_id); if (server) { var user = self.users.add(new _StructuresUser2["default"](data.user, client)); if (user) { var oldMember = null; if (server.memberMap[data.user.id]) { oldMember = { roles: server.memberMap[data.user.id].roles, mute: server.memberMap[data.user.id].mute, selfMute: server.memberMap[data.user.id].selfMute, deaf: server.memberMap[data.user.id].deaf, selfDeaf: server.memberMap[data.user.id].selfDeaf, nick: server.memberMap[data.user.id].nick }; } else { server.memberMap[data.user.id] = {}; } server.memberMap[data.user.id].roles = data.roles ? data.roles : server.memberMap[data.user.id].roles; server.memberMap[data.user.id].mute = data.mute || server.memberMap[data.user.id].mute; server.memberMap[data.user.id].selfMute = data.self_mute === undefined ? server.memberMap[data.user.id].selfMute : data.self_mute; server.memberMap[data.user.id].deaf = data.deaf || server.memberMap[data.user.id].deaf; server.memberMap[data.user.id].selfDeaf = data.self_deaf === undefined ? server.memberMap[data.user.id].selfDeaf : data.self_deaf; server.memberMap[data.user.id].nick = data.nick === undefined ? server.memberMap[data.user.id].nick : data.nick || null; client.emit("serverMemberUpdated", server, user, oldMember); } else { client.emit("warn", "server member removed but user doesn't exist in cache"); } } else { client.emit("warn", "server member updated but server doesn't exist in cache"); } break; case _Constants.PacketType.PRESENCE_UPDATE: var user = self.users.add(new _StructuresUser2["default"](data.user, client)); var server = self.servers.get("id", data.guild_id); if (user && server) { server.members.add(user); data.user.username = data.user.username || user.username; data.user.id = data.user.id || user.id; data.user.avatar = data.user.avatar === undefined ? user.avatar : data.user.avatar; data.user.discriminator = data.user.discriminator || user.discriminator; data.user.status = data.status || user.status; data.user.game = data.game; var presenceUser = new _StructuresUser2["default"](data.user, client); if (!presenceUser.equalsStrict(user)) { client.emit("presence", user, presenceUser); self.users.update(user, presenceUser); } } else { client.emit("warn", "presence update but user/server not in cache"); } break; case _Constants.PacketType.USER_UPDATE: var user = self.users.get("id", data.id); if (user) { data.username = data.username || user.username; data.id = data.id || user.id; data.avatar = data.avatar || user.avatar; data.discriminator = data.discriminator || user.discriminator; _this41.email = data.email || _this41.email; var presenceUser = new _StructuresUser2["default"](data, client); client.emit("presence", user, presenceUser); self.users.update(user, presenceUser); } else { client.emit("warn", "user update but user not in cache (this should never happen)"); } break; case _Constants.PacketType.TYPING: var user = self.users.get("id", data.user_id); var channel = self.channels.get("id", data.channel_id) || self.private_channels.get("id", data.channel_id); if (user && channel) { if (user.typing.since) { user.typing.since = Date.now(); user.typing.channel = channel; } else { user.typing.since = Date.now(); user.typing.channel = channel; client.emit("userTypingStarted", user, channel); } setTimeout(function () { if (Date.now() - user.typing.since > 5500) { // they haven't typed since user.typing.since = null; user.typing.channel = null; client.emit("userTypingStopped", user, channel); } }, 6000); } else { client.emit("warn", "user typing but user or channel not existant in cache"); } break; case _Constants.PacketType.SERVER_BAN_ADD: var user = self.users.get("id", data.user.id); var server = self.servers.get("id", data.guild_id); if (user && server) { client.emit("userBanned", user, server); } else { client.emit("warn", "user banned but user/server not in cache."); } break; case _Constants.PacketType.SERVER_BAN_REMOVE: var user = self.users.get("id", data.user.id); var server = self.servers.get("id", data.guild_id); if (user && server) { client.emit("userUnbanned", user, server); } else { client.emit("warn", "user unbanned but user/server not in cache."); } break; case _Constants.PacketType.VOICE_STATE_UPDATE: var user = self.users.get("id", data.user_id); var server = self.servers.get("id", data.guild_id); var connection = self.voiceConnections.get("server", server); if (user && server) { if (data.channel_id) { // in voice channel var channel = self.channels.get("id", data.channel_id); if (channel && channel.type === "voice") { server.eventVoiceStateUpdate(channel, user, data); } else { client.emit("warn", "voice state channel not in cache"); } } else { // not in voice channel client.emit("voiceLeave", server.eventVoiceLeave(user), user); } } else { client.emit("warn", "voice state update but user or server not in cache"); } if (user && user.id === self.user.id) { // only for detecting self user movements for connections. var connection = self.voiceConnections.get("server", server); // existing connection, perhaps channel moved if (connection && connection.voiceChannel && connection.voiceChannel.id !== data.channel_id) { // moved, update info connection.voiceChannel = self.channels.get("id", data.channel_id); client.emit("voiceMoved", connection.voiceChannel); // Moved to a new channel } } break; case _Constants.PacketType.SERVER_MEMBERS_CHUNK: var server = self.servers.get("id", data.guild_id); if (server) { var testtime = Date.now(); for (var _iterator11 = data.members, _isArray11 = Array.isArray(_iterator11), _i11 = 0, _iterator11 = _isArray11 ? _iterator11 : _iterator11[Symbol.iterator]();;) { var _ref11; if (_isArray11) { if (_i11 >= _iterator11.length) break; _ref11 = _iterator11[_i11++]; } else { _i11 = _iterator11.next(); if (_i11.done) break; _ref11 = _i11.value; } var user = _ref11; server.memberMap[user.user.id] = { roles: user.roles, mute: user.mute, selfMute: false, deaf: user.deaf, selfDeaf: false, joinedAt: Date.parse(user.joined_at), nick: user.nick || null }; server.members.add(self.users.add(new _StructuresUser2["default"](user.user, client))); } if (self.forceFetchCount.hasOwnProperty(server.id)) { if (self.forceFetchCount[server.id] <= 1) { delete self.forceFetchCount[server.id]; self.checkReady(); } else { self.forceFetchCount[server.id]--; } } client.emit("debug", Date.now() - testtime + "ms for " + data.members.length + " user chunk for server with id " + server.id); } else { client.emit("warn", "chunk update received but server not in cache"); } break; case _Constants.PacketType.FRIEND_ADD: if (_this41.user.bot) { return; } if (data.type === 1) { // accepted/got accepted a friend request var inUser = self.incoming_friend_requests.get("id", data.id); if (inUser) { // client accepted another user self.incoming_friend_requests.remove(self.friends.add(new _StructuresUser2["default"](data.user, client))); return; } var outUser = self.outgoing_friend_requests.get("id", data.id); if (outUser) { // another user accepted the client self.outgoing_friend_requests.remove(self.friends.add(new _StructuresUser2["default"](data.user, client))); client.emit("friendRequestAccepted", outUser); return; } } else if (data.type === 2) { // client received block self.blocked_users.add(new _StructuresUser2["default"](data.user, client)); } else if (data.type === 3) { // client received friend request client.emit("friendRequestReceived", self.incoming_friend_requests.add(new _StructuresUser2["default"](data.user, client))); } else if (data.type === 4) { // client sent friend request self.outgoing_friend_requests.add(new _StructuresUser2["default"](data.user, client)); } break; case _Constants.PacketType.FRIEND_REMOVE: if (_this41.user.bot) { return; } var user = self.friends.get("id", data.id); if (user) { self.friends.remove(user); client.emit("friendRemoved", user); return; } user = self.blocked_users.get("id", data.id); if (user) { // they rejected friend request self.blocked_users.remove(user); return; } user = self.incoming_friend_requests.get("id", data.id); if (user) { // they rejected outgoing friend request OR client user manually deleted incoming thru web client/other clients var rejectedUser = self.outgoing_friend_requests.get("id", user.id); if (rejectedUser) { // other person rejected outgoing client.emit("friendRequestRejected", self.outgoing_friend_requests.remove(rejectedUser)); return; } // incoming deleted manually self.incoming_friend_requests.remove(user); return; } user = self.outgoing_friend_requests.get("id", data.id); if (user) { // client cancelled incoming friend request OR client user manually deleted outgoing thru web client/other clients var incomingCancel = self.incoming_friend_requests.get("id", user.id); if (incomingCancel) { // client cancelled incoming self.incoming_friend_requests.remove(user); return; } // outgoing deleted manually self.outgoing_friend_requests.remove(user); return; } break; default: client.emit("unknown", packet); break; } }; }; _createClass(InternalClient, [{ key: "uptime", get: function get() { return this.readyTime ? Date.now() - this.readyTime : null; } }, { key: "userAgent", set: function set(info) { info.full = "DiscordBot (" + info.url + ", " + info.version + ")"; this.userAgentInfo = info; }, get: function get() { return this.userAgentInfo; } }, { key: "voiceConnection", get: function get() { return this.voiceConnections[0]; } }]); return InternalClient; })(); exports["default"] = InternalClient; module.exports = exports["default"];