mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-11 00:53:31 +01:00
refactor: remove user bot methods (#2559)
* [WIP] Remove user bots * more backend userbot removal * Add mfaEnabled back * revert client presences store removal * partially revert getAuth changes * remove more no longer used children of ClientUserGuildSettings * fix a bug with this pr and TextBasedChannel.applyToClass * remove a syncGuilds reference * more user bot data handling * various guildSync cleanup * bots can't call logout Had the user/bot portions of the code mixed up. Though, does this need to be a promise anymore? * make ClientManager#destroy() sync It nolonger needs to be a promise, and nothing depended on it being a promise that I can tell. * requested change * Fix massive error * no longer used as it's userbot only
This commit is contained in:
@@ -170,26 +170,6 @@ class ClientApplication extends Base {
|
||||
} });
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the app's secret.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @returns {Promise<ClientApplication>}
|
||||
*/
|
||||
resetSecret() {
|
||||
return this.client.api.oauth2.applications[this.id].reset.post()
|
||||
.then(app => new ClientApplication(this.client, app));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the app's bot token.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @returns {Promise<ClientApplication>}
|
||||
*/
|
||||
resetToken() {
|
||||
return this.client.api.oauth2.applications[this.id].bot.reset.post()
|
||||
.then(app => new ClientApplication(this.client, Object.assign({}, this, { bot: app })));
|
||||
}
|
||||
|
||||
/**
|
||||
* When concatenated with a string, this automatically returns the application's name instead of the
|
||||
* ClientApplication object.
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
const Structures = require('../util/Structures');
|
||||
const Collection = require('../util/Collection');
|
||||
const ClientUserSettings = require('./ClientUserSettings');
|
||||
const ClientUserGuildSettings = require('./ClientUserGuildSettings');
|
||||
const Util = require('../util/Util');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
const Guild = require('./Guild');
|
||||
|
||||
/**
|
||||
* Represents the logged in client's Discord user.
|
||||
@@ -20,75 +15,14 @@ class ClientUser extends Structures.get('User') {
|
||||
*/
|
||||
this.verified = data.verified;
|
||||
|
||||
/**
|
||||
* The email of this account
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {?string}
|
||||
*/
|
||||
this.email = data.email;
|
||||
this._typing = new Map();
|
||||
|
||||
/**
|
||||
* A Collection of friends for the logged in user
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {Collection<Snowflake, User>}
|
||||
*/
|
||||
this.friends = new Collection();
|
||||
|
||||
/**
|
||||
* A Collection of blocked users for the logged in user
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {Collection<Snowflake, User>}
|
||||
*/
|
||||
this.blocked = new Collection();
|
||||
|
||||
/**
|
||||
* A Collection of notes for the logged in user
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {Collection<Snowflake, string>}
|
||||
*/
|
||||
this.notes = new Collection();
|
||||
|
||||
/**
|
||||
* If the user has Discord premium (nitro)
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.premium = typeof data.premium === 'boolean' ? data.premium : null;
|
||||
|
||||
/**
|
||||
* If the user has MFA enabled on their account
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* If the bot's {@link ClientApplication#owner Owner} has MFA enabled on their account
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.mfaEnabled = typeof data.mfa_enabled === 'boolean' ? data.mfa_enabled : null;
|
||||
|
||||
/**
|
||||
* If the user has ever used a mobile device on Discord
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {?boolean}
|
||||
*/
|
||||
this.mobile = typeof data.mobile === 'boolean' ? data.mobile : null;
|
||||
|
||||
/**
|
||||
* Various settings for this user
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {?ClientUserSettings}
|
||||
*/
|
||||
this.settings = data.user_settings ? new ClientUserSettings(this, data.user_settings) : null;
|
||||
|
||||
/**
|
||||
* All of the user's guild settings
|
||||
* <warn>This is only filled when using a user account.</warn>
|
||||
* @type {Collection<Snowflake, ClientUserGuildSettings>}
|
||||
*/
|
||||
this.guildSettings = new Collection();
|
||||
if (data.user_guild_settings) {
|
||||
for (const settings of data.user_guild_settings) {
|
||||
this.guildSettings.set(settings.guild_id, new ClientUserGuildSettings(this.client, settings));
|
||||
}
|
||||
}
|
||||
|
||||
if (data.token) this.client.token = data.token;
|
||||
}
|
||||
|
||||
@@ -101,15 +35,7 @@ class ClientUser extends Structures.get('User') {
|
||||
return this.client.presences.clientPresence;
|
||||
}
|
||||
|
||||
edit(data, passcode) {
|
||||
if (!this.bot) {
|
||||
if (typeof passcode !== 'object') {
|
||||
data.password = passcode;
|
||||
} else {
|
||||
data.code = passcode.mfaCode;
|
||||
data.password = passcode.password;
|
||||
}
|
||||
}
|
||||
edit(data) {
|
||||
return this.client.api.users('@me').patch({ data })
|
||||
.then(newData => {
|
||||
this.client.token = newData.token;
|
||||
@@ -122,7 +48,6 @@ class ClientUser extends Structures.get('User') {
|
||||
* <info>Changing usernames in Discord is heavily rate limited, with only 2 requests
|
||||
* every hour. Use this sparingly!</info>
|
||||
* @param {string} username The new username
|
||||
* @param {string} [password] Current password (only for user accounts)
|
||||
* @returns {Promise<ClientUser>}
|
||||
* @example
|
||||
* // Set username
|
||||
@@ -130,43 +55,8 @@ class ClientUser extends Structures.get('User') {
|
||||
* .then(user => console.log(`My new username is ${user.username}`))
|
||||
* .catch(console.error);
|
||||
*/
|
||||
setUsername(username, password) {
|
||||
return this.edit({ username }, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the email for the client user's account.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @param {string} email New email to change to
|
||||
* @param {string} password Current password
|
||||
* @returns {Promise<ClientUser>}
|
||||
* @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.edit({ email }, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the password for the client user's account.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @param {string} newPassword New password to change to
|
||||
* @param {Object|string} options Object containing an MFA code, password or both.
|
||||
* Can be just a string for the password.
|
||||
* @param {string} [options.oldPassword] Current password
|
||||
* @param {string} [options.mfaCode] Timed MFA Code
|
||||
* @returns {Promise<ClientUser>}
|
||||
* @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, options) {
|
||||
return this.edit({ new_password: newPassword }, { password: options.oldPassword, mfaCode: options.mfaCode });
|
||||
setUsername(username) {
|
||||
return this.edit({ username });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,36 +152,6 @@ class ClientUser extends Structures.get('User') {
|
||||
return this.setPresence({ afk });
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches messages that mentioned the client's user.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @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 {GuildResolvable} [options.guild] Limit the search to a specific guild
|
||||
* @returns {Promise<Message[]>}
|
||||
* @example
|
||||
* // Fetch mentions
|
||||
* client.user.fetchMentions()
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
* @example
|
||||
* // Fetch mentions from a guild
|
||||
* client.user.fetchMentions({
|
||||
* guild: '222078108977594368'
|
||||
* })
|
||||
* .then(console.log)
|
||||
* .catch(console.error);
|
||||
*/
|
||||
fetchMentions(options = {}) {
|
||||
if (options.guild instanceof Guild) options.guild = options.guild.id;
|
||||
Util.mergeDefault({ limit: 25, roles: true, everyone: true, guild: null }, options);
|
||||
|
||||
return this.client.api.users('@me').mentions.get({ query: options })
|
||||
.then(data => data.map(m => this.client.channels.get(m.channel_id).messages.add(m, false)));
|
||||
}
|
||||
|
||||
/**
|
||||
* An object containing either a user or access token, and an optional nickname.
|
||||
* @typedef {Object} GroupDMRecipientOptions
|
||||
@@ -327,16 +187,6 @@ class ClientUser extends Structures.get('User') {
|
||||
return this.client.api.users('@me').channels.post({ data })
|
||||
.then(res => this.client.channels.add(res));
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return super.toJSON({
|
||||
friends: false,
|
||||
blocked: false,
|
||||
notes: false,
|
||||
settings: false,
|
||||
guildSettings: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientUser;
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
const { UserChannelOverrideMap } = require('../util/Constants');
|
||||
|
||||
/**
|
||||
* A wrapper around the ClientUser's channel overrides.
|
||||
*/
|
||||
class ClientUserChannelOverride {
|
||||
constructor(data) {
|
||||
this.patch(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the data contained in this class with new partial data.
|
||||
* @param {Object} data Data to patch this with
|
||||
* @private
|
||||
*/
|
||||
patch(data) {
|
||||
for (const [key, value] of Object.entries(UserChannelOverrideMap)) {
|
||||
if (!data.hasOwnProperty(key)) continue;
|
||||
if (typeof value === 'function') {
|
||||
this[value.name] = value(data[key]);
|
||||
} else {
|
||||
this[value] = data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientUserChannelOverride;
|
||||
@@ -1,60 +0,0 @@
|
||||
const { UserGuildSettingsMap } = require('../util/Constants');
|
||||
const Collection = require('../util/Collection');
|
||||
const ClientUserChannelOverride = require('./ClientUserChannelOverride');
|
||||
|
||||
/**
|
||||
* A wrapper around the ClientUser's guild settings.
|
||||
*/
|
||||
class ClientUserGuildSettings {
|
||||
constructor(client, data) {
|
||||
/**
|
||||
* The client that created the instance of the ClientUserGuildSettings
|
||||
* @name ClientUserGuildSettings#client
|
||||
* @type {Client}
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(this, 'client', { value: client });
|
||||
/**
|
||||
* The ID of the guild these settings are for
|
||||
* @type {Snowflake}
|
||||
*/
|
||||
this.guildID = data.guild_id;
|
||||
this.channelOverrides = new Collection();
|
||||
this.patch(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the data contained in this class with new partial data.
|
||||
* @param {Object} data Data to patch this with
|
||||
* @private
|
||||
*/
|
||||
patch(data) {
|
||||
for (const [key, value] of Object.entries(UserGuildSettingsMap)) {
|
||||
if (!data.hasOwnProperty(key)) continue;
|
||||
if (key === 'channel_overrides') {
|
||||
for (const channel of data[key]) {
|
||||
const override = this.channelOverrides.get(channel.channel_id);
|
||||
if (override) override.patch(channel);
|
||||
else this.channelOverrides.set(channel.channel_id, new ClientUserChannelOverride(channel));
|
||||
}
|
||||
} else if (typeof value === 'function') {
|
||||
this[value.name] = value(data[key]);
|
||||
} else {
|
||||
this[value] = data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a specific property of the guild settings.
|
||||
* @param {string} name Name of property
|
||||
* @param {*} value Value to patch
|
||||
* @returns {Promise<Object>}
|
||||
* @private
|
||||
*/
|
||||
update(name, value) {
|
||||
return this.client.api.users('@me').guilds(this.guildID).settings.patch({ data: { [name]: value } });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientUserGuildSettings;
|
||||
@@ -1,80 +0,0 @@
|
||||
const { UserSettingsMap } = require('../util/Constants');
|
||||
const Util = require('../util/Util');
|
||||
const { Error } = require('../errors');
|
||||
|
||||
/**
|
||||
* A wrapper around the ClientUser's settings.
|
||||
*/
|
||||
class ClientUserSettings {
|
||||
constructor(user, data) {
|
||||
this.user = user;
|
||||
this.patch(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch the data contained in this class with new partial data.
|
||||
* @param {Object} data Data to patch this with
|
||||
* @private
|
||||
*/
|
||||
patch(data) {
|
||||
for (const [key, value] of Object.entries(UserSettingsMap)) {
|
||||
if (!data.hasOwnProperty(key)) continue;
|
||||
if (typeof value === 'function') {
|
||||
this[value.name] = value(data[key]);
|
||||
} else {
|
||||
this[value] = data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a specific property of of user settings.
|
||||
* @param {string} name Name of property
|
||||
* @param {*} value Value to patch
|
||||
* @returns {Promise<Object>}
|
||||
* @private
|
||||
*/
|
||||
update(name, value) {
|
||||
return this.user.client.api.users['@me'].settings.patch({ data: { [name]: value } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the guild in the guild listing.
|
||||
* @param {Guild} guild The guild to move
|
||||
* @param {number} position Absolute or relative position
|
||||
* @param {boolean} [relative=false] Whether to position relatively or absolutely
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
setGuildPosition(guild, position, relative) {
|
||||
const temp = Object.assign([], this.guildPositions);
|
||||
Util.moveElementInArray(temp, guild.id, position, relative);
|
||||
return this.update('guild_positions', temp).then(() => guild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a guild to the list of restricted guilds.
|
||||
* @param {Guild} guild The guild to add
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
addRestrictedGuild(guild) {
|
||||
const temp = Object.assign([], this.restrictedGuilds);
|
||||
if (temp.includes(guild.id)) return Promise.reject(new Error('GUILD_RESTRICTED', true));
|
||||
temp.push(guild.id);
|
||||
return this.update('restricted_guilds', temp).then(() => guild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a guild from the list of restricted guilds.
|
||||
* @param {Guild} guild The guild to remove
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
removeRestrictedGuild(guild) {
|
||||
const temp = Object.assign([], this.restrictedGuilds);
|
||||
const index = temp.indexOf(guild.id);
|
||||
if (index < 0) return Promise.reject(new Error('GUILD_RESTRICTED'));
|
||||
temp.splice(index, 1);
|
||||
return this.update('restricted_guilds', temp).then(() => guild);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ClientUserSettings;
|
||||
@@ -184,16 +184,12 @@ class GroupDMChannel extends Channel {
|
||||
* @param {Object} options Options for this method
|
||||
* @param {UserResolvable} options.user User to add to this Group DM
|
||||
* @param {string} [options.accessToken] Access token to use to add the user to this Group DM
|
||||
* (only available under a bot account)
|
||||
* @param {string} [options.nick] Permanent nickname to give the user (only available under a bot account)
|
||||
* @param {string} [options.nick] Permanent nickname to give the user
|
||||
* @returns {Promise<GroupDMChannel>}
|
||||
*/
|
||||
addUser({ user, accessToken, nick }) {
|
||||
const id = this.client.users.resolveID(user);
|
||||
const data = this.client.user.bot ?
|
||||
{ nick, access_token: accessToken } :
|
||||
{ recipient: id };
|
||||
return this.client.api.channels[this.id].recipients[id].put({ data })
|
||||
return this.client.api.channels[this.id].recipients[id].put({ nick, access_token: accessToken })
|
||||
.then(() => this);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ const Collection = require('../util/Collection');
|
||||
const Util = require('../util/Util');
|
||||
const DataResolver = require('../util/DataResolver');
|
||||
const Snowflake = require('../util/Snowflake');
|
||||
const Shared = require('./shared');
|
||||
const GuildMemberStore = require('../stores/GuildMemberStore');
|
||||
const RoleStore = require('../stores/RoleStore');
|
||||
const GuildEmojiStore = require('../stores/GuildEmojiStore');
|
||||
@@ -352,79 +351,6 @@ class Guild extends Base {
|
||||
return this.client.voice.connections.get(this.id) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The position of this guild
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get position() {
|
||||
if (this.client.user.bot) return null;
|
||||
if (!this.client.user.settings.guildPositions) return null;
|
||||
return this.client.user.settings.guildPositions.indexOf(this.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the guild is muted
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get muted() {
|
||||
if (this.client.user.bot) return null;
|
||||
try {
|
||||
return this.client.user.guildSettings.get(this.id).muted;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of message that should notify you
|
||||
* one of `EVERYTHING`, `MENTIONS`, `NOTHING`
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get messageNotifications() {
|
||||
if (this.client.user.bot) return null;
|
||||
try {
|
||||
return this.client.user.guildSettings.get(this.id).messageNotifications;
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to receive mobile push notifications
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get mobilePush() {
|
||||
if (this.client.user.bot) return null;
|
||||
try {
|
||||
return this.client.user.guildSettings.get(this.id).mobilePush;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to suppress everyone messages
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get suppressEveryone() {
|
||||
if (this.client.user.bot) return null;
|
||||
try {
|
||||
return this.client.user.guildSettings.get(this.id).suppressEveryone;
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `@everyone` role of the guild
|
||||
* @type {?Role}
|
||||
@@ -597,26 +523,6 @@ class Guild extends Base {
|
||||
.then(data => this.members.add(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a search within the entire guild.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @param {MessageSearchOptions} [options={}] Options to pass to the search
|
||||
* @returns {Promise<MessageSearchResult>}
|
||||
* @example
|
||||
* guild.search({
|
||||
* content: 'discord.js',
|
||||
* before: '2016-11-17'
|
||||
* })
|
||||
* .then(res => {
|
||||
* const hit = res.results[0].find(m => m.hit).content;
|
||||
* console.log(`I found: **${hit}**, total results: ${res.total}`);
|
||||
* })
|
||||
* .catch(console.error);
|
||||
*/
|
||||
search(options = {}) {
|
||||
return Shared.search(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* The data for editing a guild.
|
||||
* @typedef {Object} GuildEditData
|
||||
@@ -831,55 +737,6 @@ class Guild extends Base {
|
||||
return this.edit({ splash: await DataResolver.resolveImage(splash), reason });
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the guild in the guild listing.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @param {number} position Absolute or relative position
|
||||
* @param {boolean} [relative=false] Whether to position relatively or absolutely
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
setPosition(position, relative) {
|
||||
if (this.client.user.bot) {
|
||||
return Promise.reject(new Error('FEATURE_USER_ONLY'));
|
||||
}
|
||||
return this.client.user.settings.setGuildPosition(this, position, relative);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks all messages in this guild as read.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
acknowledge() {
|
||||
return this.client.api.guilds(this.id).ack
|
||||
.post({ data: { token: this.client.rest._ackToken } })
|
||||
.then(res => {
|
||||
if (res.token) this.client.rest._ackToken = res.token;
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to allow direct messages from guild members.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @param {boolean} allow Whether to allow direct messages
|
||||
* @returns {Promise<Guild>}
|
||||
*/
|
||||
allowDMs(allow) {
|
||||
if (this.client.user.bot) return Promise.reject(new Error('FEATURE_USER_ONLY'));
|
||||
const settings = this.client.user.settings;
|
||||
if (allow) return settings.removeRestrictedGuild(this);
|
||||
else return settings.addRestrictedGuild(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs this guild (already done automatically every 30 seconds).
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
*/
|
||||
sync() {
|
||||
if (!this.client.user.bot) this.client.syncGuilds([this]);
|
||||
}
|
||||
|
||||
/**
|
||||
* The data needed for updating a channel's position.
|
||||
* @typedef {Object} ChannelPosition
|
||||
|
||||
@@ -6,7 +6,6 @@ const PermissionOverwrites = require('./PermissionOverwrites');
|
||||
const Util = require('../util/Util');
|
||||
const Permissions = require('../util/Permissions');
|
||||
const Collection = require('../util/Collection');
|
||||
const { MessageNotificationTypes } = require('../util/Constants');
|
||||
const { Error, TypeError } = require('../errors');
|
||||
|
||||
/**
|
||||
@@ -564,37 +563,6 @@ class GuildChannel extends Channel {
|
||||
delete(reason) {
|
||||
return this.client.api.channels(this.id).delete({ reason }).then(() => this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the channel is muted
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get muted() {
|
||||
if (this.client.user.bot) return null;
|
||||
try {
|
||||
return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).muted;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of message that should notify you
|
||||
* one of `EVERYTHING`, `MENTIONS`, `NOTHING`, `INHERIT`
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get messageNotifications() {
|
||||
if (this.client.user.bot) return null;
|
||||
try {
|
||||
return this.client.user.guildSettings.get(this.guild.id).channelOverrides.get(this.id).messageNotifications;
|
||||
} catch (err) {
|
||||
return MessageNotificationTypes[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GuildChannel;
|
||||
|
||||
@@ -499,20 +499,6 @@ class Message extends Base {
|
||||
return this.channel.send(content, Object.assign(options, { reply: this.member || this.author }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the message as read.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @returns {Promise<Message>}
|
||||
*/
|
||||
acknowledge() {
|
||||
return this.client.api.channels(this.channel.id).messages(this.id).ack
|
||||
.post({ data: { token: this.client.rest._ackToken } })
|
||||
.then(res => {
|
||||
if (res.token) this.client.rest._ackToken = res.token;
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the webhook used to create this message.
|
||||
* @returns {Promise<?Webhook>}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
const TextBasedChannel = require('./interfaces/TextBasedChannel');
|
||||
const { Presence } = require('./Presence');
|
||||
const UserProfile = require('./UserProfile');
|
||||
const Snowflake = require('../util/Snowflake');
|
||||
const Base = require('./Base');
|
||||
const { Error } = require('../errors');
|
||||
@@ -151,16 +150,6 @@ class User extends Base {
|
||||
return `${this.username}#${this.discriminator}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* The note that is set for the user
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get note() {
|
||||
return this.client.user.notes.get(this.id) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the user is typing in a channel.
|
||||
* @param {ChannelResolvable} channel The channel to check in
|
||||
@@ -222,26 +211,6 @@ class User extends Base {
|
||||
.then(data => this.client.actions.ChannelDelete.handle(data).channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the profile of the user.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @returns {Promise<UserProfile>}
|
||||
*/
|
||||
fetchProfile() {
|
||||
return this.client.api.users(this.id).profile.get().then(data => new UserProfile(this, data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a note for the user.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @param {string} note The note to set for the user
|
||||
* @returns {Promise<User>}
|
||||
*/
|
||||
setNote(note) {
|
||||
return this.client.api.users('@me').notes(this.id).put({ data: { note } })
|
||||
.then(() => this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user is equal to another. It compares ID, username, discriminator, avatar, and bot flags.
|
||||
* It is recommended to compare equality by using `user.id === user2.id` unless you want to compare all properties.
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
const Collection = require('../util/Collection');
|
||||
const { UserFlags } = require('../util/Constants');
|
||||
const UserConnection = require('./UserConnection');
|
||||
const Base = require('./Base');
|
||||
|
||||
/**
|
||||
* Represents a user's profile on Discord.
|
||||
* @extends {Base}
|
||||
*/
|
||||
class UserProfile extends Base {
|
||||
constructor(user, data) {
|
||||
super(user.client);
|
||||
|
||||
/**
|
||||
* The owner of the profile
|
||||
* @type {User}
|
||||
*/
|
||||
this.user = user;
|
||||
|
||||
/**
|
||||
* The guilds that the client user and the user share
|
||||
* @type {Collection<Snowflake, Guild>}
|
||||
*/
|
||||
this.mutualGuilds = new Collection();
|
||||
|
||||
/**
|
||||
* The user's connections
|
||||
* @type {Collection<Snowflake, UserConnection>}
|
||||
*/
|
||||
this.connections = new Collection();
|
||||
|
||||
this._patch(data);
|
||||
}
|
||||
|
||||
_patch(data) {
|
||||
/**
|
||||
* If the user has Discord Premium
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.premium = Boolean(data.premium_since);
|
||||
|
||||
/**
|
||||
* The Bitfield of the users' flags
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this._flags = data.user.flags;
|
||||
|
||||
/**
|
||||
* The date since which the user has had Discord Premium
|
||||
* @type {?Date}
|
||||
*/
|
||||
this.premiumSince = data.premium_since ? new Date(data.premium_since) : null;
|
||||
|
||||
for (const guild of data.mutual_guilds) {
|
||||
if (this.client.guilds.has(guild.id)) {
|
||||
this.mutualGuilds.set(guild.id, this.client.guilds.get(guild.id));
|
||||
}
|
||||
}
|
||||
for (const connection of data.connected_accounts) {
|
||||
this.connections.set(connection.id, new UserConnection(this.user, connection));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The flags the user has
|
||||
* @type {UserFlags[]}
|
||||
* @readonly
|
||||
*/
|
||||
get flags() {
|
||||
const flags = [];
|
||||
for (const [name, flag] of Object.entries(UserFlags)) {
|
||||
if ((this._flags & flag) === flag) flags.push(name);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return super.toJSON({ flags: true });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserProfile;
|
||||
@@ -119,23 +119,6 @@ class TextBasedChannel {
|
||||
return Shared.sendMessage(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a search within the channel.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @param {MessageSearchOptions} [options={}] Options to pass to the search
|
||||
* @returns {Promise<MessageSearchResult>}
|
||||
* @example
|
||||
* channel.search({ content: 'discord.js', before: '2016-11-17' })
|
||||
* .then(res => {
|
||||
* const hit = res.results[0].find(m => m.hit).content;
|
||||
* console.log(`I found: **${hit}**, total results: ${res.total}`);
|
||||
* })
|
||||
* .catch(console.error);
|
||||
*/
|
||||
search(options = {}) {
|
||||
return Shared.search(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a typing indicator in the channel.
|
||||
* @param {number} [count=1] The number of times startTyping should be considered to have been called
|
||||
@@ -273,7 +256,6 @@ class TextBasedChannel {
|
||||
|
||||
/**
|
||||
* Bulk deletes given messages that are newer than two weeks.
|
||||
* <warn>This is only available when using a bot account.</warn>
|
||||
* @param {Collection<Snowflake, Message>|Message[]|Snowflake[]|number} messages
|
||||
* Messages or number of messages to delete
|
||||
* @param {boolean} [filterOld=false] Filter messages to remove those which are older than two weeks automatically
|
||||
@@ -316,28 +298,11 @@ class TextBasedChannel {
|
||||
throw new TypeError('MESSAGE_BULK_DELETE_TYPE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks all messages in this channel as read.
|
||||
* <warn>This is only available when using a user account.</warn>
|
||||
* @returns {Promise<TextChannel|GroupDMChannel|DMChannel>}
|
||||
*/
|
||||
acknowledge() {
|
||||
if (!this.lastMessageID) return Promise.resolve(this);
|
||||
return this.client.api.channels[this.id].messages[this.lastMessageID].ack
|
||||
.post({ data: { token: this.client.rest._ackToken } })
|
||||
.then(res => {
|
||||
if (res.token) this.client.rest._ackToken = res.token;
|
||||
return this;
|
||||
});
|
||||
}
|
||||
|
||||
static applyToClass(structure, full = false, ignore = []) {
|
||||
const props = ['send'];
|
||||
if (full) {
|
||||
props.push(
|
||||
'acknowledge',
|
||||
'lastMessage',
|
||||
'search',
|
||||
'bulkDelete',
|
||||
'startTyping',
|
||||
'stopTyping',
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
const Util = require('../../util/Util');
|
||||
const { TypeError } = require('../../errors');
|
||||
|
||||
/**
|
||||
* @typedef {Object} MessageSearchOptions
|
||||
* @property {string} [content] Message content
|
||||
* @property {Snowflake} [maxID] Maximum ID for the filter
|
||||
* @property {Snowflake} [minID] Minimum ID for the filter
|
||||
* @property {string} [has] One of `link`, `embed`, `file`, `video`, `image`, or `sound`,
|
||||
* or add `-` to negate (e.g. `-file`)
|
||||
* @property {ChannelResolvable} [channel] Channel to limit search to (only for guild search endpoint)
|
||||
* @property {UserResolvable} [author] Author to limit search
|
||||
* @property {string} [authorType] One of `user`, `bot`, `webhook`, or add `-` to negate (e.g. `-webhook`)
|
||||
* @property {string} [sortBy='timestamp'] `timestamp` or `relevant`
|
||||
* @property {string} [sortOrder='descending'] `ascending` or `descending`
|
||||
* @property {number} [contextSize=2] How many messages to get around the matched message (0 to 2)
|
||||
* @property {number} [limit=25] Maximum number of results to get (1 to 25)
|
||||
* @property {number} [offset=0] Offset the "pages" of results (since you can only see 25 at a time)
|
||||
* @property {UserResolvable} [mentions] Mentioned user filter
|
||||
* @property {boolean} [mentionsEveryone] If everyone is mentioned
|
||||
* @property {string} [linkHostname] Filter links by hostname
|
||||
* @property {string} [embedProvider] The name of an embed provider
|
||||
* @property {string} [embedType] one of `image`, `video`, `url`, `rich`, or add `-` to negate (e.g. `-image`)
|
||||
* @property {string} [attachmentFilename] The name of an attachment
|
||||
* @property {string} [attachmentExtension] The extension of an attachment
|
||||
* @property {Date} [before] Date to find messages before
|
||||
* @property {Date} [after] Date to find messages before
|
||||
* @property {Date} [during] Date to find messages during (range of date to date + 24 hours)
|
||||
* @property {boolean} [nsfw=false] Include results from NSFW channels
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MessageSearchResult
|
||||
* @property {number} total Total result count
|
||||
* @property {Array<Message[]>} results Array of message results
|
||||
* The message which has triggered the result will have the `hit` property set to `true`
|
||||
*/
|
||||
|
||||
module.exports = function search(target, options) {
|
||||
if (typeof options === 'string') options = { content: options };
|
||||
if (options.before) {
|
||||
if (!(options.before instanceof Date)) options.before = new Date(options.before);
|
||||
options.maxID = Util.binaryToID((options.before.getTime() - 14200704e5).toString(2) + '0'.repeat(22));
|
||||
}
|
||||
if (options.after) {
|
||||
if (!(options.after instanceof Date)) options.after = new Date(options.after);
|
||||
options.minID = Util.binaryToID((options.after.getTime() - 14200704e5).toString(2) + '0'.repeat(22));
|
||||
}
|
||||
if (options.during) {
|
||||
if (!(options.during instanceof Date)) options.during = new Date(options.during);
|
||||
const t = options.during.getTime() - 14200704e5;
|
||||
options.minID = Util.binaryToID(t.toString(2) + '0'.repeat(22));
|
||||
options.maxID = Util.binaryToID((t + 864e5).toString(2) + '0'.repeat(22));
|
||||
}
|
||||
if (options.channel) options.channel = target.client.channels.resolveID(options.channel);
|
||||
if (options.author) options.author = target.client.users.resolveID(options.author);
|
||||
if (options.mentions) options.mentions = target.client.users.resolveID(options.options.mentions);
|
||||
if (options.sortOrder) {
|
||||
options.sortOrder = { ascending: 'asc', descending: 'desc' }[options.sortOrder] || options.sortOrder;
|
||||
}
|
||||
options = {
|
||||
content: options.content,
|
||||
max_id: options.maxID,
|
||||
min_id: options.minID,
|
||||
has: options.has,
|
||||
channel_id: options.channel,
|
||||
author_id: options.author,
|
||||
author_type: options.authorType,
|
||||
context_size: options.contextSize,
|
||||
sort_by: options.sortBy,
|
||||
sort_order: options.sortOrder,
|
||||
limit: options.limit,
|
||||
offset: options.offset,
|
||||
mentions: options.mentions,
|
||||
mentions_everyone: options.mentionsEveryone,
|
||||
link_hostname: options.linkHostname,
|
||||
embed_provider: options.embedProvider,
|
||||
embed_type: options.embedType,
|
||||
attachment_filename: options.attachmentFilename,
|
||||
attachment_extension: options.attachmentExtension,
|
||||
include_nsfw: options.nsfw,
|
||||
};
|
||||
|
||||
// Lazy load these because some of them use util
|
||||
const Channel = require('../Channel');
|
||||
const Guild = require('../Guild');
|
||||
|
||||
if (!(target instanceof Channel || target instanceof Guild)) throw new TypeError('SEARCH_CHANNEL_TYPE');
|
||||
|
||||
let endpoint = target.client.api[target instanceof Channel ? 'channels' : 'guilds'](target.id).messages().search;
|
||||
return endpoint.get({ query: options }).then(body => {
|
||||
const results = body.messages.map(x =>
|
||||
x.map(m => target.client.channels.get(m.channel_id).messages.add(m, false))
|
||||
);
|
||||
return {
|
||||
total: body.total_results,
|
||||
results,
|
||||
};
|
||||
});
|
||||
};
|
||||
@@ -1,5 +1,4 @@
|
||||
module.exports = {
|
||||
search: require('./Search'),
|
||||
sendMessage: require('./SendMessage'),
|
||||
createMessage: require('./CreateMessage'),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user