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 os
import re import re
import sqlite3 import sqlite3
import threading
from email_validator import validate_email, EmailNotValidError from email_validator import validate_email, EmailNotValidError
from flask import Flask, render_template, request, redirect, url_for, jsonify, abort 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(): with app.app_context():
migrate_db() 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 # Public routes
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@@ -230,6 +247,13 @@ def index():
error="Unable to save your entry. Please try again.", error="Unable to save your entry. Please try again.",
guests=[]) guests=[])
logger.info("Added guest: %s %s from %s", first_name, last_name, location) 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')) return redirect(url_for('index'))
try: try:
+2
View File
@@ -13,3 +13,5 @@ LOGO_URL="/static/images/logo.png"
ADMIN_USER=admin ADMIN_USER=admin
ADMIN_PASSWORD=changeme ADMIN_PASSWORD=changeme
SECRET_KEY=change-this-to-a-random-secret-key SECRET_KEY=change-this-to-a-random-secret-key
# Optional: POST new signups as JSON to this URL (e.g. an n8n Webhook node)
WEBHOOK_URL=