From d6ff9767a114dcb825e8d16b802b38e0c95f029e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Susa=C3=B1a?= Date: Wed, 7 Aug 2024 20:26:47 -0400 Subject: [PATCH] feat: http voice states (#235) * feat: http voice states * fix: ups * fix: typo * fix: structure --- src/api/Routes/guilds.ts | 6 +++++- src/cache/resources/voice-states.ts | 14 +++++++------- src/common/shorters/members.ts | 15 ++++++++++++--- src/structures/GuildMember.ts | 4 ++-- src/structures/VoiceState.ts | 9 +++++++-- src/types/gateway.ts | 6 +++--- src/types/payloads/channel.ts | 2 ++ src/types/payloads/voice.ts | 2 +- src/types/rest/voice.ts | 12 +++++++++++- 9 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/api/Routes/guilds.ts b/src/api/Routes/guilds.ts index d47404a..2c9f9cd 100644 --- a/src/api/Routes/guilds.ts +++ b/src/api/Routes/guilds.ts @@ -15,6 +15,7 @@ import type { RESTGetAPIAuditLogResult, RESTGetAPIAutoModerationRuleResult, RESTGetAPIAutoModerationRulesResult, + RESTGetAPICurrentUserVoiceState, RESTGetAPIGuildBanResult, RESTGetAPIGuildBansQuery, RESTGetAPIGuildBansResult, @@ -53,6 +54,7 @@ import type { RESTGetAPIGuildWidgetJSONResult, RESTGetAPIGuildWidgetSettingsResult, RESTGetAPITemplateResult, + RESTGetAPIUserVoiceState, RESTPatchAPIAutoModerationRuleJSONBody, RESTPatchAPIAutoModerationRuleResult, RESTPatchAPICurrentGuildMemberJSONBody, @@ -313,13 +315,15 @@ export interface GuildRoutes { patch( args: RestArguments, ): Promise; + get(args?: RestArguments): Promise; }; ( - id: string, + userId: string, ): { patch( args: RestArguments, ): Promise; + get(args?: RestArguments): Promise; }; }; stickers: { diff --git a/src/cache/resources/voice-states.ts b/src/cache/resources/voice-states.ts index c5f2155..3bd6b69 100644 --- a/src/cache/resources/voice-states.ts +++ b/src/cache/resources/voice-states.ts @@ -1,14 +1,14 @@ -import type { GatewayVoiceState } from '../../types'; +import type { APIVoiceState } from '../../types'; import type { ReturnCache } from '../..'; import { fakePromise } from '../../common'; import { GuildBasedResource } from './default/guild-based'; import { Transformers, type VoiceStateStructure } from '../../client/transformers'; -export class VoiceStates extends GuildBasedResource { +export class VoiceStates extends GuildBasedResource { namespace = 'voice_state'; //@ts-expect-error - filter(data: GatewayVoiceState, id: string, guild_id: string) { + filter(data: APIVoiceState, id: string, guild_id: string) { return true; } @@ -23,7 +23,7 @@ export class VoiceStates extends GuildBasedResource { ); } - raw(memberId: string, guildId: string): ReturnCache { + raw(memberId: string, guildId: string): ReturnCache { return super.get(memberId, guildId); } @@ -36,7 +36,7 @@ export class VoiceStates extends GuildBasedResource { ); } - bulkRaw(ids: string[], guild: string): ReturnCache { + bulkRaw(ids: string[], guild: string): ReturnCache { return super.bulk(ids, guild); } @@ -46,9 +46,9 @@ export class VoiceStates extends GuildBasedResource { ); } - valuesRaw(guildId: string): ReturnCache { + valuesRaw(guildId: string): ReturnCache { return super.values(guildId); } } -export type VoiceStateResource = Omit & { guild_id: string }; +export type VoiceStateResource = Omit & { guild_id: string }; diff --git a/src/common/shorters/members.ts b/src/common/shorters/members.ts index 2a2b80e..fcffb38 100644 --- a/src/common/shorters/members.ts +++ b/src/common/shorters/members.ts @@ -10,7 +10,7 @@ import { import { PermissionsBitField } from '../../structures/extra/Permissions'; import type { GuildMemberResolvable } from '../types/resolvables'; import { BaseShorter } from './base'; -import { Transformers } from '../../client/transformers'; +import { Transformers, type VoiceStateStructure } from '../../client/transformers'; export class MemberShorter extends BaseShorter { /** @@ -222,8 +222,17 @@ export class MemberShorter extends BaseShorter { return this.client.cache.presences?.get(memberId); } - voice(guildId: string, memberId: string) { - return this.client.cache.voiceStates?.get(memberId, guildId); + async voice(guildId: string, memberId: '@me', force?: boolean): Promise; + async voice(guildId: string, memberId: string, force?: boolean): Promise; + async voice(guildId: string, memberId: string | '@me', force = false) { + if (!force) { + const state = await this.client.cache.voiceStates?.get(memberId, guildId); + if (state) return state; + } + + const state = await this.client.proxy.guilds(guildId)['voice-states'](memberId).get(); + await this.client.cache.voiceStates?.set(memberId, guildId, state); + return Transformers.VoiceState(this.client, state); } /** diff --git a/src/structures/GuildMember.ts b/src/structures/GuildMember.ts index ffa43d3..3dffa73 100644 --- a/src/structures/GuildMember.ts +++ b/src/structures/GuildMember.ts @@ -74,8 +74,8 @@ export class BaseGuildMember extends DiscordBase { return this.client.members.presence(this.id); } - voice() { - return this.client.members.voice(this.guildId, this.id); + voice(force = false) { + return this.client.members.voice(this.guildId, this.id, force); } toString() { diff --git a/src/structures/VoiceState.ts b/src/structures/VoiceState.ts index 788bb6a..8032382 100644 --- a/src/structures/VoiceState.ts +++ b/src/structures/VoiceState.ts @@ -2,14 +2,14 @@ import type { UsingClient } from '../'; import type { VoiceStateResource } from '../cache/resources/voice-states'; import { type GuildMemberStructure, Transformers } from '../client/transformers'; import type { ObjectToLower } from '../common'; -import type { GatewayVoiceState } from '../types'; +import type { APIVoiceState } from '../types'; import { Base } from './extra/Base'; export interface VoiceState extends Base, ObjectToLower> {} export class VoiceState extends Base { protected withMember?: GuildMemberStructure; - constructor(client: UsingClient, data: GatewayVoiceState) { + constructor(client: UsingClient, data: APIVoiceState) { super(client); const { member, ...rest } = data; this.__patchThis(rest); @@ -68,6 +68,11 @@ export class VoiceState extends Base { return this.setChannel(null, reason); } + async fetch(force = false) { + const member = this.withMember ?? (await this.member(force)); + return this.client.members.voice(this.guildId, member.id, force); + } + async setChannel(channel_id: null | string, reason?: string) { const member = await this.client.members.edit(this.guildId, this.userId, { channel_id }, reason); this.channelId = channel_id; diff --git a/src/types/gateway.ts b/src/types/gateway.ts index fce9346..69b631d 100644 --- a/src/types/gateway.ts +++ b/src/types/gateway.ts @@ -26,7 +26,7 @@ import type { GatewayPresenceUpdate as RawGatewayPresenceUpdate, GatewayThreadListSync as RawGatewayThreadListSync, GatewayThreadMembersUpdate as RawGatewayThreadMembersUpdate, - GatewayVoiceState, + APIVoiceState, InviteTargetType, PresenceUpdateStatus, AutoModerationRuleTriggerType, @@ -554,7 +554,7 @@ export interface GatewayGuildCreateDispatchData extends APIGuild { * * See https://discord.com/developers/docs/resources/voice#voice-state-object */ - voice_states: Omit[]; + voice_states: Omit[]; /** * Users in the guild * @@ -1517,7 +1517,7 @@ export type GatewayVoiceStateUpdateDispatch = DataPayload< /** * https://discord.com/developers/docs/topics/gateway-events#voice-state-update */ -export type GatewayVoiceStateUpdateDispatchData = GatewayVoiceState; +export type GatewayVoiceStateUpdateDispatchData = APIVoiceState; /** * https://discord.com/developers/docs/topics/gateway-events#voice-server-update diff --git a/src/types/payloads/channel.ts b/src/types/payloads/channel.ts index 0a61878..2db8543 100644 --- a/src/types/payloads/channel.ts +++ b/src/types/payloads/channel.ts @@ -681,6 +681,8 @@ export enum MessageType { GuildIncidentAlertModeDisabled, GuildIncidentReportRaid, GuildIncidentReportFalseAlarm, + PurchaseNotification = 44, + PollResult = 46, } /** diff --git a/src/types/payloads/voice.ts b/src/types/payloads/voice.ts index 2c94670..a14107c 100644 --- a/src/types/payloads/voice.ts +++ b/src/types/payloads/voice.ts @@ -8,7 +8,7 @@ import type { APIGuildMember } from './guild'; /** * https://discord.com/developers/docs/resources/voice#voice-state-object */ -export interface GatewayVoiceState { +export interface APIVoiceState { /** * The guild id this voice state is for */ diff --git a/src/types/rest/voice.ts b/src/types/rest/voice.ts index c8357a9..ffe61a0 100644 --- a/src/types/rest/voice.ts +++ b/src/types/rest/voice.ts @@ -1,10 +1,20 @@ -import type { APIVoiceRegion } from '../payloads'; +import type { APIVoiceRegion, APIVoiceState } from '../payloads'; /** * https://discord.com/developers/docs/resources/voice#list-voice-regions */ export type RESTGetAPIVoiceRegionsResult = APIVoiceRegion[]; +/** + * https://discord.com/developers/docs/resources/voice#get-current-user-voice-state + */ +export type RESTGetAPICurrentUserVoiceState = RESTGetAPIUserVoiceState; + +/** + * https://discord.com/developers/docs/resources/voice#get-user-voice-state + */ +export type RESTGetAPIUserVoiceState = APIVoiceState; + /** * @deprecated This was exported with the wrong name, use `RESTGetAPIVoiceRegionsResult` instead */