"""消息工具函数""" from __future__ import annotations import asyncio import logging import config logger = logging.getLogger("spam_guard") TRANSIENT_BOT_RECORD_PREFIXES = ( "🔍 正在搜索知识库", "正在搜索知识库", "🔎 正在搜索知识库", "正在整理详细答案", ) def should_record_bot_message(text: str) -> bool: body = (text or "").strip() if not body: return False return not any(body.startswith(prefix) for prefix in TRANSIENT_BOT_RECORD_PREFIXES) 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 "") if not should_record_bot_message(str(body)): return None 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