# Webhook Automation Guide Practical patterns for automating workflows with Synapse webhooks. ## Pattern 1: Memory Log Log every new memory to a file or external service. ### Setup ```python from flask import Flask, request, jsonify import hashlib, hmac app = Flask(__name__) WEBHOOK_SECRET = 'your-webhook-secret' @app.route('/webhook', methods=['POST']) def webhook(): # Verify signature sig = request.headers.get('X-Synapse-Signature', '') expected = 'sha256=' + hmac.new(WEBHOOK_SECRET.encode(), request.get_data(), hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): return jsonify({'error': 'invalid signature'}), 401 event = request.headers.get('X-Synapse-Event') if event == 'memory.created': data = request.get_json() with open('memory-log.txt', 'a') as f: f.write(f"{data['event']}: {data['data']['key']} = {data['data']['content'][:100]}\n") return jsonify({'status': 'ok'}), 200 return jsonify({'status': 'ignored'}), 200 ``` ### Explanation The handler listens for `memory.created` events and logs each new memory's key and a content preview to a file. This is useful for auditing, debugging, or creating a secondary backup of important memories. ## Pattern 2: Memory Summary Summarize new memories using an LLM and store the summary. ### Setup ```python from flask import Flask, request, jsonify import hashlib, hmac app = Flask(__name__) WEBHOOK_SECRET = 'your-webhook-secret' @app.route('/webhook', methods=['POST']) def webhook(): sig = request.headers.get('X-Synapse-Signature', '') expected = 'sha256=' + hmac.new(WEBHOOK_SECRET.encode(), request.get_data(), hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): return jsonify({'error': 'invalid signature'}), 401 event = request.headers.get('X-Synapse-Event') if event in ('memory.created', 'memory.updated'): data = request.get_json() content = data['data']['content'] # Send to your LLM for summarization summary = summarize_with_llm(content) # your function store_summary(data['data']['key'], summary) return jsonify({'status': 'summarized'}), 200 return jsonify({'status': 'ignored'}), 200 ``` ### Explanation This pattern captures both `memory.created` and `memory.updated` events, sends the content to an LLM for summarization, and stores the result. Useful for maintaining a condensed knowledge base. ## Pattern 3: Sync to Note-Taking App Forward new memories to Notion, Obsidian, or similar tools. ### Setup ```python from flask import Flask, request, jsonify import hashlib, hmac, requests app = Flask(__name__) WEBHOOK_SECRET = 'your-webhook-secret' NOTION_API_KEY = 'your-notion-key' NOTION_DATABASE_ID = 'your-database-id' @app.route('/webhook', methods=['POST']) def webhook(): sig = request.headers.get('X-Synapse-Signature', '') expected = 'sha256=' + hmac.new(WEBHOOK_SECRET.encode(), request.get_data(), hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): return jsonify({'error': 'invalid signature'}), 401 event = request.headers.get('X-Synapse-Event') if event == 'memory.created': data = request.get_json() # Create Notion page requests.post('https://api.notion.com/v1/pages', headers={ 'Authorization': f'Bearer {NOTION_API_KEY}', 'Content-Type': 'application/json', 'Notion-Version': '2022-06-28', }, json={ 'parent': {'database_id': NOTION_DATABASE_ID}, 'properties': { 'Title': {'title': [{'text': {'content': data['data']['key']}}]}, 'Content': {'rich_text': [{'text': {'content': data['data']['content'][:2000]}}]}, 'Category': {'select': {'name': data['data'].get('category', 'note')}}, }, }) return jsonify({'status': 'synced'}), 200 return jsonify({'status': 'ignored'}), 200 ``` ### Explanation This pattern forwards each new memory to a Notion database, preserving the key as the title, content as a text property, and category as a select field. Adapt the API call for Obsidian, Logseq, or other tools. ## Pattern 4: Monitoring & Alerting Get notified when memories are deleted or when tasks fail. ### Setup ```python from flask import Flask, request, jsonify import hashlib, hmac app = Flask(__name__) WEBHOOK_SECRET = 'your-webhook-secret' @app.route('/webhook', methods=['POST']) def webhook(): sig = request.headers.get('X-Synapse-Signature', '') expected = 'sha256=' + hmac.new(WEBHOOK_SECRET.encode(), request.get_data(), hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): return jsonify({'error': 'invalid signature'}), 401 event = request.headers.get('X-Synapse-Event') data = request.get_json() if event == 'memory.deleted': send_alert(f"Memory deleted: {data['data']['key']}") elif event == 'task.updated': task_data = data['data'] if task_data.get('status') == 'failed': send_alert(f"Task failed: {task_data.get('name', 'unknown')}") return jsonify({'status': 'ok'}), 200 def send_alert(message): # Send to Slack, Discord, email, etc. print(f'ALERT: {message}') ``` ### Explanation This pattern monitors for `memory.deleted` and `task.updated` events. When a memory is deleted or a task fails, it triggers an alert. Useful for monitoring and ensuring data integrity. ## Pattern 5: Chat Message Relay Forward chat messages to an external system for logging or analysis. ### Setup ```python from flask import Flask, request, jsonify import hashlib, hmac app = Flask(__name__) WEBHOOK_SECRET = 'your-webhook-secret' @app.route('/webhook', methods=['POST']) def webhook(): sig = request.headers.get('X-Synapse-Signature', '') expected = 'sha256=' + hmac.new(WEBHOOK_SECRET.encode(), request.get_data(), hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): return jsonify({'error': 'invalid signature'}), 401 event = request.headers.get('X-Synapse-Event') if event == 'chat.message_sent': data = request.get_json() # Process chat message log_chat_message(data['data']) return jsonify({'status': 'ok'}), 200 return jsonify({'status': 'ignored'}), 200 ``` ### Explanation This pattern listens for `chat.message_sent` events and forwards them to an external logging or analysis system. Useful for conversation analytics, compliance logging, or integration with CRM systems.