Skip to main content

Webhook Automation

ทริกเกอร์ระบบภายนอกเมื่อ memory เปลี่ยนแปลง — sync, แจ้งเตือน, ทำให้เป็นอัตโนมัติ


Webhook Automation

Webhook ช่วยให้คุณทริกเกอร์ระบบภายนอกเมื่อ Synapse event ทำงาน คู่มือนี้ครอบคลุมรูปแบบ automation ทั่วไป

รูปแบบทั่วไป

รูปแบบ 1: แจ้งเตือนเมื่อ Memory Critical

ส่งข้อความ Slack เมื่อ memory critical ถูกเก็บ:

# Webhook handler (your server)
@app.post("/webhook")
async def handle(request):
    payload = await request.json()
    
    # Verify signature
    if not verify_signature(payload, request.headers):
        return 401
    
    if payload["event"] == "memory.store":
        memory = payload["data"]
        if memory.get("priority") == "critical":
            # Send Slack notification
            await slack.post(
                f"🚨 Critical memory stored: {memory['key']}\n{memory['content'][:200]}"
            )
    
    return 200

ลงทะเบียน webhook:

curl -X POST https://synapse.schaefer.zone/webhooks \
  -H "Authorization: Bearer YOUR_MIND_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://my-app.com/webhook",
    "events": "memory.store",
    "secret": "my-hmac-secret"
  }'

รูปแบบ 2: Sync ไปยังระบบภายนอก

Sync memory ไปยัง Notion, Obsidian หรือ KB ภายนอกใด ๆ:

@app.post("/webhook")
async def sync_to_notion(request):
    payload = await request.json()
    
    if payload["event"] == "memory.store":
        memory = payload["data"]
        # Create Notion page
        await notion.create_page(
            title=memory["key"],
            content=memory["content"],
            tags=memory.get("tags", [])
        )
    
    elif payload["event"] == "memory.delete":
        # Delete from Notion
        await notion.delete_page(memory_id=payload["data"]["id"])
    
    return 200

รูปแบบ 3: ทริกเกอร์ CI/CD

ทริกเกอร์ deployment เมื่อ memory "release" ถูกเก็บ:

@app.post("/webhook")
async def trigger_deploy(request):
    payload = await request.json()
    
    if payload["event"] == "memory.store":
        memory = payload["data"]
        if memory.get("key", "").startswith("release_"):
            # Trigger GitLab pipeline
            await gitlab.trigger_pipeline(
                project="synapse",
                ref="main",
                variables={"RELEASE_MEMORY_ID": memory["id"]}
            )
    
    return 200

รูปแบบ 4: ปลุก Agent เมื่อ Human ส่งข้อความ

ทริกเกอร์การรัน LLM agent เมื่อ human ส่งข้อความแช็ต:

@app.post("/webhook")
async def wake_agent(request):
    payload = await request.json()
    
    if payload["event"] == "chat.message_received":
        message = payload["data"]
        # Queue agent processing job
        await job_queue.enqueue(
            "process_message",
            message_id=message["id"],
            content=message["content"]
        )
    
    return 200

รูปแบบ 5: รวม Metric

ติดตามการเติบโตของ memory, กิจกรรมแช็ต, การทำ task เสร็จ:

@app.post("/webhook")
async def track_metrics(request):
    payload = await request.json()
    event = payload["event"]
    
    metrics = {
        "memory.store": "memories_stored_total",
        "memory.delete": "memories_deleted_total",
        "chat.message_received": "messages_received_total",
        "task.created": "tasks_created_total",
        "task.completed": "tasks_completed_total",
    }
    
    if event in metrics:
        await prometheus.increment(metrics[event])
    
    return 200

การตรวจสอบ Signature

ตรวจสอบ webhook signature เสมอเพื่อป้องกันการปลอมแปลง:

import hmac
import hashlib

def verify_signature(payload_body: bytes, headers, secret: str) -> bool:
    signature = headers.get("X-Synapse-Signature", "")
    if not signature.startswith("sha256="):
        return False
    
    expected = hmac.new(
        secret.encode(),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(f"sha256={expected}", signature)

ตรรกะ Retry

Synapse retry webhook ที่ล้มเหลวด้วย exponential backoff handler ของคุณควร:

  1. ส่งกลับ 200 อย่างรวดเร็ว — อย่าทำงานหนักแบบ synchronous
  2. จัดคิวงาน — ใช้ระบบ background job
  3. เป็น idempotent — event เดียวกันอาจถูกส่งสองครั้ง
@app.post("/webhook")
async def handle(request):
    payload = await request.json()
    # Queue for async processing
    await job_queue.enqueue("process_webhook", payload)
    # Return immediately
    return 200

Debugging Webhook

ตรวจสอบประวัติการจัดส่ง

การจัดส่ง webhook ถูกบันทึก ตรวจสอบการจัดส่งล่าสุดของ webhook:

# Get webhook details including recent deliveries
curl -H "Authorization: Bearer YOUR_MIND_KEY" \
     https://synapse.schaefer.zone/webhooks/wh_001

ทดสอบ webhook ด้วยตนเอง

# Trigger a test event
curl -X POST https://synapse.schaefer.zone/webhooks/wh_001/test \
  -H "Authorization: Bearer YOUR_MIND_KEY"

ปัญหาทั่วไป

ปัญหา วิธีแก้
4xx response ตรวจ handler ส่งกลับ 200
5xx response server error — ตรวจ log แอป
Timeout ส่งกลับ 200 เร็ว, จัดคิวงาน async
การจัดส่งซ้ำ ทำ handler idempotent
Signature ไม่ตรง ตรวจ secret ถูกต้อง

แนวทางปฏิบัติที่ดีที่สุด

ขั้นตอนถัดไป