From 1a6e043331aea04de307a71d2e50e9680d1a5ae3 Mon Sep 17 00:00:00 2001 From: bsian03 Date: Fri, 7 Jan 2022 01:21:33 +0000 Subject: [PATCH] feat(timeout): Timeout and Moderate Members permission (#1317) --- index.d.ts | 8 ++++++-- lib/Client.js | 2 ++ lib/Constants.js | 6 ++++-- lib/gateway/Shard.js | 2 ++ lib/structures/Guild.js | 1 + lib/structures/Member.js | 10 ++++++++++ 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/index.d.ts b/index.d.ts index 9aedba5ee..aa30ff952 100644 --- a/index.d.ts +++ b/index.d.ts @@ -649,6 +649,7 @@ declare namespace Eris { } interface OldMember { avatar: string | null; + communicationDisabledUntil: number | null; nick: string | null; pending?: boolean; premiumSince: number; @@ -1033,6 +1034,7 @@ declare namespace Eris { } interface MemberOptions { channelID?: string | null; + communicationDisabledUntil?: Date | null; deaf?: boolean; mute?: boolean; nick?: string | null; @@ -1803,10 +1805,11 @@ declare namespace Eris { useExternalStickers: 137438953472n; sendMessagesInThreads: 274877906944n; startEmbeddedActivities: 549755813888n; - allGuild: 2080899262n; + moderateMembers: 1099511627776n; + allGuild: 1101592527038n; allText: 518349388881n; allVoice: 554385278737n; - all: 1073741823999n; + all: 1228360646655n; }; PremiumTiers: { NONE: 0; @@ -3029,6 +3032,7 @@ declare namespace Eris { bannerURL: string | null; bot: boolean; clientStatus?: ClientStatus; + communicationDisabledUntil: number | null; createdAt: number; defaultAvatar: string; defaultAvatarURL: string; diff --git a/lib/Client.js b/lib/Client.js index 5c7ef6afa..66988a4d4 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1503,6 +1503,7 @@ class Client extends EventEmitter { * @arg {String} memberID The ID of the member (you can use "@me" if you are only editing the bot user's nickname) * @arg {Object} options The properties to edit * @arg {String?} [options.channelID] The ID of the voice channel to move the member to (must be in voice). Set to `null` to disconnect the member + * @arg {Date?} [options.communicationDisabledUntil] When the user's timeout should expire. Set to `null` to instantly remove timeout * @arg {Boolean} [options.deaf] Server deafen the member * @arg {Boolean} [options.mute] Server mute the member * @arg {String} [options.nick] Set the member's server nickname, "" to remove @@ -1517,6 +1518,7 @@ class Client extends EventEmitter { mute: options.mute, deaf: options.deaf, channel_id: options.channelID, + communication_disabled_until: options.communicationDisabledUntil, reason: reason }).then((member) => new Member(member, this.guilds.get(guildID), this)); } diff --git a/lib/Constants.js b/lib/Constants.js index f2c17d19f..dc04918ef 100644 --- a/lib/Constants.js +++ b/lib/Constants.js @@ -381,7 +381,8 @@ const Permissions = { createPrivateThreads: 1n << 36n, useExternalStickers: 1n << 37n, sendMessagesInThreads: 1n << 38n, - startEmbeddedActivities: 1n << 39n + startEmbeddedActivities: 1n << 39n, + moderateMembers: 1n << 40n }; Permissions.allGuild = Permissions.kickMembers | Permissions.banMembers @@ -394,7 +395,8 @@ Permissions.allGuild = Permissions.kickMembers | Permissions.manageNicknames | Permissions.manageRoles | Permissions.manageWebhooks - | Permissions.manageEmojisAndStickers; + | Permissions.manageEmojisAndStickers + | Permissions.moderateMembers; Permissions.allText = Permissions.createInstantInvite | Permissions.manageChannels | Permissions.addReactions diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 655ad14c5..2ef157e5b 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -1144,6 +1144,7 @@ class Shard extends EventEmitter { if(member) { oldMember = { avatar: member.avatar, + communicationDisabledUntil: member.communicationDisabledUntil, roles: member.roles, nick: member.nick, premiumSince: member.premiumSince, @@ -1158,6 +1159,7 @@ class Shard extends EventEmitter { * @prop {Member} member The updated member * @prop {Object?} oldMember The old member data, or null if the member wasn't cached * @prop {String?} oldMember.avatar The hash of the member's guild avatar, or null if no guild avatar + * @prop {Number?} communicationDisabledUntil Timestamp of previous timeout expiry. If `null`, the member was not timed out * @prop {Array} oldMember.roles An array of role IDs this member is a part of * @prop {String?} oldMember.nick The server nickname of the member * @prop {Number} oldMember.premiumSince Timestamp of when the member boosted the guild diff --git a/lib/structures/Guild.js b/lib/structures/Guild.js index e04f4b372..433d99294 100644 --- a/lib/structures/Guild.js +++ b/lib/structures/Guild.js @@ -685,6 +685,7 @@ class Guild extends Base { * @arg {String} memberID The ID of the member (use "@me" to edit the current bot user) * @arg {Object} options The properties to edit * @arg {String?} [options.channelID] The ID of the voice channel to move the member to (must be in voice). Set to `null` to disconnect the member + * @arg {Date?} [options.communicationDisabledUntil] When the user's timeout should expire. Set to `null` to instantly remove timeout * @arg {Boolean} [options.deaf] Server deafen the member * @arg {Boolean} [options.mute] Server mute the member * @arg {String} [options.nick] Set the member's guild nickname, "" to remove diff --git a/lib/structures/Member.js b/lib/structures/Member.js index 4085b36a6..02ce7991a 100644 --- a/lib/structures/Member.js +++ b/lib/structures/Member.js @@ -18,6 +18,7 @@ const VoiceState = require("./VoiceState"); * @prop {String} clientStatus.web The member's status on web. Either "online", "idle", "dnd", or "offline". Will be "online" for bots * @prop {String} clientStatus.desktop The member's status on desktop. Either "online", "idle", "dnd", or "offline". Will be "offline" for bots * @prop {String} clientStatus.mobile The member's status on mobile. Either "online", "idle", "dnd", or "offline". Will be "offline" for bots +* @prop {Number?} communicationDisabledUntil Timestamp of timeout expiry. If `null`, the member is not timed out * @prop {Number} createdAt Timestamp of user creation * @prop {String} defaultAvatar The hash for the default avatar of a user if there is no avatar set * @prop {String} defaultAvatarURL The URL of the user's default avatar @@ -105,6 +106,13 @@ class Member extends Base { if(data.avatar !== undefined) { this.avatar = data.avatar; } + if(data.communication_disabled_until !== undefined) { + if(data.communication_disabled_until !== null) { + this.communicationDisabledUntil = Date.parse(data.communication_disabled_until); + } else { + this.communicationDisabledUntil = data.communication_disabled_until; + } + } } get accentColor() { @@ -202,6 +210,7 @@ class Member extends Base { * Edit the guild member * @arg {Object} options The properties to edit * @arg {String?} [options.channelID] The ID of the voice channel to move the member to (must be in voice). Set to `null` to disconnect the member + * @arg {Date?} [options.communicationDisabledUntil] When the user's timeout should expire. Set to `null` to instantly remove timeout * @arg {Boolean} [options.deaf] Server deafen the user * @arg {Boolean} [options.mute] Server mute the user * @arg {String} [options.nick] Set the user's server nickname, "" to remove @@ -244,6 +253,7 @@ class Member extends Base { toJSON(props = []) { return super.toJSON([ "activities", + "communicationDisabledUntil", "joinedAt", "nick", "pending",