This commit is contained in:
Slipstream 2025-06-10 15:58:15 -06:00
commit 3d0f26f68f
Signed by: slipstream
GPG Key ID: 13E498CE010AC6FD
4 changed files with 86 additions and 0 deletions

View File

@ -79,6 +79,10 @@ class EventDispatcher:
self._client._messages.pop(message_id, None)
return data
def _parse_message_reaction_raw(self, data: Dict[str, Any]) -> Dict[str, Any]:
"""Returns the raw reaction payload."""
return data
def _parse_interaction_create(self, data: Dict[str, Any]) -> "Interaction":
"""Parses raw INTERACTION_CREATE data into an Interaction object."""
from .interactions import Interaction

View File

@ -348,6 +348,18 @@ class HTTPClient:
f"/channels/{channel_id}/messages/{message_id}/reactions/{encoded}",
)
async def bulk_delete_messages(
self, channel_id: "Snowflake", messages: List["Snowflake"]
) -> List["Snowflake"]:
"""Bulk deletes messages in a channel and returns their IDs."""
await self.request(
"POST",
f"/channels/{channel_id}/messages/bulk-delete",
payload={"messages": messages},
)
return messages
async def delete_channel(
self, channel_id: str, reason: Optional[str] = None
) -> None:

View File

@ -31,6 +31,7 @@ if TYPE_CHECKING:
from .client import Client # For type hinting to avoid circular imports
from .enums import OverwriteType # For PermissionOverwrite model
from .ui.view import View
from .interactions import Snowflake
# Forward reference Message if it were used in type hints before its definition
# from .models import Message # Not needed as Message is defined before its use in TextChannel.send etc.
@ -1085,6 +1086,27 @@ class TextChannel(Channel):
components=components,
)
async def purge(
self, limit: int, *, before: "Snowflake | None" = None
) -> List["Snowflake"]:
"""Bulk delete messages from this channel."""
params: Dict[str, Union[int, str]] = {"limit": limit}
if before is not None:
params["before"] = before
messages = await self._client._http.request(
"GET", f"/channels/{self.id}/messages", params=params
)
ids = [m["id"] for m in messages]
if not ids:
return []
await self._client._http.bulk_delete_messages(self.id, ids)
for mid in ids:
self._client._messages.pop(mid, None)
return ids
def __repr__(self) -> str:
return f"<TextChannel id='{self.id}' name='{self.name}' guild_id='{self.guild_id}'>"

View File

@ -0,0 +1,48 @@
import pytest
from types import SimpleNamespace
from unittest.mock import AsyncMock
from disagreement.client import Client
from disagreement.models import TextChannel
@pytest.mark.asyncio
async def test_textchannel_purge_calls_bulk_delete():
http = SimpleNamespace(
request=AsyncMock(return_value=[{"id": "1"}, {"id": "2"}]),
bulk_delete_messages=AsyncMock(),
)
client = Client.__new__(Client)
client._http = http
client._messages = {}
channel = TextChannel({"id": "c", "type": 0}, client)
deleted = await channel.purge(2)
http.request.assert_called_once_with(
"GET", "/channels/c/messages", params={"limit": 2}
)
http.bulk_delete_messages.assert_awaited_once_with("c", ["1", "2"])
assert deleted == ["1", "2"]
@pytest.mark.asyncio
async def test_textchannel_purge_before_param():
http = SimpleNamespace(
request=AsyncMock(return_value=[]),
bulk_delete_messages=AsyncMock(),
)
client = Client.__new__(Client)
client._http = http
client._messages = {}
channel = TextChannel({"id": "c", "type": 0}, client)
deleted = await channel.purge(1, before="b")
http.request.assert_called_once_with(
"GET", "/channels/c/messages", params={"limit": 1, "before": "b"}
)
http.bulk_delete_messages.assert_not_awaited()
assert deleted == []