Webhook Automation Guide
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
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'}), 200Explanation
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
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'}), 200Explanation
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
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'}), 200Explanation
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
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
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'}), 200Explanation
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.