71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
"""Conversation id helpers for Douyin IM."""
|
|
|
|
|
|
def parse_conversation_parts(conversation_id: str) -> tuple[int, int] | None:
|
|
parts = (conversation_id or "").split(":")
|
|
if len(parts) >= 4 and parts[0] == "0" and parts[1] == "1":
|
|
try:
|
|
return int(parts[2]), int(parts[3])
|
|
except (TypeError, ValueError):
|
|
return None
|
|
return None
|
|
|
|
|
|
def resolve_peer_uid(conversation_id: str, my_uid: int) -> int | None:
|
|
"""Resolve peer user id from conversation id or bare numeric id."""
|
|
raw = (conversation_id or "").strip()
|
|
if not raw:
|
|
return None
|
|
|
|
parts = parse_conversation_parts(raw)
|
|
if parts:
|
|
uid1, uid2 = parts
|
|
if my_uid and uid1 == my_uid:
|
|
return uid2
|
|
if my_uid and uid2 == my_uid:
|
|
return uid1
|
|
# 0:1:{my}:{peer} — 若 my_uid 与首段不一致,仍取末段为对方
|
|
return uid2
|
|
|
|
if raw.isdigit():
|
|
peer = int(raw)
|
|
if my_uid and peer == my_uid:
|
|
return None
|
|
return peer
|
|
return None
|
|
|
|
|
|
def build_conversation_id(my_uid: int, peer_uid: int) -> str:
|
|
return f"0:1:{int(my_uid)}:{int(peer_uid)}"
|
|
|
|
|
|
def normalize_conversation_id(conversation_id: str, my_uid: int) -> str:
|
|
"""Ensure conversation id uses current account uid as first participant."""
|
|
peer_uid = resolve_peer_uid(conversation_id, my_uid)
|
|
if peer_uid and my_uid:
|
|
return build_conversation_id(my_uid, peer_uid)
|
|
return (conversation_id or "").strip()
|
|
|
|
|
|
def conversation_belongs_to(conversation_id: str, my_uid: int) -> bool:
|
|
"""判断单聊会话是否属于 my_uid 本人。
|
|
|
|
托管多个账号时,一条属于别的账号的会话(例如 frontier 长连接按设备号寻址
|
|
造成的跨账号推送)一旦流进本账号的处理链路,resolve_peer_uid 会把末段当成
|
|
「对方」、normalize_conversation_id 再拼成 0:1:{本账号}:{别人的好友},于是
|
|
本账号就把消息发给了另一个账号的好友。这里给出唯一的归属判据。
|
|
|
|
无法判定时一律返回 True(保守放行):缺 my_uid、群聊、裸 UID 等形态本来就
|
|
不带参与方信息。只有两个参与方都已知、且都不是本账号时才判定为不属于本账号。
|
|
"""
|
|
try:
|
|
uid = int(my_uid or 0)
|
|
except (TypeError, ValueError):
|
|
return True
|
|
if not uid:
|
|
return True
|
|
parts = parse_conversation_parts(conversation_id)
|
|
if not parts:
|
|
return True
|
|
return uid in parts
|