import os from typing import Any, Dict import httpx def env_bool(name: str, default: bool = False) -> bool: fallback = "true" if default else "false" value = os.getenv(name, fallback).strip().lower() return value in {"true", "1", "yes", "on"} def get_mautic_config() -> Dict[str, str]: return { "base_url": os.getenv("MAUTIC_BASE_URL", "").rstrip("/"), "api_token": os.getenv("MAUTIC_API_TOKEN", ""), "add_tag_url": os.getenv("MAUTIC_ADD_TAG_URL", ""), "remove_tag_url": os.getenv("MAUTIC_REMOVE_TAG_URL", ""), } def build_tag_payload(payload: Dict[str, Any]) -> Dict[str, Any]: return { "tag": payload.get("tag"), "contact_id": payload.get("contact_id"), "conversation_id": payload.get("conversation_id"), "event_type": payload.get("event_type"), "source": "clientflow", "metadata": payload, } def add_tag_from_outbox_payload(payload: Dict[str, Any]) -> Dict[str, Any]: if not env_bool("MAUTIC_WRITE_ENABLED", False): raise RuntimeError("MAUTIC_WRITE_ENABLED=false") config = get_mautic_config() if not config["api_token"]: raise RuntimeError("MAUTIC_API_TOKEN em falta") if not config["add_tag_url"]: raise RuntimeError("MAUTIC_ADD_TAG_URL em falta") headers = { "Content-Type": "application/json", "Authorization": f"Bearer {config['api_token']}", } body = build_tag_payload(payload) with httpx.Client(timeout=30) as client: response = client.post(config["add_tag_url"], headers=headers, json=body) if response.status_code >= 400: raise RuntimeError(f"Mautic error {response.status_code}: {response.text}") try: return response.json() except Exception: return {"status_code": response.status_code, "text": response.text} def remove_tag_from_outbox_payload(payload: Dict[str, Any]) -> Dict[str, Any]: if not env_bool("MAUTIC_WRITE_ENABLED", False): raise RuntimeError("MAUTIC_WRITE_ENABLED=false") config = get_mautic_config() if not config["api_token"]: raise RuntimeError("MAUTIC_API_TOKEN em falta") if not config["remove_tag_url"]: raise RuntimeError("MAUTIC_REMOVE_TAG_URL em falta") headers = { "Content-Type": "application/json", "Authorization": f"Bearer {config['api_token']}", } body = build_tag_payload(payload) with httpx.Client(timeout=30) as client: response = client.post(config["remove_tag_url"], headers=headers, json=body) if response.status_code >= 400: raise RuntimeError(f"Mautic error {response.status_code}: {response.text}") try: return response.json() except Exception: return {"status_code": response.status_code, "text": response.text}