From 57c2a7cdf8ccaf7918aaacb1c30db639949027bb Mon Sep 17 00:00:00 2001 From: Danial Raza Date: Tue, 5 Nov 2024 19:28:05 +0100 Subject: [PATCH] feat: add soundboard --- packages/discord.js/src/client/Client.js | 9 ++ .../src/client/actions/ActionsManager.js | 3 + .../actions/GuildSoundboardSoundCreate.js | 29 +++++ .../actions/GuildSoundboardSoundDelete.js | 29 +++++ .../actions/GuildSoundboardSoundUpdate.js | 34 +++++ .../handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js | 5 + .../handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js | 5 + .../handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js | 5 + .../websocket/handlers/SOUNDBOARD_SOUNDS.js | 24 ++++ .../src/client/websocket/handlers/index.js | 6 + packages/discord.js/src/index.js | 5 + packages/discord.js/src/structures/Guild.js | 9 ++ .../src/structures/SoundboardSound.js | 121 ++++++++++++++++++ .../discord.js/src/structures/VoiceChannel.js | 17 ++- packages/discord.js/src/util/Events.js | 8 ++ packages/discord.js/typings/index.d.ts | 32 +++++ 16 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 packages/discord.js/src/client/actions/GuildSoundboardSoundCreate.js create mode 100644 packages/discord.js/src/client/actions/GuildSoundboardSoundDelete.js create mode 100644 packages/discord.js/src/client/actions/GuildSoundboardSoundUpdate.js create mode 100644 packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js create mode 100644 packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js create mode 100644 packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js create mode 100644 packages/discord.js/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js create mode 100644 packages/discord.js/src/structures/SoundboardSound.js diff --git a/packages/discord.js/src/client/Client.js b/packages/discord.js/src/client/Client.js index 9db2739c3ce3..6ea101bf8628 100644 --- a/packages/discord.js/src/client/Client.js +++ b/packages/discord.js/src/client/Client.js @@ -11,6 +11,8 @@ const ActionsManager = require('./actions/ActionsManager'); const ClientVoiceManager = require('./voice/ClientVoiceManager'); const PacketHandlers = require('./websocket/handlers'); const { DiscordjsError, DiscordjsTypeError, ErrorCodes } = require('../errors'); +// TODO: Uncomment after finishing the manager +// const { BaseSoundboardSoundManager } = require('../managers/BaseSoundboardSoundManager'); const BaseGuildEmojiManager = require('../managers/BaseGuildEmojiManager'); const ChannelManager = require('../managers/ChannelManager'); const GuildManager = require('../managers/GuildManager'); @@ -176,6 +178,13 @@ class Client extends BaseClient { */ this.voice = new ClientVoiceManager(this); + // TODO: Uncomment after finishing the manager + // /** + // * The soundboard sound manager of the client + // * @type {BaseSoundboardSoundManager} + // */ + // this.soundboardSounds = new BaseSoundboardSoundManager(this); + /** * User that the client is logged in as * @type {?ClientUser} diff --git a/packages/discord.js/src/client/actions/ActionsManager.js b/packages/discord.js/src/client/actions/ActionsManager.js index dd305a94804a..6a664dc51531 100644 --- a/packages/discord.js/src/client/actions/ActionsManager.js +++ b/packages/discord.js/src/client/actions/ActionsManager.js @@ -43,6 +43,9 @@ class ActionsManager { this.register(require('./GuildScheduledEventUpdate')); this.register(require('./GuildScheduledEventUserAdd')); this.register(require('./GuildScheduledEventUserRemove')); + this.register(require('./GuildSoundboardSoundCreate')); + this.register(require('./GuildSoundboardSoundDelete')); + this.register(require('./GuildSoundboardSoundUpdate')); this.register(require('./GuildStickerCreate')); this.register(require('./GuildStickerDelete')); this.register(require('./GuildStickerUpdate')); diff --git a/packages/discord.js/src/client/actions/GuildSoundboardSoundCreate.js b/packages/discord.js/src/client/actions/GuildSoundboardSoundCreate.js new file mode 100644 index 000000000000..c77f0e442fc5 --- /dev/null +++ b/packages/discord.js/src/client/actions/GuildSoundboardSoundCreate.js @@ -0,0 +1,29 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildSoundboardSoundCreateAction extends Action { + handle(data) { + const guild = this.client.guilds.cache.get(data.guild_id); + + let soundboardSound; + + if (guild) { + const already = guild.soundboardSounds.cache.has(data.sound_id); + + soundboardSound = guild.soundboardSounds._add(data); + + /** + * Emitted whenever a soundboard sound is created in a guild. + * @event Client#guildSoundboardSoundCreate + * @param {SoundboardSound} soundboardSound The soundboard sound that was created + */ + if (!already) this.client.emit(Events.GuildSoundboardSoundCreate, soundboardSound); + } + + return { soundboardSound }; + } +} + +module.exports = GuildSoundboardSoundCreateAction; diff --git a/packages/discord.js/src/client/actions/GuildSoundboardSoundDelete.js b/packages/discord.js/src/client/actions/GuildSoundboardSoundDelete.js new file mode 100644 index 000000000000..1dadbe526285 --- /dev/null +++ b/packages/discord.js/src/client/actions/GuildSoundboardSoundDelete.js @@ -0,0 +1,29 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildSoundboardSoundDeleteAction extends Action { + handle(data) { + const guild = this.client.guilds.cache.get(data.guild_id); + + let soundboardSound; + + if (guild) { + soundboardSound = guild.soundboardSounds.cache._add(data, false); + + guild.soundboardSounds.cache.delete(soundboardSound.id); + + /** + * Emitted whenever a soundboard sound is deleted in a guild. + * @event Client#guildSoundboardSoundDelete + * @param {SoundboardSound} soundboardSound The soundboard sound that was deleted + */ + this.client.emit(Events.GuildSoundboardSoundDelete, soundboardSound); + } + + return { soundboardSound }; + } +} + +module.exports = GuildSoundboardSoundDeleteAction; diff --git a/packages/discord.js/src/client/actions/GuildSoundboardSoundUpdate.js b/packages/discord.js/src/client/actions/GuildSoundboardSoundUpdate.js new file mode 100644 index 000000000000..d2cda8b277b6 --- /dev/null +++ b/packages/discord.js/src/client/actions/GuildSoundboardSoundUpdate.js @@ -0,0 +1,34 @@ +'use strict'; + +const Action = require('./Action'); +const Events = require('../../util/Events'); + +class GuildSoundboardSoundUpdateAction extends Action { + handle(data) { + const guild = this.client.guilds.cache.get(data.guild_id); + + if (guild) { + let oldSoundboardSound = null; + + const newSoundboardSound = guild.soundboardSounds.cache.get(data.sound_id); + + if (newSoundboardSound) { + oldSoundboardSound = newSoundboardSound._update(data); + + /** + * Emitted whenever a soundboard sound is updated in a guild. + * @event Client#guildSoundboardSoundUpdate + * @param {?SoundboardSound} oldSoundboardSound The soundboard sound before the update + * @param {SoundboardSound} newSoundboardSound The soundboard sound after the update + */ + this.client.emit(Events.GuildSoundboardSoundUpdate, oldSoundboardSound, newSoundboardSound); + } + + return { oldSoundboardSound, newSoundboardSound }; + } + + return { oldSoundboardSound: null, newSoundboardSound: null }; + } +} + +module.exports = GuildSoundboardSoundUpdateAction; diff --git a/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js b/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js new file mode 100644 index 000000000000..24cbe581f51b --- /dev/null +++ b/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_CREATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, { d: data }) => { + client.actions.GuildSoundboardSoundCreate.handle(data); +}; diff --git a/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js b/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js new file mode 100644 index 000000000000..3adafdba77d7 --- /dev/null +++ b/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_DELETE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, { d: data }) => { + client.actions.GuildSoundboardSoundDelete.handle(data); +}; diff --git a/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js b/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js new file mode 100644 index 000000000000..8f9527ac5f85 --- /dev/null +++ b/packages/discord.js/src/client/websocket/handlers/GUILD_SOUNDBOARD_SOUND_UPDATE.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = (client, { d: data }) => { + client.actions.GuildSoundboardSoundUpdate.handle(data); +}; diff --git a/packages/discord.js/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js b/packages/discord.js/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js new file mode 100644 index 000000000000..7e0885c2f2c5 --- /dev/null +++ b/packages/discord.js/src/client/websocket/handlers/SOUNDBOARD_SOUNDS.js @@ -0,0 +1,24 @@ +'use strict'; + +const { Collection } = require('@discordjs/collection'); +const Events = require('../../../util/Events'); + +module.exports = (client, { d: data }) => { + const guild = client.guilds.cache.get(data.guild_id); + + if (!guild) return; + + const soundboardSounds = new Collection(); + + for (const soundboardSound of data.soundboard_sounds) { + soundboardSounds.set(soundboardSound.sound_id, guild.soundboardSounds._add(soundboardSound)); + } + + /** + * Emitted whenever soundboard sounds are received (all soundboard sounds come from the same guild). + * @event Client#soundboardSounds + * @param {Collection} soundboardSounds The sounds received + * @param {Guild} guild The guild related to the soundboard sounds + */ + client.emit(Events.SoundboardSounds, soundboardSounds, guild); +}; diff --git a/packages/discord.js/src/client/websocket/handlers/index.js b/packages/discord.js/src/client/websocket/handlers/index.js index 24c3f86a4aeb..7e04eb5618c5 100644 --- a/packages/discord.js/src/client/websocket/handlers/index.js +++ b/packages/discord.js/src/client/websocket/handlers/index.js @@ -32,6 +32,11 @@ const handlers = Object.fromEntries([ ['GUILD_SCHEDULED_EVENT_UPDATE', require('./GUILD_SCHEDULED_EVENT_UPDATE')], ['GUILD_SCHEDULED_EVENT_USER_ADD', require('./GUILD_SCHEDULED_EVENT_USER_ADD')], ['GUILD_SCHEDULED_EVENT_USER_REMOVE', require('./GUILD_SCHEDULED_EVENT_USER_REMOVE')], + ['GUILD_SOUNDBOARD_SOUND_CREATE', require('./GUILD_SOUNDBOARD_SOUND_CREATE')], + ['GUILD_SOUNDBOARD_SOUND_DELETE', require('./GUILD_SOUNDBOARD_SOUND_DELETE')], + ['GUILD_SOUNDBOARD_SOUND_UPDATE', require('./GUILD_SOUNDBOARD_SOUND_UPDATE')], + // TODO: Uncomment this line after finishing the GUILD_SOUNDBOARD_SOUNDS_UPDATE handler + // ['GUILD_SOUNDBOARD_SOUNDS_UPDATE', require('./GUILD_SOUNDBOARD_SOUNDS_UPDATE')], ['GUILD_STICKERS_UPDATE', require('./GUILD_STICKERS_UPDATE')], ['GUILD_UPDATE', require('./GUILD_UPDATE')], ['INTERACTION_CREATE', require('./INTERACTION_CREATE')], @@ -49,6 +54,7 @@ const handlers = Object.fromEntries([ ['MESSAGE_UPDATE', require('./MESSAGE_UPDATE')], ['PRESENCE_UPDATE', require('./PRESENCE_UPDATE')], ['READY', require('./READY')], + ['SOUNDBOARD_SOUNDS', require('./SOUNDBOARD_SOUNDS')], ['STAGE_INSTANCE_CREATE', require('./STAGE_INSTANCE_CREATE')], ['STAGE_INSTANCE_DELETE', require('./STAGE_INSTANCE_DELETE')], ['STAGE_INSTANCE_UPDATE', require('./STAGE_INSTANCE_UPDATE')], diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index 7c5c17cd63df..a2ef988df4b5 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -56,6 +56,8 @@ exports.ApplicationEmojiManager = require('./managers/ApplicationEmojiManager'); exports.ApplicationCommandPermissionsManager = require('./managers/ApplicationCommandPermissionsManager'); exports.AutoModerationRuleManager = require('./managers/AutoModerationRuleManager'); exports.BaseGuildEmojiManager = require('./managers/BaseGuildEmojiManager'); +// TODO: Uncomment after finishing the manager +// exports.BaseSoundboardSoundManager = require('./managers/BaseSoundboardSoundManager').BaseSoundboardSoundManager; exports.CachedManager = require('./managers/CachedManager'); exports.ChannelManager = require('./managers/ChannelManager'); exports.ClientVoiceManager = require('./client/voice/ClientVoiceManager'); @@ -73,6 +75,8 @@ exports.GuildManager = require('./managers/GuildManager'); exports.GuildMemberManager = require('./managers/GuildMemberManager'); exports.GuildMemberRoleManager = require('./managers/GuildMemberRoleManager'); exports.GuildMessageManager = require('./managers/GuildMessageManager'); +// Uncomment after finishing the manager +// exports.GuildSoundboardSoundManager = require('./managers/GuildSoundboardSoundManager').GuildSoundboardSoundManager; exports.GuildScheduledEventManager = require('./managers/GuildScheduledEventManager'); exports.GuildStickerManager = require('./managers/GuildStickerManager'); exports.GuildTextThreadManager = require('./managers/GuildTextThreadManager'); @@ -190,6 +194,7 @@ exports.RoleSelectMenuInteraction = require('./structures/RoleSelectMenuInteract exports.StringSelectMenuInteraction = require('./structures/StringSelectMenuInteraction'); exports.UserSelectMenuInteraction = require('./structures/UserSelectMenuInteraction'); exports.SKU = require('./structures/SKU').SKU; +exports.SoundboardSound = require('./structures/SoundboardSound').SoundboardSound; exports.StringSelectMenuOptionBuilder = require('./structures/StringSelectMenuOptionBuilder'); exports.StageChannel = require('./structures/StageChannel'); exports.StageInstance = require('./structures/StageInstance').StageInstance; diff --git a/packages/discord.js/src/structures/Guild.js b/packages/discord.js/src/structures/Guild.js index fa11307fca39..da38179b3ca8 100644 --- a/packages/discord.js/src/structures/Guild.js +++ b/packages/discord.js/src/structures/Guild.js @@ -29,6 +29,8 @@ const VoiceStateManager = require('../managers/VoiceStateManager'); const { resolveImage } = require('../util/DataResolver'); const SystemChannelFlagsBitField = require('../util/SystemChannelFlagsBitField'); const { discordSort, getSortableGroupTypes, resolvePartialEmoji } = require('../util/Util'); +// TODO: Uncomment this after finishing the manager +// const { GuildSoundboardSoundManager } = require('../managers/GuildSoundboardSoundManager'); /** * Represents a guild (or a server) on Discord. @@ -106,6 +108,13 @@ class Guild extends AnonymousGuild { */ this.autoModerationRules = new AutoModerationRuleManager(this); + // TODO: Remove this after finishing the manager + // /** + // * A manager of the soundboard sounds of this guild. + // * @type {GuildSoundboardSoundManager} + // */ + // this.soundboardSounds = new GuildSoundboardSoundManager(this); + if (!data) return; if (data.unavailable) { /** diff --git a/packages/discord.js/src/structures/SoundboardSound.js b/packages/discord.js/src/structures/SoundboardSound.js new file mode 100644 index 000000000000..eeb48c32f7cd --- /dev/null +++ b/packages/discord.js/src/structures/SoundboardSound.js @@ -0,0 +1,121 @@ +'use strict'; + +const Base = require('./Base'); + +/** + * Represents a soundboard sound. + * @extends {Base} + */ +class SoundboardSound extends Base { + constructor(client, data) { + super(client); + + /** + * The id of the soundboard sound + * @type {Snowflake|number} + */ + this.soundId = data.sound_id; + + this._patch(data); + } + + _patch(data) { + /** + * Whether this soundboard sound is available + * @type {boolean} + */ + this.available = data.available; + + /** + * The name of the soundboard sound + * @type {string} + */ + this.name = data.name; + + /** + * The volume of the soundboard sound + * @type {number} + */ + this.volume = data.volume; + + if ('emoji_id' in data) { + /** + * The emoji id of the soundboard sound + * @type {?Snowflake} + */ + this.emojiId = data.emojiId; + } else { + this.emojiId ??= null; + } + + if ('emoji_name' in data) { + /** + * The emoji name of the soundboard sound + * @type {?string} + */ + this.emojiName = data.emojiName; + } else { + this.emojiName ??= null; + } + + if ('guild_id' in data) { + /** + * The guild id of the soundboard sound + * @type {?Snowflake} + */ + this.guildId = data.guildId; + } else { + this.guildId ??= null; + } + + if ('user' in data) { + /** + * The user who created this soundboard sound + * @type {?User} + */ + this.user = this.client.users._add(data.user); + } else { + this.user ??= null; + } + } + + /** + * The guild this soundboard sound is part of + * @type {?Guild} + * @readonly + */ + get guild() { + return this.client.guilds.resolve(this.guildId); + } + + /** + * Whether this soundboard sound is the same as another one. + * @param {SoundboardSound|APISoundboardSound} other The soundboard sound to compare it to + * @returns {boolean} + */ + equals(other) { + if (other instanceof SoundboardSound) { + return ( + this.id === other.id && + this.name === other.name && + this.volume === other.volume && + this.emojiId === other.emojiId && + this.emojiName === other.emojiName && + this.guildId === other.guildId && + this.user?.id === other.user?.id + ); + } + + return ( + this.id === other.sound_id && + this.name === other.name && + this.volume === other.volume && + this.emojiId === other.emoji_id && + this.emojiName === other.emoji_name && + this.guildId === other.guild_id && + this.user?.id === other.user?.id + ); + } +} + +exports.SoundboardSound = SoundboardSound; diff --git a/packages/discord.js/src/structures/VoiceChannel.js b/packages/discord.js/src/structures/VoiceChannel.js index d4f33ca1224b..c943cce2cd64 100644 --- a/packages/discord.js/src/structures/VoiceChannel.js +++ b/packages/discord.js/src/structures/VoiceChannel.js @@ -1,6 +1,6 @@ 'use strict'; -const { PermissionFlagsBits } = require('discord-api-types/v10'); +const { PermissionFlagsBits, Routes } = require('discord-api-types/v10'); const BaseGuildVoiceChannel = require('./BaseGuildVoiceChannel'); /** @@ -35,6 +35,21 @@ class VoiceChannel extends BaseGuildVoiceChannel { permissions.has(PermissionFlagsBits.Speak, false) ); } + + /** + * Send a soundboard sound to a voice channel the user is connected to. + * Fires a Voice Channel Effect Send Gateway event. + * @param {SoundboardSound} sound the sound to send + * @returns {void} + */ + async sendSoundboardSound(sound) { + await this.client.rest.post(Routes.sendSoundboardSound(this.id), { + body: { + sound_id: sound.id, + source_guild_id: sound.guildId ?? undefined, + }, + }); + } } /** diff --git a/packages/discord.js/src/util/Events.js b/packages/discord.js/src/util/Events.js index a4b658e5cfba..3d2e5b747aa1 100644 --- a/packages/discord.js/src/util/Events.js +++ b/packages/discord.js/src/util/Events.js @@ -41,6 +41,9 @@ * @property {string} GuildScheduledEventUpdate guildScheduledEventUpdate * @property {string} GuildScheduledEventUserAdd guildScheduledEventUserAdd * @property {string} GuildScheduledEventUserRemove guildScheduledEventUserRemove + * @property {string} GuildSoundboardSoundCreate guildSoundboardSoundCreate + * @property {string} GuildSoundboardSoundDelete guildSoundboardSoundDelete + * @property {string} GuildSoundboardSoundUpdate guildSoundboardSoundUpdate * @property {string} GuildStickerCreate stickerCreate * @property {string} GuildStickerDelete stickerDelete * @property {string} GuildStickerUpdate stickerUpdate @@ -61,6 +64,7 @@ * @property {string} MessageReactionRemoveEmoji messageReactionRemoveEmoji * @property {string} MessageUpdate messageUpdate * @property {string} PresenceUpdate presenceUpdate + * @property {string} SoundboardSounds soundboardSounds * @property {string} StageInstanceCreate stageInstanceCreate * @property {string} StageInstanceDelete stageInstanceDelete * @property {string} StageInstanceUpdate stageInstanceUpdate @@ -124,6 +128,9 @@ module.exports = { GuildScheduledEventUpdate: 'guildScheduledEventUpdate', GuildScheduledEventUserAdd: 'guildScheduledEventUserAdd', GuildScheduledEventUserRemove: 'guildScheduledEventUserRemove', + GuildSoundboardSoundCreate: 'guildSoundboardSoundCreate', + GuildSoundboardSoundDelete: 'guildSoundboardSoundDelete', + GuildSoundboardSoundUpdate: 'guildSoundboardSound', GuildStickerCreate: 'stickerCreate', GuildStickerDelete: 'stickerDelete', GuildStickerUpdate: 'stickerUpdate', @@ -144,6 +151,7 @@ module.exports = { MessageReactionRemoveEmoji: 'messageReactionRemoveEmoji', MessageUpdate: 'messageUpdate', PresenceUpdate: 'presenceUpdate', + SoundboardSounds: 'soundboardSounds', StageInstanceCreate: 'stageInstanceCreate', StageInstanceDelete: 'stageInstanceDelete', StageInstanceUpdate: 'stageInstanceUpdate', diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index ac5df23cbcfc..19e9023d2a74 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -168,6 +168,7 @@ import { GatewayDispatchPayload, VoiceChannelEffectSendAnimationType, GatewayVoiceChannelEffectSendDispatchData, + APISoundboardSound, } from 'discord-api-types/v10'; import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; @@ -3704,6 +3705,30 @@ export class WidgetMember extends Base { public activity: WidgetActivity | null; } +export interface SoundboardSoundEditOptions { + name?: string; + volume?: number | null; + emojiId?: Snowflake | null; + emojiName?: string | null; +} + +export class SoundboardSound extends Base { + private constructor(client: Client, data: APISoundboardSound); + public name: string; + public id: Snowflake | string | number; + public volume: number; + public emojiId: Snowflake | null; + public emojiName: string | null; + public guildId: Snowflake | null; + public get guild(): Guild | null; + public available: boolean; + public user: User | null; + public fetch(): Promise; + public edit(options?: SoundboardSoundEditOptions): Promise; + public delete(reason?: string): Promise; + public equals(other: SoundboardSound | APISoundboardSound): boolean; +} + export class WelcomeChannel extends Base { private constructor(guild: Guild, data: RawWelcomeChannelData); private _emoji: Omit; @@ -5137,6 +5162,9 @@ export interface ClientEvents { guildMembersChunk: [members: ReadonlyCollection, guild: Guild, data: GuildMembersChunk]; guildMemberUpdate: [oldMember: GuildMember | PartialGuildMember, newMember: GuildMember]; guildUpdate: [oldGuild: Guild, newGuild: Guild]; + guildSoundboardSoundCreate: [soundboardSound: SoundboardSound]; + guildSoundboardSoundDelete: [soundboardSound: SoundboardSound]; + guildSoundboardSoundUpdate: [oldSoundboardSound: SoundboardSound | null, newSoundboardSound: SoundboardSound]; inviteCreate: [invite: Invite]; inviteDelete: [invite: Invite]; messageCreate: [message: OmitPartialGroupDMChannel]; @@ -5201,6 +5229,7 @@ export interface ClientEvents { guildScheduledEventDelete: [guildScheduledEvent: GuildScheduledEvent | PartialGuildScheduledEvent]; guildScheduledEventUserAdd: [guildScheduledEvent: GuildScheduledEvent | PartialGuildScheduledEvent, user: User]; guildScheduledEventUserRemove: [guildScheduledEvent: GuildScheduledEvent | PartialGuildScheduledEvent, user: User]; + soundboardSounds: [soundboardSounds: ReadonlyCollection, guild: Guild]; } export interface ClientFetchInviteOptions { @@ -5400,6 +5429,9 @@ export enum Events { GuildScheduledEventDelete = 'guildScheduledEventDelete', GuildScheduledEventUserAdd = 'guildScheduledEventUserAdd', GuildScheduledEventUserRemove = 'guildScheduledEventUserRemove', + guildSoundboardSoundCreate = 'guildSoundboardSoundCreate', + guildSoundboardSoundDelete = 'guildSoundboardSoundDelete', + guildSoundboardSoundUpdate = 'guildSoundboardSoundUpdate', } export enum ShardEvents {