{"title":"أتمتة الـ Webhooks","slug":"webhook-automation","category":"guides","summary":"شغّل الأنظمة الخارجية عند تغير الذكريات — مزامنة، إشعارات، أتمتة.","audience":["human","llm"],"tags":["guide","webhooks","automation","integration"],"difficulty":"intermediate","updated":"2026-06-27","word_count":309,"read_minutes":2,"lang":"ar","translated":true,"requested_lang":"ar","content_markdown":"\n# أتمتة الـ Webhooks\n\nتتيح لك الـ Webhooks تشغيل الأنظمة الخارجية عند إطلاق أحداث Synapse. يغطي هذا الدليل\nأنماط أتمتة شائعة.\n\n## الأنماط الشائعة\n\n### النمط 1: إشعار عند ذاكرة حرجة\n\nأرسل رسالة Slack عند تخزين ذاكرة حرجة:\n\n```python\n# معالج الـ webhook (خادمك)\n@app.post(\"/webhook\")\nasync def handle(request):\n    payload = await request.json()\n    \n    # تحقق من التوقيع\n    if not verify_signature(payload, request.headers):\n        return 401\n    \n    if payload[\"event\"] == \"memory.store\":\n        memory = payload[\"data\"]\n        if memory.get(\"priority\") == \"critical\":\n            # أرسل إشعار Slack\n            await slack.post(\n                f\"🚨 Critical memory stored: {memory['key']}\\n{memory['content'][:200]}\"\n            )\n    \n    return 200\n```\n\nسجّل الـ webhook:\n\n```bash\ncurl -X POST https://synapse.schaefer.zone/webhooks \\\n  -H \"Authorization: Bearer YOUR_MIND_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://my-app.com/webhook\",\n    \"events\": \"memory.store\",\n    \"secret\": \"my-hmac-secret\"\n  }'\n```\n\n### النمط 2: مزامنة إلى نظام خارجي\n\nزامن الذكريات إلى Notion، Obsidian، أو أي KB خارجي:\n\n```python\n@app.post(\"/webhook\")\nasync def sync_to_notion(request):\n    payload = await request.json()\n    \n    if payload[\"event\"] == \"memory.store\":\n        memory = payload[\"data\"]\n        # أنشئ صفحة Notion\n        await notion.create_page(\n            title=memory[\"key\"],\n            content=memory[\"content\"],\n            tags=memory.get(\"tags\", [])\n        )\n    \n    elif payload[\"event\"] == \"memory.delete\":\n        # احذف من Notion\n        await notion.delete_page(memory_id=payload[\"data\"][\"id\"])\n    \n    return 200\n```\n\n### النمط 3: تشغيل CI/CD\n\nشغّل نشرًا عند تخزين ذاكرة \"release\":\n\n```python\n@app.post(\"/webhook\")\nasync def trigger_deploy(request):\n    payload = await request.json()\n    \n    if payload[\"event\"] == \"memory.store\":\n        memory = payload[\"data\"]\n        if memory.get(\"key\", \"\").startswith(\"release_\"):\n            # شغّل pipeline GitLab\n            await gitlab.trigger_pipeline(\n                project=\"synapse\",\n                ref=\"main\",\n                variables={\"RELEASE_MEMORY_ID\": memory[\"id\"]}\n            )\n    \n    return 200\n```\n\n### النمط 4: إيقاظ الوكيل عند رسالة الإنسان\n\nشغّل تشغيل وكيل LLM عندما يرسل الإنسان رسالة دردشة:\n\n```python\n@app.post(\"/webhook\")\nasync def wake_agent(request):\n    payload = await request.json()\n    \n    if payload[\"event\"] == \"chat.message_received\":\n        message = payload[\"data\"]\n        # أدرج مهمة معالجة الوكيل في الطابور\n        await job_queue.enqueue(\n            \"process_message\",\n            message_id=message[\"id\"],\n            content=message[\"content\"]\n        )\n    \n    return 200\n```\n\n### النمط 5: تجميع المقاييس\n\nتتبع نمو الذاكرة، نشاط الدردشة، إكمال المهام:\n\n```python\n@app.post(\"/webhook\")\nasync def track_metrics(request):\n    payload = await request.json()\n    event = payload[\"event\"]\n    \n    metrics = {\n        \"memory.store\": \"memories_stored_total\",\n        \"memory.delete\": \"memories_deleted_total\",\n        \"chat.message_received\": \"messages_received_total\",\n        \"task.created\": \"tasks_created_total\",\n        \"task.completed\": \"tasks_completed_total\",\n    }\n    \n    if event in metrics:\n        await prometheus.increment(metrics[event])\n    \n    return 200\n```\n\n## التحقق من التوقيع\n\nتحقق دائمًا من توقيعات الـ webhook لمنع الانتحال:\n\n```python\nimport hmac\nimport hashlib\n\ndef verify_signature(payload_body: bytes, headers, secret: str) -> bool:\n    signature = headers.get(\"X-Synapse-Signature\", \"\")\n    if not signature.startswith(\"sha256=\"):\n        return False\n    \n    expected = hmac.new(\n        secret.encode(),\n        payload_body,\n        hashlib.sha256\n    ).hexdigest()\n    \n    return hmac.compare_digest(f\"sha256={expected}\", signature)\n```\n\n## منطق إعادة المحاولة\n\nيعيد Synapse محاولة الـ webhooks الفاشلة مع تراجع أُسي. يجب أن يفعل معالجك:\n\n1. **يُرجع 200 بسرعة** — لا تفعل عملًا ثقيلًا تزامنيًا\n2. **أدرج العمل في الطابور** — استخدم نظام مهام خلفي\n3. **كن idempotent** — قد يُسلَّم نفس الحدث مرتين\n\n```python\n@app.post(\"/webhook\")\nasync def handle(request):\n    payload = await request.json()\n    # أدرج للمعالجة غير المتزامنة\n    await job_queue.enqueue(\"process_webhook\", payload)\n    # اعد فورًا\n    return 200\n```\n\n## تصحيح الـ Webhooks\n\n### تحقق من سجل التسليم\n\nتُسجَّل تسليمات الـ webhook. تحقق من التسليمات الحديثة لـ webhook الخاص بك:\n\n```bash\n# احصل على تفاصيل الـ webhook بما في ذلك التسليمات الحديثة\ncurl -H \"Authorization: Bearer YOUR_MIND_KEY\" \\\n     https://synapse.schaefer.zone/webhooks/wh_001\n```\n\n### اختبر الـ webhook يدويًا\n\n```bash\n# شغّل حدث اختبار\ncurl -X POST https://synapse.schaefer.zone/webhooks/wh_001/test \\\n  -H \"Authorization: Bearer YOUR_MIND_KEY\"\n```\n\n### مشكلات شائعة\n\n| المشكلة | الإصلاح |\n|-------|-----|\n| استجابات 4xx | تحقق أن معالجك يُرجع 200 |\n| استجابات 5xx | خطأ خادم — تحقق من سجلات تطبيقك |\n| انتهاء المهلة | أرجع 200 بسرعة، أدرج العمل غير المتزامن |\n| تسليمات مكررة | اجعل المعالج idempotent |\n| عدم تطابق التوقيع | تحقق أن السر صحيح |\n\n## أفضل الممارسات\n\n> [!TIP]\n> - **تحقق من التوقيعات دائمًا** — لا تتخطى هذا أبدًا\n> - **أرجع 200 بسرعة** — لا تحجب Synapse\n> - **كن idempotent** — تعامل مع التسليمات المكررة\n> - **استخدم أحداثًا محددة** — `memory.store` لا `*`\n> - **راقب إخفاقات التسليم** — أعد تنبيهًا\n\n## الخطوات التالية\n\n- [Webhooks API](/docs/api/webhooks)\n- [Cron والمجدول](/docs/api/cron)\n- [وكيل LLM الدائم](/docs/guides/persistent-llm-agent)\n","content_html":"<h1>أتمتة الـ Webhooks</h1>\n<p>تتيح لك الـ Webhooks تشغيل الأنظمة الخارجية عند إطلاق أحداث Synapse. يغطي هذا الدليل\nأنماط أتمتة شائعة.</p>\n<h2>الأنماط الشائعة</h2>\n<h3>النمط 1: إشعار عند ذاكرة حرجة</h3>\n<p>أرسل رسالة Slack عند تخزين ذاكرة حرجة:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-comment\"># معالج الـ webhook (خادمك)</span>\n<span class=\"hljs-meta\">@app.post(<span class=\"hljs-params\"><span class=\"hljs-string\">&quot;/webhook&quot;</span></span>)</span>\n<span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">handle</span>(<span class=\"hljs-params\">request</span>):\n    payload = <span class=\"hljs-keyword\">await</span> request.json()\n    \n    <span class=\"hljs-comment\"># تحقق من التوقيع</span>\n    <span class=\"hljs-keyword\">if</span> <span class=\"hljs-keyword\">not</span> verify_signature(payload, request.headers):\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">401</span>\n    \n    <span class=\"hljs-keyword\">if</span> payload[<span class=\"hljs-string\">&quot;event&quot;</span>] == <span class=\"hljs-string\">&quot;memory.store&quot;</span>:\n        memory = payload[<span class=\"hljs-string\">&quot;data&quot;</span>]\n        <span class=\"hljs-keyword\">if</span> memory.get(<span class=\"hljs-string\">&quot;priority&quot;</span>) == <span class=\"hljs-string\">&quot;critical&quot;</span>:\n            <span class=\"hljs-comment\"># أرسل إشعار Slack</span>\n            <span class=\"hljs-keyword\">await</span> slack.post(\n                <span class=\"hljs-string\">f&quot;🚨 Critical memory stored: <span class=\"hljs-subst\">{memory[<span class=\"hljs-string\">&#x27;key&#x27;</span>]}</span>\\n<span class=\"hljs-subst\">{memory[<span class=\"hljs-string\">&#x27;content&#x27;</span>][:<span class=\"hljs-number\">200</span>]}</span>&quot;</span>\n            )\n    \n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">200</span></code></pre><p>سجّل الـ webhook:</p>\n<pre><code class=\"hljs language-bash\">curl -X POST https://synapse.schaefer.zone/webhooks \\\n  -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_MIND_KEY&quot;</span> \\\n  -H <span class=\"hljs-string\">&quot;Content-Type: application/json&quot;</span> \\\n  -d <span class=\"hljs-string\">&#x27;{\n    &quot;url&quot;: &quot;https://my-app.com/webhook&quot;,\n    &quot;events&quot;: &quot;memory.store&quot;,\n    &quot;secret&quot;: &quot;my-hmac-secret&quot;\n  }&#x27;</span></code></pre><h3>النمط 2: مزامنة إلى نظام خارجي</h3>\n<p>زامن الذكريات إلى Notion، Obsidian، أو أي KB خارجي:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-meta\">@app.post(<span class=\"hljs-params\"><span class=\"hljs-string\">&quot;/webhook&quot;</span></span>)</span>\n<span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">sync_to_notion</span>(<span class=\"hljs-params\">request</span>):\n    payload = <span class=\"hljs-keyword\">await</span> request.json()\n    \n    <span class=\"hljs-keyword\">if</span> payload[<span class=\"hljs-string\">&quot;event&quot;</span>] == <span class=\"hljs-string\">&quot;memory.store&quot;</span>:\n        memory = payload[<span class=\"hljs-string\">&quot;data&quot;</span>]\n        <span class=\"hljs-comment\"># أنشئ صفحة Notion</span>\n        <span class=\"hljs-keyword\">await</span> notion.create_page(\n            title=memory[<span class=\"hljs-string\">&quot;key&quot;</span>],\n            content=memory[<span class=\"hljs-string\">&quot;content&quot;</span>],\n            tags=memory.get(<span class=\"hljs-string\">&quot;tags&quot;</span>, [])\n        )\n    \n    <span class=\"hljs-keyword\">elif</span> payload[<span class=\"hljs-string\">&quot;event&quot;</span>] == <span class=\"hljs-string\">&quot;memory.delete&quot;</span>:\n        <span class=\"hljs-comment\"># احذف من Notion</span>\n        <span class=\"hljs-keyword\">await</span> notion.delete_page(memory_id=payload[<span class=\"hljs-string\">&quot;data&quot;</span>][<span class=\"hljs-string\">&quot;id&quot;</span>])\n    \n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">200</span></code></pre><h3>النمط 3: تشغيل CI/CD</h3>\n<p>شغّل نشرًا عند تخزين ذاكرة &quot;release&quot;:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-meta\">@app.post(<span class=\"hljs-params\"><span class=\"hljs-string\">&quot;/webhook&quot;</span></span>)</span>\n<span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">trigger_deploy</span>(<span class=\"hljs-params\">request</span>):\n    payload = <span class=\"hljs-keyword\">await</span> request.json()\n    \n    <span class=\"hljs-keyword\">if</span> payload[<span class=\"hljs-string\">&quot;event&quot;</span>] == <span class=\"hljs-string\">&quot;memory.store&quot;</span>:\n        memory = payload[<span class=\"hljs-string\">&quot;data&quot;</span>]\n        <span class=\"hljs-keyword\">if</span> memory.get(<span class=\"hljs-string\">&quot;key&quot;</span>, <span class=\"hljs-string\">&quot;&quot;</span>).startswith(<span class=\"hljs-string\">&quot;release_&quot;</span>):\n            <span class=\"hljs-comment\"># شغّل pipeline GitLab</span>\n            <span class=\"hljs-keyword\">await</span> gitlab.trigger_pipeline(\n                project=<span class=\"hljs-string\">&quot;synapse&quot;</span>,\n                ref=<span class=\"hljs-string\">&quot;main&quot;</span>,\n                variables={<span class=\"hljs-string\">&quot;RELEASE_MEMORY_ID&quot;</span>: memory[<span class=\"hljs-string\">&quot;id&quot;</span>]}\n            )\n    \n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">200</span></code></pre><h3>النمط 4: إيقاظ الوكيل عند رسالة الإنسان</h3>\n<p>شغّل تشغيل وكيل LLM عندما يرسل الإنسان رسالة دردشة:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-meta\">@app.post(<span class=\"hljs-params\"><span class=\"hljs-string\">&quot;/webhook&quot;</span></span>)</span>\n<span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">wake_agent</span>(<span class=\"hljs-params\">request</span>):\n    payload = <span class=\"hljs-keyword\">await</span> request.json()\n    \n    <span class=\"hljs-keyword\">if</span> payload[<span class=\"hljs-string\">&quot;event&quot;</span>] == <span class=\"hljs-string\">&quot;chat.message_received&quot;</span>:\n        message = payload[<span class=\"hljs-string\">&quot;data&quot;</span>]\n        <span class=\"hljs-comment\"># أدرج مهمة معالجة الوكيل في الطابور</span>\n        <span class=\"hljs-keyword\">await</span> job_queue.enqueue(\n            <span class=\"hljs-string\">&quot;process_message&quot;</span>,\n            message_id=message[<span class=\"hljs-string\">&quot;id&quot;</span>],\n            content=message[<span class=\"hljs-string\">&quot;content&quot;</span>]\n        )\n    \n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">200</span></code></pre><h3>النمط 5: تجميع المقاييس</h3>\n<p>تتبع نمو الذاكرة، نشاط الدردشة، إكمال المهام:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-meta\">@app.post(<span class=\"hljs-params\"><span class=\"hljs-string\">&quot;/webhook&quot;</span></span>)</span>\n<span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">track_metrics</span>(<span class=\"hljs-params\">request</span>):\n    payload = <span class=\"hljs-keyword\">await</span> request.json()\n    event = payload[<span class=\"hljs-string\">&quot;event&quot;</span>]\n    \n    metrics = {\n        <span class=\"hljs-string\">&quot;memory.store&quot;</span>: <span class=\"hljs-string\">&quot;memories_stored_total&quot;</span>,\n        <span class=\"hljs-string\">&quot;memory.delete&quot;</span>: <span class=\"hljs-string\">&quot;memories_deleted_total&quot;</span>,\n        <span class=\"hljs-string\">&quot;chat.message_received&quot;</span>: <span class=\"hljs-string\">&quot;messages_received_total&quot;</span>,\n        <span class=\"hljs-string\">&quot;task.created&quot;</span>: <span class=\"hljs-string\">&quot;tasks_created_total&quot;</span>,\n        <span class=\"hljs-string\">&quot;task.completed&quot;</span>: <span class=\"hljs-string\">&quot;tasks_completed_total&quot;</span>,\n    }\n    \n    <span class=\"hljs-keyword\">if</span> event <span class=\"hljs-keyword\">in</span> metrics:\n        <span class=\"hljs-keyword\">await</span> prometheus.increment(metrics[event])\n    \n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">200</span></code></pre><h2>التحقق من التوقيع</h2>\n<p>تحقق دائمًا من توقيعات الـ webhook لمنع الانتحال:</p>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-keyword\">import</span> hmac\n<span class=\"hljs-keyword\">import</span> hashlib\n\n<span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">verify_signature</span>(<span class=\"hljs-params\">payload_body: <span class=\"hljs-built_in\">bytes</span>, headers, secret: <span class=\"hljs-built_in\">str</span></span>) -&gt; <span class=\"hljs-built_in\">bool</span>:\n    signature = headers.get(<span class=\"hljs-string\">&quot;X-Synapse-Signature&quot;</span>, <span class=\"hljs-string\">&quot;&quot;</span>)\n    <span class=\"hljs-keyword\">if</span> <span class=\"hljs-keyword\">not</span> signature.startswith(<span class=\"hljs-string\">&quot;sha256=&quot;</span>):\n        <span class=\"hljs-keyword\">return</span> <span class=\"hljs-literal\">False</span>\n    \n    expected = hmac.new(\n        secret.encode(),\n        payload_body,\n        hashlib.sha256\n    ).hexdigest()\n    \n    <span class=\"hljs-keyword\">return</span> hmac.compare_digest(<span class=\"hljs-string\">f&quot;sha256=<span class=\"hljs-subst\">{expected}</span>&quot;</span>, signature)</code></pre><h2>منطق إعادة المحاولة</h2>\n<p>يعيد Synapse محاولة الـ webhooks الفاشلة مع تراجع أُسي. يجب أن يفعل معالجك:</p>\n<ol>\n<li><strong>يُرجع 200 بسرعة</strong> — لا تفعل عملًا ثقيلًا تزامنيًا</li>\n<li><strong>أدرج العمل في الطابور</strong> — استخدم نظام مهام خلفي</li>\n<li><strong>كن idempotent</strong> — قد يُسلَّم نفس الحدث مرتين</li>\n</ol>\n<pre><code class=\"hljs language-python\"><span class=\"hljs-meta\">@app.post(<span class=\"hljs-params\"><span class=\"hljs-string\">&quot;/webhook&quot;</span></span>)</span>\n<span class=\"hljs-keyword\">async</span> <span class=\"hljs-keyword\">def</span> <span class=\"hljs-title function_\">handle</span>(<span class=\"hljs-params\">request</span>):\n    payload = <span class=\"hljs-keyword\">await</span> request.json()\n    <span class=\"hljs-comment\"># أدرج للمعالجة غير المتزامنة</span>\n    <span class=\"hljs-keyword\">await</span> job_queue.enqueue(<span class=\"hljs-string\">&quot;process_webhook&quot;</span>, payload)\n    <span class=\"hljs-comment\"># اعد فورًا</span>\n    <span class=\"hljs-keyword\">return</span> <span class=\"hljs-number\">200</span></code></pre><h2>تصحيح الـ Webhooks</h2>\n<h3>تحقق من سجل التسليم</h3>\n<p>تُسجَّل تسليمات الـ webhook. تحقق من التسليمات الحديثة لـ webhook الخاص بك:</p>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># احصل على تفاصيل الـ webhook بما في ذلك التسليمات الحديثة</span>\ncurl -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_MIND_KEY&quot;</span> \\\n     https://synapse.schaefer.zone/webhooks/wh_001</code></pre><h3>اختبر الـ webhook يدويًا</h3>\n<pre><code class=\"hljs language-bash\"><span class=\"hljs-comment\"># شغّل حدث اختبار</span>\ncurl -X POST https://synapse.schaefer.zone/webhooks/wh_001/test \\\n  -H <span class=\"hljs-string\">&quot;Authorization: Bearer YOUR_MIND_KEY&quot;</span></code></pre><h3>مشكلات شائعة</h3>\n<table>\n<thead>\n<tr>\n<th>المشكلة</th>\n<th>الإصلاح</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>استجابات 4xx</td>\n<td>تحقق أن معالجك يُرجع 200</td>\n</tr>\n<tr>\n<td>استجابات 5xx</td>\n<td>خطأ خادم — تحقق من سجلات تطبيقك</td>\n</tr>\n<tr>\n<td>انتهاء المهلة</td>\n<td>أرجع 200 بسرعة، أدرج العمل غير المتزامن</td>\n</tr>\n<tr>\n<td>تسليمات مكررة</td>\n<td>اجعل المعالج idempotent</td>\n</tr>\n<tr>\n<td>عدم تطابق التوقيع</td>\n<td>تحقق أن السر صحيح</td>\n</tr>\n</tbody></table>\n<h2>أفضل الممارسات</h2>\n<div class=\"callout callout-ok\"></div><h2>الخطوات التالية</h2>\n<ul>\n<li><a href=\"/docs/api/webhooks\">Webhooks API</a></li>\n<li><a href=\"/docs/api/cron\">Cron والمجدول</a></li>\n<li><a href=\"/docs/guides/persistent-llm-agent\">وكيل LLM الدائم</a></li>\n</ul>\n","urls":{"html":"/docs/guides/webhook-automation","text":"/docs/guides/webhook-automation?format=text","json":"/docs/guides/webhook-automation?format=json","llm":"/docs/guides/webhook-automation?format=llm"},"translations_available":["en","zh","hi","es","fr","ar","pt","ru","ja","de","it","ko","nl","pl","tr","sv","vi","th","id","uk"]}