Skip to content

Commit 99ab385

Browse files
committed
feat: add message delete event
1 parent 8b7ebd6 commit 99ab385

File tree

9 files changed

+194
-19
lines changed

9 files changed

+194
-19
lines changed

pybotx/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
from pybotx.models.system_events.cts_login import CTSLoginEvent
145145
from pybotx.models.system_events.cts_logout import CTSLogoutEvent
146146
from pybotx.models.system_events.deleted_from_chat import DeletedFromChatEvent
147+
from pybotx.models.system_events.event_delete import EventDeleted
147148
from pybotx.models.system_events.event_edit import EventEdit
148149
from pybotx.models.system_events.internal_bot_notification import (
149150
InternalBotNotificationEvent,
@@ -206,6 +207,7 @@
206207
"DeletedFromChatEvent",
207208
"Document",
208209
"EditMessage",
210+
"EventDeleted",
209211
"EventEdit",
210212
"EventNotFoundError",
211213
"File",

pybotx/bot/bot.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,7 @@
33
from contextlib import asynccontextmanager
44
from datetime import datetime
55
from types import SimpleNamespace
6-
from typing import (
7-
Any,
8-
Dict,
9-
List,
10-
Optional,
11-
Set,
12-
Tuple,
13-
Union,
14-
)
6+
from typing import Any, Dict, List, Optional, Set, Tuple, Union
157
from uuid import UUID
168

179
import aiofiles

pybotx/bot/handler.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
11
from dataclasses import dataclass
22
from functools import partial
3-
from typing import (
4-
TYPE_CHECKING,
5-
Awaitable,
6-
Callable,
7-
List,
8-
Literal,
9-
TypeVar,
10-
Union,
11-
)
3+
from typing import TYPE_CHECKING, Awaitable, Callable, List, Literal, TypeVar, Union
124

135
from pybotx.models.commands import BotCommand
146
from pybotx.models.message.incoming_message import IncomingMessage
@@ -23,6 +15,7 @@
2315
from pybotx.models.system_events.cts_login import CTSLoginEvent
2416
from pybotx.models.system_events.cts_logout import CTSLogoutEvent
2517
from pybotx.models.system_events.deleted_from_chat import DeletedFromChatEvent
18+
from pybotx.models.system_events.event_delete import EventDeleted
2619
from pybotx.models.system_events.event_edit import EventEdit
2720
from pybotx.models.system_events.internal_bot_notification import (
2821
InternalBotNotificationEvent,
@@ -53,6 +46,7 @@
5346
HandlerFunc[CTSLogoutEvent],
5447
HandlerFunc[InternalBotNotificationEvent],
5548
HandlerFunc[SmartAppEvent],
49+
HandlerFunc[EventDeleted],
5650
HandlerFunc[EventEdit],
5751
HandlerFunc[JoinToChatEvent],
5852
HandlerFunc[ConferenceChangedEvent],

pybotx/bot/handler_collector.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from pybotx.models.system_events.cts_login import CTSLoginEvent
4949
from pybotx.models.system_events.cts_logout import CTSLogoutEvent
5050
from pybotx.models.system_events.deleted_from_chat import DeletedFromChatEvent
51+
from pybotx.models.system_events.event_delete import EventDeleted
5152
from pybotx.models.system_events.event_edit import EventEdit
5253
from pybotx.models.system_events.internal_bot_notification import (
5354
InternalBotNotificationEvent,
@@ -316,6 +317,14 @@ def event_edit(
316317
self._system_event(EventEdit, handler_func)
317318
return handler_func
318319

320+
def event_delete(
321+
self,
322+
handler_func: HandlerFunc[EventDeleted],
323+
) -> HandlerFunc[EventDeleted]:
324+
"""Decorate `event delete` event handler."""
325+
self._system_event(EventDeleted, handler_func)
326+
return handler_func
327+
319328
def conference_changed(
320329
self,
321330
handler_func: HandlerFunc[ConferenceChangedEvent],

pybotx/models/commands.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
BotAPIDeletedFromChat,
3232
DeletedFromChatEvent,
3333
)
34+
from pybotx.models.system_events.event_delete import BotAPIEventDeleted, EventDeleted
3435
from pybotx.models.system_events.event_edit import BotAPIEventEdit, EventEdit
3536
from pybotx.models.system_events.internal_bot_notification import (
3637
BotAPIInternalBotNotification,
@@ -60,6 +61,7 @@
6061
BotAPILeftFromChat,
6162
BotAPICTSLogin,
6263
BotAPICTSLogout,
64+
BotAPIEventDeleted,
6365
BotAPIEventEdit,
6466
BotAPIJoinToChat,
6567
BotAPIConferenceChanged,
@@ -79,6 +81,7 @@
7981
LeftFromChatEvent,
8082
CTSLoginEvent,
8183
CTSLogoutEvent,
84+
EventDeleted,
8285
EventEdit,
8386
JoinToChatEvent,
8487
ConferenceChangedEvent,

pybotx/models/enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ class BotAPISystemEventTypes(StrEnum):
111111
INTERNAL_BOT_NOTIFICATION = "system:internal_bot_notification"
112112
LEFT_FROM_CHAT = "system:left_from_chat"
113113
SMARTAPP_EVENT = "system:smartapp_event"
114+
EVENT_DELETED = "system:event_deleted"
114115
EVENT_EDIT = "system:event_edit"
115116
JOIN_TO_CHAT = "system:user_joined_to_chat"
116117
CONFERENCE_CHANGED = "system:conference_changed"
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from dataclasses import dataclass
2+
from datetime import datetime
3+
from typing import Any, Dict, List, Literal
4+
from uuid import UUID
5+
6+
from pydantic import Field
7+
8+
from pybotx.models.api_base import VerifiedPayloadBaseModel
9+
from pybotx.models.base_command import (
10+
BaseBotAPIContext,
11+
BotAPIBaseCommand,
12+
BotAPIBaseSystemEventPayload,
13+
BotCommandBase,
14+
)
15+
from pybotx.models.bot_account import BotAccount
16+
from pybotx.models.enums import BotAPISystemEventTypes
17+
18+
19+
@dataclass
20+
class EventDeletedMeta:
21+
deleted_by: UUID
22+
deleted_by_admin: bool
23+
24+
25+
@dataclass
26+
class EventDeleted(BotCommandBase):
27+
"""Event `system:event_deleted`.
28+
29+
Attributes:
30+
deleted_at: Delete message date and time.
31+
group_chat_id: Delete message group chat id.
32+
meta: Delete message meta.
33+
sync_ids: Delete message sync ids.
34+
"""
35+
36+
deleted_at: datetime
37+
group_chat_id: UUID
38+
meta: EventDeletedMeta
39+
sync_ids: List[UUID]
40+
41+
42+
class BotAPIEventDeletedData(VerifiedPayloadBaseModel):
43+
deleted_at: datetime
44+
group_chat_id: UUID
45+
meta: EventDeletedMeta
46+
sync_ids: List[UUID]
47+
48+
49+
class BotAPIEventDeletedPayload(BotAPIBaseSystemEventPayload):
50+
body: Literal[BotAPISystemEventTypes.EVENT_DELETED]
51+
data: BotAPIEventDeletedData
52+
53+
54+
class BotAPIEventDeleted(BotAPIBaseCommand):
55+
payload: BotAPIEventDeletedPayload = Field(..., alias="command")
56+
bot: BaseBotAPIContext = Field(..., alias="from")
57+
58+
def to_domain(self, raw_command: Dict[str, Any]) -> EventDeleted:
59+
return EventDeleted(
60+
bot=BotAccount(
61+
id=self.bot_id,
62+
host=self.bot.host,
63+
),
64+
raw_command=raw_command,
65+
deleted_at=self.payload.data.deleted_at,
66+
group_chat_id=self.payload.data.group_chat_id,
67+
meta=EventDeletedMeta(
68+
deleted_by=self.payload.data.meta.deleted_by,
69+
deleted_by_admin=self.payload.data.meta.deleted_by_admin,
70+
),
71+
sync_ids=self.payload.data.sync_ids,
72+
)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "pybotx"
3-
version = "0.75.2"
3+
version = "0.76.0"
44
description = "A python library for interacting with eXpress BotX API"
55
authors = [
66
"Sidnev Nikolay <nsidnev@ccsteam.ru>",
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
from datetime import datetime
2+
from typing import Callable, Optional
3+
from uuid import UUID
4+
5+
import pytest
6+
7+
from pybotx import (
8+
Bot,
9+
BotAccount,
10+
BotAccountWithSecret,
11+
EventDeleted,
12+
HandlerCollector,
13+
lifespan_wrapper,
14+
)
15+
from pybotx.models.system_events.event_delete import EventDeletedMeta
16+
17+
pytestmark = [
18+
pytest.mark.asyncio,
19+
pytest.mark.mock_authorization,
20+
pytest.mark.usefixtures("respx_mock"),
21+
]
22+
23+
24+
async def test__event_delete__succeed(
25+
bot_account: BotAccountWithSecret,
26+
datetime_formatter: Callable[[str], datetime],
27+
) -> None:
28+
# - Arrange -
29+
payload = {
30+
"sync_id": "a465f0f3-1354-491c-8f11-f400164295cb",
31+
"command": {
32+
"body": "system:event_deleted",
33+
"data": {
34+
"deleted_at": "2025-09-23T09:04:49.787078Z",
35+
"group_chat_id": "6fe9b0e7-32e3-4843-8486-897eabd69422",
36+
"meta": {
37+
"deleted_by": "fbc84c63-e432-4ff1-99bd-c3275f053866",
38+
"deleted_by_admin": True,
39+
},
40+
"sync_ids": ["36c4f12a-7082-599a-9842-cd146730e179"],
41+
},
42+
"command_type": "system",
43+
"metadata": {},
44+
},
45+
"async_files": [],
46+
"attachments": [],
47+
"entities": [],
48+
"from": {
49+
"user_huid": None,
50+
"group_chat_id": "6fe9b0e7-32e3-4843-8486-897eabd69422",
51+
"ad_login": None,
52+
"ad_domain": None,
53+
"username": None,
54+
"chat_type": None,
55+
"manufacturer": None,
56+
"device": None,
57+
"device_software": None,
58+
"device_meta": {},
59+
"platform": None,
60+
"platform_package_id": None,
61+
"is_admin": None,
62+
"is_creator": None,
63+
"app_version": None,
64+
"locale": "en",
65+
"host": "cts.example.com",
66+
},
67+
"bot_id": "24348246-6791-4ac0-9d86-b948cd6a0e46",
68+
"proto_version": 4,
69+
"source_sync_id": None,
70+
}
71+
72+
collector = HandlerCollector()
73+
event_delete: Optional[EventDeleted] = None
74+
75+
@collector.event_delete
76+
async def event_delete_handler(event: EventDeleted, _: Bot) -> None:
77+
nonlocal event_delete
78+
event_delete = event
79+
# Drop `raw_command` from asserting
80+
event_delete.raw_command = None
81+
82+
built_bot = Bot(collectors=[collector], bot_accounts=[bot_account])
83+
84+
# - Act -
85+
async with lifespan_wrapper(built_bot) as bot:
86+
bot.async_execute_raw_bot_command(payload, verify_request=False)
87+
88+
# - Assert -
89+
assert event_delete == EventDeleted(
90+
bot=BotAccount(
91+
id=UUID("24348246-6791-4ac0-9d86-b948cd6a0e46"),
92+
host="cts.example.com",
93+
),
94+
raw_command=None,
95+
deleted_at=datetime_formatter("2025-09-23T09:04:49.787078Z"),
96+
meta=EventDeletedMeta(
97+
deleted_by=UUID("fbc84c63-e432-4ff1-99bd-c3275f053866"),
98+
deleted_by_admin=True,
99+
),
100+
group_chat_id=UUID("6fe9b0e7-32e3-4843-8486-897eabd69422"),
101+
sync_ids=[UUID("36c4f12a-7082-599a-9842-cd146730e179")],
102+
)

0 commit comments

Comments
 (0)