Skip to content

Commit 004bfb7

Browse files
authored
feat: add message delete event (#524)
1 parent 8b7ebd6 commit 004bfb7

File tree

10 files changed

+165
-19
lines changed

10 files changed

+165
-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_deleted(
321+
self,
322+
handler_func: HandlerFunc[EventDeleted],
323+
) -> HandlerFunc[EventDeleted]:
324+
"""Decorate `event deleted` 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: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
from dataclasses import dataclass
2+
from datetime import datetime
3+
from typing import Any, Dict, List, Literal, Optional
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 EventDeleted(BotCommandBase):
21+
"""Event `system:event_deleted`.
22+
23+
Attributes:
24+
deleted_at: Delete message date and time.
25+
group_chat_id: Delete message group chat id.
26+
meta: Delete message meta.
27+
sync_ids: Delete message sync ids.
28+
"""
29+
30+
deleted_at: datetime
31+
group_chat_id: UUID
32+
sync_ids: List[UUID]
33+
meta: Optional[Dict[str, Any]]
34+
35+
36+
class BotAPIEventDeletedData(VerifiedPayloadBaseModel):
37+
deleted_at: datetime
38+
group_chat_id: UUID
39+
sync_ids: List[UUID]
40+
meta: Optional[Dict[str, Any]]
41+
42+
43+
class BotAPIEventDeletedPayload(BotAPIBaseSystemEventPayload):
44+
body: Literal[BotAPISystemEventTypes.EVENT_DELETED]
45+
data: BotAPIEventDeletedData
46+
47+
48+
class BotAPIEventDeleted(BotAPIBaseCommand):
49+
payload: BotAPIEventDeletedPayload = Field(..., alias="command")
50+
bot: BaseBotAPIContext = Field(..., alias="from")
51+
52+
def to_domain(self, raw_command: Dict[str, Any]) -> EventDeleted:
53+
return EventDeleted(
54+
bot=BotAccount(
55+
id=self.bot_id,
56+
host=self.bot.host,
57+
),
58+
raw_command=raw_command,
59+
deleted_at=self.payload.data.deleted_at,
60+
group_chat_id=self.payload.data.group_chat_id,
61+
meta=self.payload.data.meta,
62+
sync_ids=self.payload.data.sync_ids,
63+
)

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.75.3"
44
description = "A python library for interacting with eXpress BotX API"
55
authors = [
66
"Sidnev Nikolay <nsidnev@ccsteam.ru>",

tests/system_events/factories.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,13 @@ class ConferenceChangedDataFactory(DictFactory):
7777
operation = "change_conference_info"
7878
sip_number = 12345678
7979
start_at = "2025-04-15T11:00:39.634000Z"
80+
81+
82+
class DeleteEventFactory(DictFactory):
83+
deleted_at = "2025-09-23T09:04:49.787078Z"
84+
group_chat_id = "30dc1980-643a-00ad-37fc-7cc10d74e935"
85+
meta = {
86+
"deleted_by": "fbc84c63-e432-4ff1-99bd-c3275f053866",
87+
"deleted_by_admin": True,
88+
}
89+
sync_ids = ["36c4f12a-7082-599a-9842-cd146730e179"]
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from datetime import datetime
2+
from typing import Any, Callable, Dict, Optional
3+
from uuid import UUID
4+
5+
import pytest
6+
from deepdiff import DeepDiff
7+
8+
from pybotx import (
9+
Bot,
10+
BotAccount,
11+
BotAccountWithSecret,
12+
EventDeleted,
13+
HandlerCollector,
14+
lifespan_wrapper,
15+
)
16+
from tests.system_events.factories import DeleteEventFactory
17+
18+
pytestmark = [
19+
pytest.mark.asyncio,
20+
pytest.mark.mock_authorization,
21+
pytest.mark.usefixtures("respx_mock"),
22+
]
23+
24+
25+
async def test__event_delete__succeed(
26+
bot_account: BotAccountWithSecret,
27+
bot_id: UUID,
28+
host: str,
29+
datetime_formatter: Callable[[str], datetime],
30+
api_incoming_message_factory: Callable[..., Dict[str, Any]],
31+
) -> None:
32+
# - Arrange -
33+
event_deleted_data = DeleteEventFactory.create()
34+
35+
payload = api_incoming_message_factory(
36+
body="system:event_deleted",
37+
command_type="system",
38+
data=event_deleted_data,
39+
bot_id=bot_id,
40+
host=host,
41+
)
42+
43+
collector = HandlerCollector()
44+
event_deleted: Optional[EventDeleted] = None
45+
46+
@collector.event_deleted
47+
async def event_deleted_handler(event: EventDeleted, _: Bot) -> None:
48+
nonlocal event_deleted
49+
event_deleted = event
50+
# Drop `raw_command` from asserting
51+
event_deleted.raw_command = None
52+
53+
built_bot = Bot(collectors=[collector], bot_accounts=[bot_account])
54+
55+
# - Act -
56+
async with lifespan_wrapper(built_bot) as bot:
57+
bot.async_execute_raw_bot_command(payload, verify_request=False)
58+
59+
# - Assert -
60+
diff = DeepDiff(
61+
event_deleted,
62+
EventDeleted(
63+
bot=BotAccount(id=bot_id, host=host),
64+
raw_command=None,
65+
deleted_at=datetime_formatter(event_deleted_data["deleted_at"]),
66+
meta=event_deleted_data["meta"],
67+
group_chat_id=UUID(event_deleted_data["group_chat_id"]),
68+
sync_ids=[UUID(uuid_str) for uuid_str in event_deleted_data["sync_ids"]],
69+
),
70+
)
71+
72+
assert diff == {}, diff

0 commit comments

Comments
 (0)