ForcePilot/backend/package/yuxi/channels/adapters/googlechat/target.py

108 lines
3.2 KiB
Python
Raw Normal View History

from __future__ import annotations
import re
from typing import Any
_CHANNEL_PREFIXES = ("googlechat:", "gchat:", "google-chat:")
_VALID_GC_RESOURCE_PREFIXES = frozenset({"spaces/", "users/"})
_MESSAGES_SUFFIX_RE = re.compile(r"/messages/[^/]+$")
def strip_message_suffix(target: str) -> tuple[str, bool]:
stripped = _MESSAGES_SUFFIX_RE.sub("", target)
return stripped, stripped != target
def detect_deprecated_target(target: str) -> str | None:
cleaned = _strip_channel_prefix(target)
for prefix in _VALID_GC_RESOURCE_PREFIXES:
if cleaned.startswith(prefix):
return None
return f"Target '{target}' does not use a valid Google Chat resource prefix (spaces/ or users/)"
def normalize_googlechat_target(target: str) -> dict[str, Any]:
if not target:
return {"raw": target, "type": "unknown"}
target = _strip_channel_prefix(target)
if "@" in target and not target.startswith(("spaces/", "users/")):
target = _convert_email_to_user(target)
if target.startswith("spaces/"):
parts = target.removeprefix("spaces/").split("/")
space_id = parts[0]
thread_key = parts[2] if len(parts) > 2 and parts[1] == "threads" else None
return {
"raw": target,
"type": "thread" if thread_key else "space",
"space_id": space_id,
"space_name": f"spaces/{space_id}",
"thread_key": thread_key,
"full_target": target,
}
if target.startswith("users/"):
user_id = target.removeprefix("users/")
cleaned = user_id.removeprefix("user:")
return {
"raw": target,
"type": "user",
"user_id": cleaned,
"user_name": f"users/{cleaned}",
"full_target": target,
}
if target.startswith("user:"):
user_id = target.removeprefix("user:")
return {
"raw": target,
"type": "user",
"user_id": user_id,
"user_name": f"users/{user_id}",
"full_target": f"users/{user_id}",
}
return {"raw": target, "type": "unknown"}
def is_googlechat_user_target(target: str) -> bool:
target = _strip_channel_prefix(target)
return target.startswith("users/") or target.startswith("user:")
def is_googlechat_space_target(target: str) -> bool:
target = _strip_channel_prefix(target)
return target.startswith("spaces/")
def resolve_targets(inputs: list[str], kind: str | None = None) -> list[dict[str, Any]]:
results: list[dict[str, Any]] = []
for target in inputs:
normalized = normalize_googlechat_target(target)
target_type = normalized.get("type", "unknown")
if kind and target_type != kind:
continue
results.append(normalized)
return results
def _strip_channel_prefix(target: str) -> str:
for prefix in _CHANNEL_PREFIXES:
if target.lower().startswith(prefix):
return target[len(prefix) :]
return target
def _convert_email_to_user(email: str) -> str:
email_match = re.match(r"^[\w.+-]+@[\w-]+\.[\w.-]+$", email)
if email_match:
return f"users/{email}"
return f"users/{email}"