feat: add webhook integration for new guestbook submissions

Posts signup data as JSON to WEBHOOK_URL (e.g. an n8n Webhook node)
in a daemon thread so it never blocks the visitor-facing response.
This commit is contained in:
2026-03-11 15:30:31 -06:00
parent 2d4eac6583
commit 9ebac80f35
2 changed files with 27 additions and 1 deletions
+24
View File
@@ -2,6 +2,7 @@ import logging
import os
import re
import sqlite3
import threading
from email_validator import validate_email, EmailNotValidError
from flask import Flask, render_template, request, redirect, url_for, jsonify, abort
@@ -173,6 +174,22 @@ def is_valid_email(email):
with app.app_context():
migrate_db()
# ---------------------------------------------------------------------------
# Webhook
# ---------------------------------------------------------------------------
def _fire_webhook(payload):
url = os.environ.get("WEBHOOK_URL", "")
if not url:
return
try:
import urllib.request, json as _json
data = _json.dumps(payload).encode()
req = urllib.request.Request(url, data=data, headers={"Content-Type": "application/json"})
urllib.request.urlopen(req, timeout=5)
except Exception as e:
logger.warning("Webhook delivery failed: %s", e)
# ---------------------------------------------------------------------------
# Public routes
# ---------------------------------------------------------------------------
@@ -230,6 +247,13 @@ def index():
error="Unable to save your entry. Please try again.",
guests=[])
logger.info("Added guest: %s %s from %s", first_name, last_name, location)
threading.Thread(target=_fire_webhook, args=({
"first_name": first_name,
"last_name": last_name,
"email": email,
"location": location,
"newsletter_opt_in": newsletter_opt_in,
},), daemon=True).start()
return redirect(url_for('index'))
try: