from __future__ import annotations import re from typing import Any from django.db.models import Q from core.models import ExternalChatLink, PersonIdentifier def channel_variants(service: str, channel: str) -> list[str]: value = str(channel or "").strip() if not value: return [] variants = [value] service_key = str(service or "").strip().lower() if service_key == "whatsapp": bare = value.split("@", 1)[0].strip() if bare and bare not in variants: variants.append(bare) direct = f"{bare}@s.whatsapp.net" if bare else "" if direct and direct not in variants: variants.append(direct) group = f"{bare}@g.us" if bare else "" if group and group not in variants: variants.append(group) if service_key == "signal": digits = re.sub(r"[^0-9]", "", value) if digits and digits not in variants: variants.append(digits) if digits: plus = f"+{digits}" if plus not in variants: variants.append(plus) return variants def resolve_external_chat_id(*, user, provider: str, service: str, channel: str) -> str: variants = channel_variants(service, channel) if not variants: return "" person_identifier = ( PersonIdentifier.objects.filter( user=user, service=service, identifier__in=variants, ) .select_related("person") .order_by("-id") .first() ) if person_identifier is None: return "" link = ( ExternalChatLink.objects.filter( user=user, provider=provider, enabled=True, ) .filter(Q(person_identifier=person_identifier) | Q(person=person_identifier.person)) .order_by("-updated_at", "-id") .first() ) return str(getattr(link, "external_chat_id", "") or "").strip() def compact_json_snippet(payload: Any, limit: int = 800) -> str: text = str(payload or "").strip() if len(text) <= limit: return text return text[:limit].rstrip() + "..."