51 lines
1.3 KiB
Python
51 lines
1.3 KiB
Python
|
|
def normalize_target_input(raw: str) -> str:
|
||
|
|
if not raw:
|
||
|
|
return ""
|
||
|
|
cleaned = raw.strip()
|
||
|
|
if ":" in cleaned:
|
||
|
|
prefix, rest = cleaned.split(":", 1)
|
||
|
|
return f"{prefix.lower().strip()}:{rest.strip()}"
|
||
|
|
return cleaned
|
||
|
|
|
||
|
|
|
||
|
|
def detect_target_kind(raw: str, channel_chat_types: list[str] | None = None) -> str:
|
||
|
|
trimmed = raw.strip()
|
||
|
|
|
||
|
|
if trimmed.startswith("@") or trimmed.lower().startswith("user:"):
|
||
|
|
return "user"
|
||
|
|
if trimmed.startswith("#") or trimmed.lower().startswith("channel:"):
|
||
|
|
return "group"
|
||
|
|
if trimmed.lower().startswith("thread:"):
|
||
|
|
return "channel"
|
||
|
|
|
||
|
|
if channel_chat_types:
|
||
|
|
if "direct" in channel_chat_types and "group" not in channel_chat_types:
|
||
|
|
return "user"
|
||
|
|
|
||
|
|
return "group"
|
||
|
|
|
||
|
|
|
||
|
|
def looks_like_target_id(raw: str) -> bool:
|
||
|
|
trimmed = raw.strip()
|
||
|
|
core = trimmed
|
||
|
|
for prefix in ("user:", "channel:", "group:", "thread:", "@", "#"):
|
||
|
|
if core.lower().startswith(prefix):
|
||
|
|
core = core[len(prefix) :].strip()
|
||
|
|
break
|
||
|
|
|
||
|
|
if not core:
|
||
|
|
return False
|
||
|
|
|
||
|
|
if core.isdigit():
|
||
|
|
return True
|
||
|
|
|
||
|
|
if any("\u4e00" <= c <= "\u9fff" for c in core):
|
||
|
|
return False
|
||
|
|
if " " in core:
|
||
|
|
return False
|
||
|
|
|
||
|
|
if "-" in core and len(core) > 20:
|
||
|
|
return True
|
||
|
|
|
||
|
|
return False
|