chorus/bot/chorus_bot/ping.py

78 lines
2.7 KiB
Python
Raw Permalink 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",
) -> 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,
)
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,
}