chorus/bot/chorus_bot/ping.py

83 lines
3 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime
import discord
MODALITY_LABELS = {
"bh_email": "BH Email",
"personal_email": "Personal Email",
"bh_text": "BH Text",
"personal_text": "Personal Text",
"voice": "Voice",
"fb_messenger": "FB Messenger",
"nd_messenger": "ND Messenger",
"lead_found": "Found Lead",
"magpie_lead": "Magpie Lead",
}
# Discord's API rejects embed field values of length 0 (min 1, max 1024 chars).
# Use a zero-width space as a round-trip-safe sentinel for "empty" values so we
# never send a literal "" to Discord.
_EMPTY_FIELD_SENTINEL = ""
# Hard cap for any field value, with headroom for a truncation marker so the
# final value never exceeds Discord's 1024-char limit regardless of caller.
_FIELD_VALUE_MAX = 1024
_TRUNCATION_MARKER = "\n\n[...truncated for Discord embed limit...]"
def _safe_field_value(value: str) -> str:
"""Return a Discord-safe embed field value: never empty, never over 1024 chars."""
if not value:
return _EMPTY_FIELD_SENTINEL
if len(value) > _FIELD_VALUE_MAX:
keep = _FIELD_VALUE_MAX - len(_TRUNCATION_MARKER)
return value[:keep] + _TRUNCATION_MARKER
return value
def build_ping_embed(
*, modality: str, sender_id: str | None, snippet: str, raw_content: str,
captured_at: datetime, direction: str = "inbound", image_url: str | None = None,
) -> discord.Embed:
label = MODALITY_LABELS.get(modality, modality)
embed = discord.Embed(
title=f"{label}" + (f" - {sender_id}" if sender_id else ""),
description=snippet,
)
embed.add_field(name="modality", value=_safe_field_value(modality), inline=True)
embed.add_field(name="direction", value=_safe_field_value(direction), inline=True)
embed.add_field(name="sender_id", value=_safe_field_value(sender_id or ""), inline=True)
embed.add_field(
name="captured_at", value=_safe_field_value(captured_at.isoformat()), inline=True,
)
embed.add_field(
name="raw_content", value=_safe_field_value(raw_content), inline=False,
)
# Discord CDN attachment URLs carry a signed expiry (ex/is/hm query params),
# typically valid ~24h. Fine for same-day triage; a stale link just stops
# rendering the preview without breaking anything else in the embed.
if image_url:
embed.set_image(url=image_url)
return embed
def parse_ping_embed(embed: discord.Embed) -> dict:
values = {field.name: field.value for field in embed.fields}
sender_id = values.get("sender_id")
if sender_id == _EMPTY_FIELD_SENTINEL:
sender_id = None
else:
sender_id = sender_id or None
raw_content = values["raw_content"]
if raw_content == _EMPTY_FIELD_SENTINEL:
raw_content = ""
direction = values.get("direction") or "inbound"
return {
"modality": values["modality"],
"sender_id": sender_id,
"raw_content": raw_content,
"captured_at": datetime.fromisoformat(values["captured_at"]),
"direction": direction,
}