Compare commits

...

2 Commits

Author SHA1 Message Date
a4aa4335a5
Merge branch 'master' of https://github.com/Slipstreamm/disagreement 2025-06-10 20:49:58 -06:00
b9d93a90fa
Adds invite management functionality
Introduces comprehensive invite handling capabilities including creation, deletion, and retrieval operations.

Implements invite data model with proper parsing and representation methods to handle Discord invite objects and their metadata.

Provides HTTP client methods for all invite-related API endpoints with appropriate error handling and response processing.

Includes documentation with practical examples for common invite operations.
2025-06-10 20:37:21 -06:00
4 changed files with 120 additions and 1 deletions

View File

@ -50,6 +50,7 @@ if TYPE_CHECKING:
Thread,
DMChannel,
Webhook,
Invite,
)
from .ui.view import View
from .enums import ChannelType as EnumChannelType
@ -698,6 +699,13 @@ class Client:
self._webhooks[webhook.id] = webhook
return webhook
def parse_invite(self, data: Dict[str, Any]) -> "Invite":
"""Parses invite data into an :class:`Invite`."""
from .models import Invite
return Invite.from_dict(data)
async def fetch_user(self, user_id: Snowflake) -> Optional["User"]:
"""Fetches a user by ID from Discord."""
if self._closed:
@ -1249,6 +1257,33 @@ class Client:
await self._http.delete_webhook(webhook_id)
async def create_invite(
self, channel_id: Snowflake, payload: Dict[str, Any]
) -> "Invite":
"""|coro| Create an invite for the given channel."""
if self._closed:
raise DisagreementException("Client is closed.")
return await self._http.create_invite(channel_id, payload)
async def delete_invite(self, code: str) -> None:
"""|coro| Delete an invite by code."""
if self._closed:
raise DisagreementException("Client is closed.")
await self._http.delete_invite(code)
async def fetch_invites(self, channel_id: Snowflake) -> List["Invite"]:
"""|coro| Fetch all invites for a channel."""
if self._closed:
raise DisagreementException("Client is closed.")
data = await self._http.get_channel_invites(channel_id)
return [self.parse_invite(inv) for inv in data]
# --- Application Command Methods ---
async def process_interaction(self, interaction: Interaction) -> None:
"""Internal method to process an interaction from the gateway."""

View File

@ -23,7 +23,7 @@ from .interactions import InteractionResponsePayload
if TYPE_CHECKING:
from .client import Client
from .models import Message, Webhook, File
from .models import Message, Webhook, File, Invite
from .interactions import ApplicationCommand, Snowflake
# Discord API constants
@ -409,6 +409,30 @@ class HTTPClient:
"""Fetches a channel by ID."""
return await self.request("GET", f"/channels/{channel_id}")
async def get_channel_invites(
self, channel_id: "Snowflake"
) -> List[Dict[str, Any]]:
"""Fetches the invites for a channel."""
return await self.request("GET", f"/channels/{channel_id}/invites")
async def create_invite(
self, channel_id: "Snowflake", payload: Dict[str, Any]
) -> "Invite":
"""Creates an invite for a channel."""
data = await self.request(
"POST", f"/channels/{channel_id}/invites", payload=payload
)
from .models import Invite
return Invite.from_dict(data)
async def delete_invite(self, code: str) -> None:
"""Deletes an invite by code."""
await self.request("DELETE", f"/invites/{code}")
async def create_webhook(
self, channel_id: "Snowflake", payload: Dict[str, Any]
) -> "Webhook":

View File

@ -6,6 +6,7 @@ Data models for Discord objects.
import asyncio
import json
from dataclasses import dataclass
from typing import Any, AsyncIterator, Dict, List, Optional, TYPE_CHECKING, Union
import aiohttp # pylint: disable=import-error
@ -1978,6 +1979,41 @@ class Reaction:
return f"<Reaction message_id='{self.message_id}' user_id='{self.user_id}' emoji='{emoji_value}'>"
@dataclass
class Invite:
"""Represents a Discord invite."""
code: str
channel_id: Optional[str]
guild_id: Optional[str]
inviter_id: Optional[str]
uses: Optional[int]
max_uses: Optional[int]
max_age: Optional[int]
temporary: Optional[bool]
created_at: Optional[str]
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "Invite":
channel = data.get("channel")
guild = data.get("guild")
inviter = data.get("inviter")
return cls(
code=data["code"],
channel_id=(channel or {}).get("id") if channel else data.get("channel_id"),
guild_id=(guild or {}).get("id") if guild else data.get("guild_id"),
inviter_id=(inviter or {}).get("id"),
uses=data.get("uses"),
max_uses=data.get("max_uses"),
max_age=data.get("max_age"),
temporary=data.get("temporary"),
created_at=data.get("created_at"),
)
def __repr__(self) -> str:
return f"<Invite code='{self.code}' guild_id='{self.guild_id}' channel_id='{self.channel_id}'>"
class GuildMemberRemove:
"""Represents a GUILD_MEMBER_REMOVE event."""

24
docs/invites.md Normal file
View File

@ -0,0 +1,24 @@
# Working with Invites
The library exposes helper methods for creating and deleting invites.
## Create an Invite
```python
invite = await client.create_invite("1234567890", {"max_age": 3600})
print(invite.code)
```
## Delete an Invite
```python
await client.delete_invite(invite.code)
```
## List Invites
```python
invites = await client.fetch_invites("1234567890")
for inv in invites:
print(inv.code, inv.uses)
```