From b0e413c116305a57c80e3d1d60d2a760f2914eba Mon Sep 17 00:00:00 2001 From: Asad <105254706+AsadHumayun@users.noreply.github.com> Date: Tue, 27 Jan 2026 23:17:01 +0000 Subject: [PATCH] feat(structure): add voice structure (#11400) * feat(structure): add Voice structures * feat(structure): add VoiceState structure * feat(structure): add VoiceRegion structure * chore(structures): lib exports consistency --------- Co-authored-by: Almeida --- packages/structures/src/index.ts | 3 +- packages/structures/src/voice/VoiceRegion.ts | 58 ++++++++++ packages/structures/src/voice/VoiceState.ts | 108 +++++++++++++++++++ packages/structures/src/voice/index.ts | 2 + 4 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 packages/structures/src/voice/VoiceRegion.ts create mode 100644 packages/structures/src/voice/VoiceState.ts create mode 100644 packages/structures/src/voice/index.ts diff --git a/packages/structures/src/index.ts b/packages/structures/src/index.ts index 5150b9fd5..d21ff8bf0 100644 --- a/packages/structures/src/index.ts +++ b/packages/structures/src/index.ts @@ -8,10 +8,11 @@ export * from './invites/index.js'; export * from './messages/index.js'; export * from './polls/index.js'; export * from './soundboards/index.js'; +export * from './stageInstances/index.js'; export * from './stickers/index.js'; export * from './teams/index.js'; export * from './users/index.js'; -export * from './stageInstances/index.js'; +export * from './voice/index.js'; export * from './Structure.js'; export * from './subscriptions/index.js'; export * from './Mixin.js'; diff --git a/packages/structures/src/voice/VoiceRegion.ts b/packages/structures/src/voice/VoiceRegion.ts new file mode 100644 index 000000000..0e7fe7cfa --- /dev/null +++ b/packages/structures/src/voice/VoiceRegion.ts @@ -0,0 +1,58 @@ +import type { APIVoiceRegion } from 'discord-api-types/v10'; +import { Structure } from '../Structure.js'; +import { kData } from '../utils/symbols.js'; +import type { Partialize } from '../utils/types.js'; + +/** + * Represents any voice region on Discord. + * + * @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate` + */ +export class VoiceRegion extends Structure { + /** + * The template used for removing data from the raw data stored for each voice region + */ + public static override readonly DataTemplate: Partial = {}; + + /** + * @param data - The raw data received from the API for the voice region + */ + public constructor(data: Partialize) { + super(data); + } + + /** + * Unique id for the region + */ + public get id() { + return this[kData].id; + } + + /** + * Name of the region + */ + public get name() { + return this[kData].name; + } + + /** + * `true` for a single server that is closest to the current user's client + */ + public get optimal() { + return this[kData].optimal; + } + + /** + * Whether this is a deprecated voice region (avoid switching to these) + */ + public get deprecated() { + return this[kData].deprecated; + } + + /** + * Whether this is a custom voice region (used for events/etc) + */ + public get custom() { + return this[kData].custom; + } +} diff --git a/packages/structures/src/voice/VoiceState.ts b/packages/structures/src/voice/VoiceState.ts new file mode 100644 index 000000000..0969a369e --- /dev/null +++ b/packages/structures/src/voice/VoiceState.ts @@ -0,0 +1,108 @@ +import type { APIVoiceState } from 'discord-api-types/v10'; +import { Structure } from '../Structure.js'; +import { kData } from '../utils/symbols.js'; +import type { Partialize } from '../utils/types.js'; + +/** + * Represents any voice state on Discord. + * + * @typeParam Omitted - Specify the properties that will not be stored in the raw data field as a union, implement via `DataTemplate` + * @remarks has substructure `GuildMember` which needs to be instantiated and stored by an extending class using it + */ +export class VoiceState extends Structure { + /** + * The template used for removing data from the raw data stored for each voice state + */ + public static override readonly DataTemplate: Partial = {}; + + /** + * @param data - The raw data received from the API for the voice state + */ + public constructor(data: Partialize) { + super(data); + } + + /** + * The guild id this voice state is for + */ + public get guildId() { + return this[kData].guild_id; + } + + /** + * The channel id this user is connected to + */ + public get channelId() { + return this[kData].channel_id; + } + + /** + * The user id this voice state is for + */ + public get userId() { + return this[kData].user_id; + } + + /** + * The session id for this voice state + */ + public get sessionId() { + return this[kData].session_id; + } + + /** + * Whether this user is deafened by the server + */ + public get deaf() { + return this[kData].deaf; + } + + /** + * Whether this user is muted by the server + */ + public get mute() { + return this[kData].mute; + } + + /** + * Whether this user is locally deafened + */ + public get selfDeaf() { + return this[kData].self_deaf; + } + + /** + * Whether this user is locally muted + */ + public get selfMute() { + return this[kData].self_mute; + } + + /** + * Whether this user is streaming using "Go Live" + */ + public get selfStream() { + return this[kData].self_stream; + } + + /** + * Whether this user's camera is enabled + */ + public get selfVideo() { + return this[kData].self_video; + } + + /** + * Whether this user's permission to speak is denied + */ + public get suppress() { + return this[kData].suppress; + } + + /** + * The time at which the user requested to speak + */ + public get requestToSpeakTimestamp() { + return this[kData].request_to_speak_timestamp; + } +} diff --git a/packages/structures/src/voice/index.ts b/packages/structures/src/voice/index.ts new file mode 100644 index 000000000..4bfdf61d1 --- /dev/null +++ b/packages/structures/src/voice/index.ts @@ -0,0 +1,2 @@ +export * from './VoiceState.js'; +export * from './VoiceRegion.js';