oclaw/runtime/extensions/whatsapp/api.py
oliver 4a23b715a2 重构仓库目录为统一的 runtime 分层并清理历史 openclaw 残留。
本次迁移将网关/通道/工具/技能/脚本与协议资源集中到新结构,统一路径常量与脚本转发机制,减少顶层噪音并保证运行与测试行为一致。

Made-with: Cursor
2026-04-25 01:24:23 +08:00

49 lines
1.4 KiB
Python

from __future__ import annotations
import re
from typing import Iterable
WHATSAPP_LEGACY_OUTBOUND_SEND_DEP_KEYS: tuple[str, ...] = ("whatsapp", "legacy_outbound_send")
_GROUP_SUFFIX = "@g.us"
_USER_SUFFIX = "@s.whatsapp.net"
def is_whatsapp_group_jid(value: str) -> bool:
return str(value or "").strip().lower().endswith(_GROUP_SUFFIX)
def is_whatsapp_user_target(value: str) -> bool:
v = str(value or "").strip().lower()
return v.endswith(_USER_SUFFIX) or bool(re.fullmatch(r"\+?\d{6,20}", v))
def looks_like_whatsapp_target_id(value: str) -> bool:
v = str(value or "").strip().lower()
return is_whatsapp_group_jid(v) or is_whatsapp_user_target(v)
def normalize_whatsapp_target(value: str) -> str:
raw = str(value or "").strip()
if not raw:
raise ValueError("whatsapp target is required")
low = raw.lower()
if low.endswith(_GROUP_SUFFIX) or low.endswith(_USER_SUFFIX):
return low
digits = re.sub(r"[^\d+]", "", raw)
if digits.startswith("+"):
digits = digits[1:]
if not digits:
raise ValueError(f"invalid whatsapp target: {value}")
return f"{digits}{_USER_SUFFIX}"
def normalize_whatsapp_allow_from_entries(entries: Iterable[str] | None) -> tuple[str, ...]:
out: list[str] = []
for item in entries or ():
try:
out.append(normalize_whatsapp_target(str(item)))
except Exception:
continue
return tuple(sorted(set(out)))