"""PatchFirst receiver example (Python 3, standard library only). Pass the original request bytes, before JSON parsing. The secret is the exact UTF-8 string shown in the dashboard; do not base64-decode it. """ import hashlib import hmac import json import re import time def verify_webhook(secret, body, headers, *, now=None): """Return the authenticated event or raise ValueError. No side effects.""" headers = {key.lower(): value for key, value in headers.items()} timestamp = headers.get('x-patchfirst-timestamp', '') signature = headers.get('x-patchfirst-signature', '') if not re.fullmatch(r'[0-9]{1,12}', timestamp): raise ValueError('Invalid timestamp') if abs((time.time() if now is None else now) - int(timestamp)) > 300: raise ValueError('Expired timestamp') if not re.fullmatch(r'sha256=[0-9a-f]{64}', signature): raise ValueError('Invalid signature format') expected = 'sha256=' + hmac.new( secret.encode('utf-8'), timestamp.encode('ascii') + b'.' + body, hashlib.sha256).hexdigest() if not hmac.compare_digest(expected, signature): raise ValueError('Invalid signature') event = json.loads(body) if not isinstance(event, dict) or not isinstance(event.get('id'), str) or not event['id']: raise ValueError('Missing delivery id') if event['id'] != headers.get('x-patchfirst-delivery'): raise ValueError('Delivery id mismatch') if event.get('event') != headers.get('x-patchfirst-event'): raise ValueError('Event mismatch') return event def receive_webhook(secret, body, headers, enqueue_unique, *, now=None): """Verify, then persist once. Return True for new, False for duplicate. enqueue_unique(id, event) MUST atomically persist the event to a durable queue with a UNIQUE constraint on id, returning False for an existing id. Only return HTTP 2xx after this call succeeds. Queue consumers perform business actions transactionally or with the same idempotency key. """ event = verify_webhook(secret, body, headers, now=now) return enqueue_unique(event['id'], event)