Commit 1a95760

benny-dou <60535774+benny-dou@users.noreply.github.com>
2025-06-15 17:27:10
fix(history): support query by Telegram UID
1 parent 8286676
Changed files (2)
src
src/history/query.py
@@ -36,7 +36,7 @@ HELP = f"""🗣**查询当前对话聊天记录**
 
 注意:
 - 用户名和关键词需要区分大小写
-- 用户名可以为昵称 (Name)、用户名 (@username)
+- 用户名可以为昵称 (Name)、用户名 (@username)、用户的TelegramUID
 - 如果用户名中有空格, 请去除空格。例如: 想指定用户为John Doe请使用 `@JohnDoe`
 {BLOCKQUOTE_EXPANDABLE_END_DELIM}
 `/history` 使用说明:
@@ -184,7 +184,7 @@ async def query_turso(client: Client, cinfo: dict[str, str], match_time: str, us
 
     segmented = " ".join(cutter.cutword(keyword))
     texts_to_match = keyword if segmented == keyword else f'"{keyword}" OR "{segmented}"'  # must use double quotes for inner part
-    sql = f"SELECT T.mid, T.mtype, T.time, T.fullname, T.content FROM '{cinfo['tablename']}' AS T JOIN fts_{cinfo['cid']} AS FTS ON T.mid = FTS.rowid WHERE FTS.segmented MATCH '{texts_to_match}' ORDER BY T.mid DESC"
+    sql = f"SELECT T.mid, T.mtype, T.time, T.fullname, T.content FROM '{cinfo['tablename']}' AS T JOIN fts_{cinfo['cid']} AS FTS ON T.mid = FTS.rowid WHERE FTS.segmented MATCH '{texts_to_match}'"
     if match_time:
         if len(match_time) == 4:  # 2025
             begin = f"{match_time}-01-01 00:00:00"
@@ -198,10 +198,12 @@ async def query_turso(client: Client, cinfo: dict[str, str], match_time: str, us
         sql += f" AND T.time >= '{begin}' AND T.time <= '{end}'"
     if user:
         # 由于username可以修改, 我们优先使用UID进行匹配
-        if uid := await get_uid_by_username(client, user):
+        real_cid = cinfo["chandle"] if cinfo.get("chandle") else cinfo["cid"] if cinfo["ctype"] in ["BOT", "PRIVATE"] else f"-100{cinfo['cid']}"
+        if uid := await get_uid_by_username(client, real_cid, user):
             sql += f" AND T.uid = {uid}"
         else:
             sql += f" AND T.user = '{user}'"
+    sql += " ORDER BY T.mid DESC"
     logger.info(sql)
     resp = await turso_exec([{"type": "execute", "stmt": {"sql": sql}}], silent=True, retry=2, **TURSO_KWARGS)
     texts = ""
src/history/utils.py
@@ -7,7 +7,7 @@ import string
 from loguru import logger
 from pyrogram.client import Client
 from pyrogram.errors import PeerIdInvalid
-from pyrogram.types import Chat, Message, User
+from pyrogram.types import Chat, ChatMember, Message
 
 from config import DB, HISTORY, TID, cache
 from database.turso import turso_exec, turso_parse_resp
@@ -121,20 +121,20 @@ def is_admin(uid: int) -> bool:
     return any(slim_cid(admin) == slim_cid(uid) for admin in strings_list(TID.HISTORY_ADMIN))
 
 
-async def get_uid_by_username(client: Client, username: str) -> int:
+async def get_uid_by_username(client: Client, chat_id: str | int, username: str) -> int:
     """Get Telegram user id by username.
 
     Support formats of `username`:
         handle (a-z, A-Z, 0-9, _)
     """
-    if cache.get(f"get_uid_by_username-{username}"):
-        return cache.get(f"get_uid_by_username-{username}")
+    if cache.get(f"get_uid_by_username-{chat_id}-{username}"):
+        return cache.get(f"get_uid_by_username-{chat_id}-{username}")
     if all(x in list(string.digits) + list(string.ascii_letters) for x in username):
         logger.debug(f"Getting uid by username: {username}")
         with contextlib.suppress(Exception):
-            user = await client.get_users(to_int(username))
-            if isinstance(user, User):
-                cache.set(f"get_uid_by_username-{username}", user.id, ttl=0)
-                return user.id
-    cache.set(f"get_uid_by_username-{username}", 0, ttl=0)
+            member = await client.get_chat_member(to_int(chat_id), to_int(username))
+            if isinstance(member, ChatMember):
+                cache.set(f"get_uid_by_username-{username}", member.user.id, ttl=0)
+                return member.user.id
+    cache.set(f"get_uid_by_username-{chat_id}-{username}", 0, ttl=0)
     return 0