feat: log presence, read receipts, group leaves, links, profiles, stories

This commit is contained in:
hh committed 2026-05-29 22:13:59 +02:00
1 parent bfd16ab02c
commit bcb94b6474
31 files changed
+1298 -19

No files matched your search

@@ -0,0 +1,3 @@
from userbot.modules.groups.service import capture_service
__all__ = ["capture_service"]
@@ -0,0 +1,68 @@
from datetime import datetime
import asyncpg
_INSERT_CHAT_HISTORY = """
INSERT INTO chat_history
(account_id, chat_id, message_id, event, title, photo_unique_id, actor_id,
ts, raw)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::jsonb)
ON CONFLICT (account_id, chat_id, message_id) DO NOTHING
"""
_INSERT_MEMBERSHIP = """
INSERT INTO memberships
(account_id, chat_id, message_id, user_id, event, actor_id, ts, raw)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb)
ON CONFLICT (account_id, chat_id, message_id, user_id) DO NOTHING
"""
async def insert_chat_history( # noqa: PLR0913
pool: asyncpg.Pool,
account_id: int,
chat_id: int,
message_id: int,
event: str,
title: str | None,
photo_unique_id: str | None,
actor_id: int | None,
ts: datetime,
raw: str,
) -> None:
await pool.execute(
_INSERT_CHAT_HISTORY,
account_id,
chat_id,
message_id,
event,
title,
photo_unique_id,
actor_id,
ts,
raw,
)
async def insert_membership( # noqa: PLR0913
pool: asyncpg.Pool,
account_id: int,
chat_id: int,
message_id: int,
user_id: int,
event: str,
actor_id: int | None,
ts: datetime,
raw: str,
) -> None:
await pool.execute(
_INSERT_MEMBERSHIP,
account_id,
chat_id,
message_id,
user_id,
event,
actor_id,
ts,
raw,
)
@@ -0,0 +1,91 @@
from pyrogram import Client, enums
from pyrogram.types import Message
from userbot.modules.avatars import capture_avatar
from userbot.modules.capture.context import CaptureContext
from userbot.modules.capture.message import sender_id
from userbot.modules.groups import repository
async def capture_service(
client: Client, message: Message, ctx: CaptureContext
) -> None:
if message.service is None or message.chat is None or message.date is None:
return
chat_id = message.chat.id or 0
actor = sender_id(message)
ts = message.date
service = message.service
if service is enums.MessageServiceType.NEW_CHAT_TITLE:
await repository.insert_chat_history(
ctx.pool,
ctx.account_id,
chat_id,
message.id,
"title",
message.new_chat_title,
None,
actor,
ts,
str(message),
)
elif service is enums.MessageServiceType.NEW_CHAT_PHOTO:
photo = message.new_chat_photo
unique_id = photo.file_unique_id if photo else None
await repository.insert_chat_history(
ctx.pool,
ctx.account_id,
chat_id,
message.id,
"photo",
None,
unique_id,
actor,
ts,
str(message),
)
if photo is not None and unique_id is not None:
await capture_avatar(
client, ctx, chat_id, "chat", photo.file_id, unique_id, str(message)
)
elif service is enums.MessageServiceType.DELETE_CHAT_PHOTO:
await repository.insert_chat_history(
ctx.pool,
ctx.account_id,
chat_id,
message.id,
"photo_deleted",
None,
None,
actor,
ts,
str(message),
)
elif service is enums.MessageServiceType.NEW_CHAT_MEMBERS:
for member in message.new_chat_members or []:
await repository.insert_membership(
ctx.pool,
ctx.account_id,
chat_id,
message.id,
member.id,
"join",
actor,
ts,
str(message),
)
elif service is enums.MessageServiceType.LEFT_CHAT_MEMBER:
member = message.left_chat_member
if member is not None:
await repository.insert_membership(
ctx.pool,
ctx.account_id,
chat_id,
message.id,
member.id,
"leave",
actor,
ts,
str(message),
)