Skip to main content

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'}), 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

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

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

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'}), 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.