const User = require('./User'); const Collection = require('../util/Collection'); /** * Represents the logged in client's Discord user * @extends {User} */ class ClientUser extends User { setup(data) { super.setup(data); /** * Whether or not this account has been verified * @type {boolean} */ this.verified = data.verified; /** * The email of this account * @type {string} */ this.email = data.email; this.localPresence = {}; this._typing = new Map(); /** * A Collection of friends for the logged in user. * This is only filled when using a user account. * @type {Collection} */ this.friends = new Collection(); /** * A Collection of blocked users for the logged in user. * This is only filled when using a user account. * @type {Collection} */ this.blocked = new Collection(); /** * A Collection of notes for the logged in user. * This is only filled when using a user account. * @type {Collection} */ this.notes = new Collection(); } edit(data) { return this.client.rest.methods.updateCurrentUser(data); } /** * Set the username of the logged in Client. * Changing usernames in Discord is heavily rate limited, with only 2 requests * every hour. Use this sparingly! * @param {string} username The new username * @param {string} [password] Current password (only for user accounts) * @returns {Promise} * @example * // set username * client.user.setUsername('discordjs') * .then(user => console.log(`My new username is ${user.username}`)) * .catch(console.error); */ setUsername(username, password) { return this.client.rest.methods.updateCurrentUser({ username }, password); } /** * Changes the email for the client user's account. * This is only available when using a user account. * @param {string} email New email to change to * @param {string} password Current password * @returns {Promise} * @example * // set email * client.user.setEmail('bob@gmail.com', 'some amazing password 123') * .then(user => console.log(`My new email is ${user.email}`)) * .catch(console.error); */ setEmail(email, password) { return this.client.rest.methods.updateCurrentUser({ email }, password); } /** * Changes the password for the client user's account. * This is only available when using a user account. * @param {string} newPassword New password to change to * @param {string} oldPassword Current password * @returns {Promise} * @example * // set password * client.user.setPassword('some new amazing password 456', 'some amazing password 123') * .then(user => console.log('New password set!')) * .catch(console.error); */ setPassword(newPassword, oldPassword) { return this.client.rest.methods.updateCurrentUser({ password: newPassword }, oldPassword); } /** * Set the avatar of the logged in Client. * @param {BufferResolvable|Base64Resolvable} avatar The new avatar * @returns {Promise} * @example * // set avatar * client.user.setAvatar('./avatar.png') * .then(user => console.log(`New avatar set!`)) * .catch(console.error); */ setAvatar(avatar) { if (avatar.startsWith('data:')) { return this.client.rest.methods.updateCurrentUser({ avatar }); } else { return this.client.resolver.resolveBuffer(avatar).then(data => this.client.rest.methods.updateCurrentUser({ avatar: data }) ); } } /** * Set the status of the logged in user. * @param {string} status can be `online`, `idle`, `invisible` or `dnd` (do not disturb) * @returns {Promise} */ setStatus(status) { return this.setPresence({ status }); } /** * Set the current game of the logged in user. * @param {string} game the game being played * @param {string} [streamingURL] an optional URL to a twitch stream, if one is available. * @returns {Promise} */ setGame(game, streamingURL) { return this.setPresence({ game: { name: game, url: streamingURL, } }); } /** * Set/remove the AFK flag for the current user. * @param {boolean} afk whether or not the user is AFK. * @returns {Promise} */ setAFK(afk) { return this.setPresence({ afk }); } /** * Fetches messages that mentioned the client's user * @param {Object} [options] Options for the fetch * @param {number} [options.limit=25] Maximum number of mentions to retrieve * @param {boolean} [options.roles=true] Whether to include role mentions * @param {boolean} [options.everyone=true] Whether to include everyone/here mentions * @param {Guild|string} [options.guild] Limit the search to a specific guild * @returns {Promise} */ fetchMentions(options = { limit: 25, roles: true, everyone: true, guild: null }) { return this.client.rest.methods.fetchMentions(options); } /** * Send a friend request * This is only available when using a user account. * @param {UserResolvable} user The user to send the friend request to. * @returns {Promise} The user the friend request was sent to. */ addFriend(user) { user = this.client.resolver.resolveUser(user); return this.client.rest.methods.addFriend(user); } /** * Remove a friend * This is only available when using a user account. * @param {UserResolvable} user The user to remove from your friends * @returns {Promise} The user that was removed */ removeFriend(user) { user = this.client.resolver.resolveUser(user); return this.client.rest.methods.removeFriend(user); } /** * Creates a guild * This is only available when using a user account. * @param {string} name The name of the guild * @param {string} region The region for the server * @param {BufferResolvable|Base64Resolvable} [icon=null] The icon for the guild * @returns {Promise} The guild that was created */ createGuild(name, region, icon = null) { if (!icon) return this.client.rest.methods.createGuild({ name, icon, region }); if (icon.startsWith('data:')) { return this.client.rest.methods.createGuild({ name, icon, region }); } else { return this.client.resolver.resolveBuffer(icon).then(data => this.client.rest.methods.createGuild({ name, icon: data, region }) ); } } /** * Set the full presence of the current user. * @param {Object} data the data to provide * @returns {Promise} */ setPresence(data) { // {"op":3,"d":{"status":"dnd","since":0,"game":null,"afk":false}} return new Promise(resolve => { let status = this.localPresence.status || this.presence.status; let game = this.localPresence.game; let afk = this.localPresence.afk || this.presence.afk; if (!game && this.presence.game) { game = { name: this.presence.game.name, type: this.presence.game.type, url: this.presence.game.url, }; } if (data.status) { if (typeof data.status !== 'string') throw new TypeError('Status must be a string'); status = data.status; } if (data.game) { game = data.game; if (game.url) game.type = 1; } if (typeof data.afk !== 'undefined') afk = data.afk; afk = Boolean(afk); this.localPresence = { status, game, afk }; this.localPresence.since = 0; this.localPresence.game = this.localPresence.game || null; this.client.ws.send({ op: 3, d: this.localPresence, }); this.client._setPresence(this.id, this.localPresence); resolve(this); }); } } module.exports = ClientUser;