-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebhook_server.py
More file actions
97 lines (80 loc) · 3.3 KB
/
webhook_server.py
File metadata and controls
97 lines (80 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from flask import Flask, request, jsonify
from pyngrok import ngrok
from dotenv import load_dotenv
import os
# Load .env from same directory
load_dotenv(os.path.join(os.path.dirname(__file__), '.env'))
# Set ngrok auth token
ngrok.set_auth_token(os.getenv('NGROK_AUTHTOKEN'))
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def handle_webhook():
"""
Receives webhook from Simplex when workflow completes.
Payload includes:
- session_id: Unique session identifier
- workflow_id: The workflow that was run
- success: Boolean success status
- screenshot_url: URL to download PDF of final result page
- agent_response: Agent's final output
- error_message: Error details if failed
- agentic_steps: Number of AI steps taken
- browser_seconds: Total browser time
- metadata: Your custom metadata passed through
- structured_output: Custom structured data fields extracted by the workflow
"""
payload = request.get_json()
print("\n" + "=" * 60)
print("WEBHOOK RECEIVED")
print("=" * 60)
print(payload)
print(f"Session ID: {payload.get('session_id')}")
print(f"Workflow ID: {payload.get('workflow_id')}")
print(f"Success: {payload.get('success')}")
print(f"Screenshot URL: {payload.get('screenshot_url')}")
print(f"Agentic Steps: {payload.get('agentic_steps')}")
print(f"Browser Seconds: {payload.get('browser_seconds')}")
print(f"Session metadata: {payload.get('metadata')}")
print(f"Workflow metadata: {payload.get('workflow_metadata')}")
if payload.get('success'):
print("\nAgent Response:")
print(payload.get('agent_response', 'N/A'))
# Print structured output if present
if payload.get('structured_output'):
print("\n--- Structured Output ---")
structured = payload.get('structured_output')
if isinstance(structured, dict):
# Display each extracted field
for key, value in structured.items():
# Format the key nicely (authorization_number -> Authorization Number)
display_key = key.replace('_', ' ').title()
print(f" {display_key}: {value}")
else:
print(structured)
print("--- End Structured Output ---")
else:
print("\nError Message:")
print(payload.get('error_message', 'Unknown error'))
if payload.get('error_screenshot_url'):
print(f"Error Screenshot: {payload.get('error_screenshot_url')}")
if payload.get('metadata'):
print("\nMetadata:")
print(payload.get('metadata'))
print("=" * 60 + "\n")
return jsonify({'received': True})
@app.route('/health', methods=['GET'])
def health():
return jsonify({'status': 'ok'})
if __name__ == '__main__':
port = 5001
# Start ngrok tunnel
public_url = ngrok.connect(port).public_url
# Save the ngrok URL to a file for the TypeScript example to read
url_file = os.path.join(os.path.dirname(__file__), 'webhook-url.txt')
with open(url_file, 'w') as f:
f.write(public_url)
print(f"Ngrok tunnel: {public_url}")
print(f"Webhook endpoint: {public_url}/webhook")
print(f"URL saved to: {url_file}")
print(f"\nLocal server: http://localhost:{port}")
app.run(host='0.0.0.0', port=port)