From 43ca2dc5617f31fbc8f37ade8303461bd1082f96 Mon Sep 17 00:00:00 2001 From: Slipstream Date: Tue, 10 Jun 2025 20:50:27 -0600 Subject: [PATCH] Add voice region support (#44) Squash and merge PR #44 --- disagreement/client.py | 16 +++++++++++++++- disagreement/enums.py | 30 ++++++++++++++++++++++++++++++ disagreement/http.py | 4 ++++ docs/voice_client.md | 11 +++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) diff --git a/disagreement/client.py b/disagreement/client.py index e43401b..ded4a99 100644 --- a/disagreement/client.py +++ b/disagreement/client.py @@ -22,7 +22,7 @@ from .http import HTTPClient from .gateway import GatewayClient from .shard_manager import ShardManager from .event_dispatcher import EventDispatcher -from .enums import GatewayIntent, InteractionType, GatewayOpcode +from .enums import GatewayIntent, InteractionType, GatewayOpcode, VoiceRegion from .errors import DisagreementException, AuthenticationError from .typing import Typing from .ext.commands.core import CommandHandler @@ -1235,6 +1235,20 @@ class Client: print(f"Failed to fetch channel {channel_id}: {e}") return None + async def fetch_voice_regions(self) -> List[VoiceRegion]: + """Fetches available voice regions.""" + + if self._closed: + raise DisagreementException("Client is closed.") + + data = await self._http.get_voice_regions() + regions = [] + for region in data: + region_id = region.get("id") + if region_id: + regions.append(VoiceRegion(region_id)) + return regions + async def create_webhook( self, channel_id: Snowflake, payload: Dict[str, Any] ) -> "Webhook": diff --git a/disagreement/enums.py b/disagreement/enums.py index 68e59c3..70f06f4 100644 --- a/disagreement/enums.py +++ b/disagreement/enums.py @@ -278,6 +278,36 @@ class GuildFeature(str, Enum): # Changed from IntEnum to Enum return str(value) +class VoiceRegion(str, Enum): + """Voice region identifier.""" + + AMSTERDAM = "amsterdam" + BRAZIL = "brazil" + DUBAI = "dubai" + EU_CENTRAL = "eu-central" + EU_WEST = "eu-west" + EUROPE = "europe" + FRANKFURT = "frankfurt" + HONGKONG = "hongkong" + INDIA = "india" + JAPAN = "japan" + RUSSIA = "russia" + SINGAPORE = "singapore" + SOUTHAFRICA = "southafrica" + SOUTH_KOREA = "south-korea" + SYDNEY = "sydney" + US_CENTRAL = "us-central" + US_EAST = "us-east" + US_SOUTH = "us-south" + US_WEST = "us-west" + VIP_US_EAST = "vip-us-east" + VIP_US_WEST = "vip-us-west" + + @classmethod + def _missing_(cls, value): # type: ignore + return str(value) + + # --- Channel Enums --- diff --git a/disagreement/http.py b/disagreement/http.py index f41e61e..34e7b11 100644 --- a/disagreement/http.py +++ b/disagreement/http.py @@ -912,3 +912,7 @@ class HTTPClient: async def trigger_typing(self, channel_id: str) -> None: """Sends a typing indicator to the specified channel.""" await self.request("POST", f"/channels/{channel_id}/typing") + + async def get_voice_regions(self) -> List[Dict[str, Any]]: + """Returns available voice regions.""" + return await self.request("GET", "/voice/regions") diff --git a/docs/voice_client.md b/docs/voice_client.md index f8a1060..a328a1b 100644 --- a/docs/voice_client.md +++ b/docs/voice_client.md @@ -42,3 +42,14 @@ await vc.play(FFmpegAudioSource("other.mp3")) ``` Call `await vc.close()` when finished. + +## Fetching Available Voice Regions + +Use :meth:`Client.fetch_voice_regions` to list the voice regions that Discord +currently offers. The method returns a list of :class:`VoiceRegion` values. + +```python +regions = await client.fetch_voice_regions() +for region in regions: + print(region.value) +```