Files
tg-spam-guard/services/message_utils.py
T
2026-07-07 13:07:27 +08:00

85 lines
3.0 KiB
Python

"""消息工具函数"""
from __future__ import annotations
import asyncio
import logging
import config
logger = logging.getLogger("spam_guard")
async def auto_delete(message, seconds: int | None = None) -> None:
"""延迟删除消息。删除失败不影响主流程。"""
if not message:
return
try:
await asyncio.sleep(seconds or config.AUTO_DELETE_SECONDS)
await message.delete()
except Exception as e:
logger.debug(f"自动删除消息失败: {e}")
def schedule_delete(message, seconds: int | None = None) -> None:
"""创建自动删除任务。"""
asyncio.create_task(auto_delete(message, seconds=seconds))
async def safe_reply(update, context, text: str, **kwargs):
"""优先回复原消息;原消息已被删除/不可回复时,降级为普通群消息。"""
try:
if update and update.message:
msg = await update.message.reply_text(text, **kwargs)
await record_bot_message(msg, text)
return msg
except Exception as e:
if "Message to be replied not found" not in str(e):
logger.warning(f"回复消息失败,降级普通发送: {type(e).__name__}: {e}")
chat_id = update.effective_chat.id if update and update.effective_chat else None
if not chat_id:
raise RuntimeError("missing chat_id for safe_reply")
msg = await context.bot.send_message(chat_id=chat_id, text=text, **kwargs)
await record_bot_message(msg, text)
return msg
async def record_bot_message(message, text: str | None = None, username: str = "tg-bot"):
"""把机器人发出的群消息写入聊天记录,作为工作记录。"""
if not message or not getattr(message, "chat_id", None):
return None
try:
chat_type = getattr(getattr(message, "chat", None), "type", None)
if chat_type == "private":
return None
from db.models import Message
from web.api import broadcast_sse, json_safe
body = text if text is not None else (getattr(message, "text", None) or getattr(message, "caption", None) or "")
rec = await Message.get_or_none(chat_id=message.chat_id, msg_id=message.message_id)
if rec:
return rec
rec = await Message.create(
msg_id=message.message_id,
chat_id=message.chat_id,
user_id=0,
username=username,
first_name="机器人工作记录",
text=str(body)[:500],
)
await broadcast_sse("chat", json_safe({
"id": rec.id,
"msg_id": rec.msg_id,
"chat_id": rec.chat_id,
"user_id": 0,
"username": username,
"first_name": "机器人工作记录",
"text": rec.text,
"time": rec.created_at,
"spam": False,
"bot_record": True,
}))
return rec
except Exception as e:
logger.debug(f"记录机器人消息失败: {e}")
return None