diff --git a/index.d.ts b/index.d.ts index 2f62cfb82..844d731ce 100644 --- a/index.d.ts +++ b/index.d.ts @@ -135,7 +135,9 @@ declare namespace Eris { type ActivityType = BotActivityType | Constants["ActivityTypes"]["CUSTOM"]; type BotActivityType = Constants["ActivityTypes"][Exclude]; type FriendSuggestionReasons = { name: string; platform_type: string; type: number }[]; - type Status = "online" | "idle" | "dnd" | "offline"; + type Status = "online" | "idle" | "dnd"; + type SelfStatus = Status | "invisible"; + type UserStatus = Status | "offline"; // Selfbot type ConnectionVisibilityTypes = Constants["ConnectionVisibilityTypes"][keyof Constants["ConnectionVisibilityTypes"]]; @@ -526,6 +528,7 @@ declare namespace Eris { } interface EmbedVideo { height?: number; + proxy_url?: string; url?: string; width?: number; } @@ -683,7 +686,7 @@ declare namespace Eris { callDelete: [call: Call]; callRing: [call: Call]; callUpdate: [call: Call, oldCall: OldCall]; - channelCreate: [channel: AnyChannel]; + channelCreate: [channel: AnyGuildChannel]; channelDelete: [channel: AnyChannel]; channelPinUpdate: [channel: TextableChannel, timestamp: number, oldTimestamp: number]; channelRecipientAdd: [channel: GroupChannel, user: User]; @@ -1250,17 +1253,17 @@ declare namespace Eris { activities: Activity[] | null; afk: boolean; since: number | null; - status: Status; + status: SelfStatus; } interface ClientStatus { - desktop: Status; - mobile: Status; - web: Status; + desktop: UserStatus; + mobile: UserStatus; + web: UserStatus; } interface Presence { activities?: Activity[]; clientStatus?: ClientStatus; - status?: Status; + status?: UserStatus; } // Role @@ -1808,10 +1811,10 @@ declare namespace Eris { sendMessagesInThreads: 274877906944n; startEmbeddedActivities: 549755813888n; moderateMembers: 1099511627776n; - allGuild: 1101592527038n; - allText: 518349388881n; + allGuild: 1110182461630n; + allText: 535529258065n; allVoice: 554385278737n; - all: 1228360646655n; + all: 2199023255551n; }; PremiumTiers: { NONE: 0; @@ -2312,7 +2315,7 @@ declare namespace Eris { ): Promise; editSelfSettings(data: UserSettings): Promise; editStageInstance(channelID: string, options: StageInstanceOptions): Promise; - editStatus(status: Status, activities?: ActivityPartial[] | ActivityPartial): void; + editStatus(status: SelfStatus, activities?: ActivityPartial[] | ActivityPartial): void; editStatus(activities?: ActivityPartial[] | ActivityPartial): void; editUserNote(userID: string, note: string): Promise; editWebhook( @@ -3310,7 +3313,7 @@ declare namespace Eris { createGuild(_guild: Guild): Guild; disconnect(options?: { reconnect?: boolean | "auto" }, error?: Error): void; editAFK(afk: boolean): void; - editStatus(status: Status, activities?: ActivityPartial[] | ActivityPartial): void; + editStatus(status: SelfStatus, activities?: ActivityPartial[] | ActivityPartial): void; editStatus(activities?: ActivityPartial[] | ActivityPartial): void; // @ts-ignore: Method override emit(event: string, ...args: any[]): void; diff --git a/lib/Client.js b/lib/Client.js index 2dc7264c8..90a2b1092 100644 --- a/lib/Client.js +++ b/lib/Client.js @@ -1093,7 +1093,7 @@ class Client extends EventEmitter { return Promise.resolve(); } if(messageIDs.length === 1) { - return this.deleteMessage(channelID, messageIDs[0]); + return this.deleteMessage(channelID, messageIDs[0], reason); } const oldestAllowedSnowflake = (Date.now() - 1421280000000) * 4194304; @@ -1106,7 +1106,7 @@ class Client extends EventEmitter { return this.requestHandler.request("POST", Endpoints.CHANNEL_BULK_DELETE(channelID), true, { messages: messageIDs.splice(0, 100), reason: reason - }).then(() => this.deleteMessages(channelID, messageIDs)); + }).then(() => this.deleteMessages(channelID, messageIDs, reason)); } return this.requestHandler.request("POST", Endpoints.CHANNEL_BULK_DELETE(channelID), true, { messages: messageIDs, @@ -1571,7 +1571,7 @@ class Client extends EventEmitter { }); } /** - * Update a user's voice state - See [caveats](https://discord.com/developers/docs/resources/guild#update-others-voice-state-caveats) + * Update a user's voice state - See [caveats](https://discord.com/developers/docs/resources/guild#modify-user-voice-state-caveats) * @arg {String} guildID The ID of the guild * @arg {Object} options The properties to edit * @arg {String} options.channelID The ID of the channel the user is currently in diff --git a/lib/Constants.js b/lib/Constants.js index dc04918ef..bcabd634b 100644 --- a/lib/Constants.js +++ b/lib/Constants.js @@ -396,6 +396,7 @@ Permissions.allGuild = Permissions.kickMembers | Permissions.manageRoles | Permissions.manageWebhooks | Permissions.manageEmojisAndStickers + | Permissions.manageEvents | Permissions.moderateMembers; Permissions.allText = Permissions.createInstantInvite | Permissions.manageChannels @@ -412,6 +413,7 @@ Permissions.allText = Permissions.createInstantInvite | Permissions.manageRoles | Permissions.manageWebhooks | Permissions.useApplicationCommands + | Permissions.manageThreads | Permissions.createPublicThreads | Permissions.createPrivateThreads | Permissions.useExternalStickers diff --git a/lib/gateway/Shard.js b/lib/gateway/Shard.js index 625791334..9bbdf7df3 100644 --- a/lib/gateway/Shard.js +++ b/lib/gateway/Shard.js @@ -140,6 +140,7 @@ class Shard extends EventEmitter { } if(this.ws.readyState !== WebSocket.CLOSED) { + this.ws.removeListener("message", this._onWSMessage); this.ws.removeListener("close", this._onWSClose); try { if(options.reconnect && this.sessionID) { @@ -620,7 +621,7 @@ class Shard extends EventEmitter { * Fired when a user's avatar, discriminator or username changes * @event Client#userUpdate * @prop {User} user The updated user - * @prop {Object?} oldUser The old user data + * @prop {Object?} oldUser The old user data. If the user was uncached, this will be null * @prop {String} oldUser.username The username of the user * @prop {String} oldUser.discriminator The discriminator of the user * @prop {String?} oldUser.avatar The hash of the user's avatar, or null if no avatar @@ -1958,13 +1959,17 @@ class Shard extends EventEmitter { break; } case "USER_UPDATE": { - const user = this.client.users.get(packet.d.id); - const oldUser = { - username: user.username, - discriminator: user.discriminator, - avatar: user.avatar - }; - this.emit("userUpdate", user.update(packet.d), oldUser); + let user = this.client.users.get(packet.d.id); + let oldUser = null; + if(user) { + oldUser = { + username: user.username, + discriminator: user.discriminator, + avatar: user.avatar + }; + } + user = this.client.users.update(packet.d, this.client); + this.emit("userUpdate", user, oldUser); break; } case "RELATIONSHIP_ADD": { diff --git a/lib/structures/Guild.js b/lib/structures/Guild.js index 534cb71f4..aa38a3099 100644 --- a/lib/structures/Guild.js +++ b/lib/structures/Guild.js @@ -761,7 +761,7 @@ class Guild extends Base { } /** - * Update a user's voice state - See [caveats](https://discord.com/developers/docs/resources/guild#update-others-voice-state-caveats) + * Update a user's voice state - See [caveats](https://discord.com/developers/docs/resources/guild#modify-user-voice-state-caveats) * @arg {Object} options The properties to edit * @arg {String} options.channelID The ID of the channel the user is currently in * @arg {Date?} [options.requestToSpeakTimestamp] Sets the user's request to speak - this can only be used when the `userID` param is "@me"