Private
Public Access
Renames the app's display name everywhere (page titles, PWA manifest, TopBar, email subject lines, HMAC signature header) and its internal technical slug from chatapp to ds-chat/ds_chat: the Python package name and console script, the systemd unit and its user/group/paths, the deploy scripts, the Docker container names, and the Postgres database name. The live dev Postgres role stays "chatapp" -- renaming a role requires disconnecting the session using it, which needed a temporary superuser role Claude's auto-mode classifier correctly declined to create unsupervised. Functionally invisible (it's just a login credential), but worth knowing about if this ever needs fully cleaning up by hand. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
import hashlib
|
|
import hmac
|
|
import json
|
|
import logging
|
|
|
|
import httpx
|
|
|
|
from app.models import EventSubscription
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
_TIMEOUT_SECONDS = 5.0
|
|
|
|
|
|
async def deliver_event(subscription: EventSubscription, event_type: str, payload: dict) -> None:
|
|
"""POST a signed event to a subscription's target_url.
|
|
|
|
Fire-once, best-effort: no retry/backoff, any failure is logged and
|
|
swallowed rather than raised -- a slow or dead third-party endpoint must
|
|
never affect message delivery to real room members. Safe to run in a
|
|
background asyncio.create_task (unlike the Phase 4 push lesson) because
|
|
there's no DB session involved here, just the already-serialized
|
|
payload and secret -- nothing that can outlive an event loop.
|
|
"""
|
|
body = json.dumps({"event": event_type, "data": payload}).encode()
|
|
signature = hmac.new(subscription.signing_secret.encode(), body, hashlib.sha256).hexdigest()
|
|
|
|
try:
|
|
async with httpx.AsyncClient(timeout=_TIMEOUT_SECONDS) as client:
|
|
await client.post(
|
|
subscription.target_url,
|
|
content=body,
|
|
headers={
|
|
"Content-Type": "application/json",
|
|
"X-DS-Chat-Signature": f"sha256={signature}",
|
|
},
|
|
)
|
|
except httpx.HTTPError:
|
|
logger.warning(
|
|
"Failed to deliver %s event to subscription %s", event_type, subscription.id
|
|
)
|