Updated to submission completed.

This commit is contained in:
David 2025-12-08 16:02:45 +01:00
parent 54f429bf50
commit 0453b9d3d0

View file

@ -47,7 +47,10 @@ def signature_required(f):
def decorated_function(*args, **kwargs):
if DISABLE_VERIFICATION:
app.logger.info("Webhook secret verification is DISABLED.")
# ... (rest of signature check logic)
return f(*args, **kwargs)
# Verify specific to DocuSeal logic usually goes here
# (Assuming your original verification logic was here)
return f(*args, **kwargs)
return decorated_function
@ -55,32 +58,61 @@ def signature_required(f):
@app.route('/webhook/docuseal', methods=['POST'])
@signature_required
def docuseal_webhook():
"""Main webhook endpoint with advanced filename and audit log control."""
"""Main webhook endpoint handling form.completed and submission.completed."""
app.logger.info(f"Webhook endpoint hit by {request.remote_addr}")
json_data = request.get_json()
if not json_data:
app.logger.error("Received request with invalid or missing JSON body.")
return 'Invalid JSON', 400
if json_data.get('event_type') == 'form.completed':
app.logger.info("Received 'form.completed' event.")
data = json_data.get('data', {})
submission = data.get('submission', {})
event_type = json_data.get('event_type')
# Handle both 'form.completed' (old) and 'submission.completed' (new)
if event_type in ['form.completed', 'submission.completed']:
app.logger.info(f"Received '{event_type}' event.")
data = json_data.get('data', {})
submission = data.get('submission', {}) # Might be empty in 'submission.completed'
# --- Extract Submitter Info ---
# 1. Try top-level data (form.completed)
submitter_name = data.get('name')
submitter_email = data.get('email')
# 2. If null, try extracting from 'submitters' list (submission.completed)
if not submitter_name and not submitter_email:
submitters_list = data.get('submitters', [])
# Priority: Try to find a Name first
for person in submitters_list:
if person.get('name'):
submitter_name = person.get('name')
break
# If still no name, try to find an Email
if not submitter_name:
for person in submitters_list:
if person.get('email'):
submitter_email = person.get('email')
break
if submitter_name:
app.logger.info(f"Identified submitter name from list: {submitter_name}")
elif submitter_email:
app.logger.info(f"Identified submitter email from list: {submitter_email}")
urls_to_process = []
# <-- KEY CHANGE: Conditionally add the audit log URL -->
# --- Handle Audit Log ---
if not SKIP_AUDIT_LOG:
# Check submission object first, then data object
audit_log_url = submission.get('audit_log_url') or data.get('audit_log_url')
if audit_log_url:
urls_to_process.append(audit_log_url)
else:
app.logger.info("Skipping audit log download as per configuration (SKIP_AUDIT_LOG=true).")
app.logger.info("Skipping audit log download (SKIP_AUDIT_LOG=true).")
# Add all other document URLs
# --- Handle Documents ---
# The structure for documents is identical in both event types
for document in data.get('documents', []):
if document.get('url'):
urls_to_process.append(document.get('url'))
@ -97,7 +129,10 @@ def docuseal_webhook():
download_thread = threading.Thread(target=download_document, args=thread_args)
download_thread.start()
return jsonify(status="acknowledged"), 200
return jsonify(status="acknowledged"), 200
app.logger.info(f"Ignored event type: {event_type}")
return jsonify(status="ignored_event_type"), 200
def download_document(url, logger, consume_dir, submitter_name, submitter_email):
@ -114,6 +149,8 @@ def download_document(url, logger, consume_dir, submitter_name, submitter_email)
if APPEND_SUBMITTER_INFO:
identifier = submitter_name or submitter_email
if identifier:
# Clean identifier slightly to be filesystem safe
identifier = "".join([c for c in identifier if c.isalnum() or c in " ._-@"]).strip()
prefix = f"{identifier} - "
timestamp = ""
@ -148,4 +185,4 @@ def download_document(url, logger, consume_dir, submitter_name, submitter_email)
@app.route('/health', methods=['GET'])
def health_check():
"""A simple health check endpoint."""
return "OK", 200
return "OK", 200