from __future__ import annotations import hashlib import hmac def verify_webhook_signature( secret: str, body: bytes, signature_header: str, ) -> bool: if not secret or not signature_header: return False expected = hmac.new( secret.encode("utf-8"), body, hashlib.sha256, ).hexdigest() received = signature_header.replace("sha256=", "").strip() return hmac.compare_digest(expected, received) def extract_signature(headers: dict[str, str]) -> str | None: for key, value in headers.items(): if key.lower() in ("x-bluebubbles-signature", "x-hub-signature-256"): return value return None