- يجب أن تكون البدائيات الأساسية هي receive و send، لا reply.
- الرد ليس إلا علاقة على رسالة صادرة.
- الدور وسيلة ملائمة لمعالجة الوارد، وليس مالك التسليم.
- يجب أن يكون الإرسال قائمًا على السياق:
begin، التصيير، المعاينة أو البث، الإرسال النهائي، التثبيت، الفشل. - يجب أن يكون الاستقبال قائمًا على السياق أيضًا: التطبيع، إزالة التكرار، التوجيه، التسجيل، الإرسال للمعالجة، إقرار المنصة، الفشل.
- يجب أن تنكمش SDK العامة للـ Plugin إلى سطح صغير واحد للصادر من القنوات.
المشكلات
نمت حزمة القنوات الحالية من عدة احتياجات محلية صحيحة:- تستخدم محولات الوارد البسيطة
runtime.channel.inbound.run. - تستخدم المحولات الغنية
runtime.channel.inbound.runPreparedReply. - تستخدم المساعدات القديمة
dispatchInboundReplyWithBase، وrecordInboundSessionAndDispatchReply، ومساعدات حمولة الرد، وتجزئة الردود، ومراجع الرد، ومساعدات وقت التشغيل الصادر. - يعيش بث المعاينة في مرسلات خاصة بالقنوات.
- تجري إضافة ديمومة التسليم النهائي حول مسارات حمولة الرد الحالية.
الأهداف
- دورة حياة مركزية واحدة لكل مسارات استقبال وإرسال رسائل القنوات.
- إرسالات نهائية دائمة افتراضيًا في دورة حياة الرسائل الجديدة بعد أن يعلن المحول سلوكًا آمنًا لإعادة التشغيل.
- دلالات مشتركة للمعاينة، والتعديل، والبث، والإنهاء، وإعادة المحاولة، والاسترداد، والإيصال.
- سطح SDK صغير للـ Plugin يمكن للـ Plugins الخارجية تعلمه وصيانته.
- توافق لمستدعي توافق رد الوارد الحاليين أثناء الترحيل.
- نقاط امتداد واضحة لقدرات القنوات الجديدة.
- لا فروع خاصة بمنصات محددة في المركز.
- لا رسائل قناة بدلتا الرموز. يظل بث القنوات معاينة رسالة، أو تعديلًا، أو إلحاقًا، أو تسليم كتلة مكتملة.
- بيانات تعريف منظمة من منشأ OpenClaw للمخرجات التشغيلية/النظامية حتى لا تدخل أعطال Gateway المرئية مجددًا إلى الغرف المشتركة المفعلة للبوت كطلبات جديدة.
غير الأهداف
- عدم إجبار كل قناة حالية على تسليم الرسائل الدائم في المرحلة الأولى.
- عدم إجبار كل قناة على سلوك النقل الأصلي نفسه.
- عدم تعليم المركز مواضيع Telegram، أو البث الأصلي في Slack، أو تنقيحات Matrix، أو بطاقات Feishu، أو صوت QQ، أو أنشطة Teams.
- عدم نشر كل مساعدات الترحيل الداخلية كواجهة SDK مستقرة.
- عدم جعل إعادة المحاولة تعيد تشغيل عمليات منصة مكتملة غير متماثلة.
النموذج المرجعي
لدى Vercel Chat نموذج ذهني عام جيد:ChatThreadChannelMessage- طرق محول مثل
postMessage، وeditMessage، وdeleteMessage، وstream، وstartTyping، وجلب السجل - محول حالة لإزالة التكرار، والأقفال، والطوابير، والاستمرارية
- نيات إرسال صادرة دائمة قبل استدعاءات النقل المباشر.
- سياقات إرسال صريحة تتضمن البدء، والتثبيت، والفشل.
- سياقات استقبال تعرف سياسة الإقرار للمنصة.
- إيصالات تنجو من إعادة التشغيل ويمكنها قيادة التعديلات، والحذف، والاسترداد، ومنع التكرار.
- SDK عامة أصغر. يمكن للـ Plugins المضمنة استخدام مساعدات وقت التشغيل الداخلية، لكن يجب أن ترى الـ Plugins الخارجية واجهة برمجة رسائل واحدة متماسكة.
- سلوك خاص بالوكلاء: الجلسات، والنصوص، وبث الكتل، وتقدم الأدوات، والموافقات، وتوجيهات الوسائط، والردود الصامتة، وسجل الإشارات في المجموعات.
thread.post() ليست كافية لـ OpenClaw. فهي تخفي حد المعاملة
الذي يقرر ما إذا كان الإرسال قابلًا للاسترداد.
النموذج المركزي
يجب أن يعيش النطاق الجديد تحت مساحة أسماء مركزية داخلية مثلsrc/channels/message/*.
لديه أربعة مفاهيم:
receive دورة حياة الوارد.
يمتلك send دورة حياة الصادر.
يمتلك live حالة المعاينة، والتعديل، والتقدم، والبث.
تمتلك state تخزين النية الدائم، والإيصالات، والتماثل، والاسترداد، والأقفال،
وإزالة التكرار.
مصطلحات الرسائل
الرسالة
الرسالة المطبعة حيادية المنصة:الهدف
يصف الهدف المكان الذي تعيش فيه الرسالة:العلاقة
الرد علاقة، وليس جذر API:المنشأ
يصف المنشأ من أنتج رسالة وكيف يجب أن يتعامل OpenClaw مع أصداء تلك الرسالة. وهو منفصل عن العلاقة: يمكن أن تكون الرسالة ردًا على مستخدم وتظل مخرجًا تشغيليًا منشؤه OpenClaw.allowBots مفعلًا.
الإيصال
الإيصالات كائنات من الدرجة الأولى:سياق الاستقبال
ينبغي ألا يكون الاستقبال استدعاء مساعد مجردًا. يحتاج المركز إلى سياق يعرف إزالة التكرار، والتوجيه، وتسجيل الجلسة، وسياسة إقرار المنصة.- إقرار النقل: يخبر Webhook أو المقبس الخاص بالمنصة أن OpenClaw قبل غلاف الحدث. تتطلب بعض المنصات ذلك قبل الإرسال للمعالجة.
- إقرار إزاحة الاستطلاع: يقدّم مؤشرًا بحيث لا يُجلب الحدث نفسه مرة أخرى. يجب ألا يتقدم هذا بعد عمل لا يمكن استرداده.
- إقرار سجل الوارد: يؤكد أن OpenClaw ثبّت ما يكفي من بيانات تعريف الوارد لإزالة التكرار وتوجيه إعادة تسليم.
- إيصال مرئي للمستخدم: سلوك اختياري للقراءة/الحالة/الكتابة؛ لا يكون أبدًا حدًا للديمومة.
ReceiveAckPolicy في إقرار النقل أو الاستطلاع فقط. يجب
ألا يُعاد استخدامه لإيصالات القراءة أو تفاعلات الحالة.
قبل تخويل البوت، يجب أن يطبق الاستقبال سياسة صدى OpenClaw المشتركة
عندما تستطيع القناة فك ترميز بيانات تعريف منشأ الرسالة:
allowBots العادي.
سياسة الإقرار صريحة:
getUpdates upstream في Telegram
تُدار بواسطة مكتبة الاستطلاع، لذا فإن القطع الأعمق المتبقي هو مصدر استطلاع
دائم بالكامل إذا احتجنا إلى إعادة تسليم على مستوى المنصة بما يتجاوز علامة
إعادة التشغيل المائية الخاصة بـ OpenClaw. قد تحتاج منصات Webhook إلى إقرار
HTTP فوري، لكنها لا تزال تحتاج إلى إزالة تكرار الوارد ونوايا إرسال صادرة دائمة
لأن Webhooks يمكن أن تعيد التسليم.
سياق الإرسال
الإرسال يعتمد أيضًا على السياق:unknown_after_send، لا أن تُعاد عشوائيًا. قد تختار القنوات
التي لا تتضمن مطابقة إعادة إرسال بنمط مرة واحدة على الأقل فقط إذا كانت الرسائل المرئية المكررة
مقايضة مقبولة وموثقة لتلك القناة والعلاقة.
يتطلب جسر مطابقة SDK الحالي أن يصرح المهايئ بـ
reconcileUnknownSend، ثم يطلب من durableFinal.reconcileUnknownSend
تصنيف إدخال مجهول على أنه sent أو not_sent أو unresolved؛ ولا يسمح إلا not_sent
بإعادة الإرسال، وتبقى الإدخالات غير المحلولة نهائية أو تعيد فقط محاولة
فحص المطابقة.
يجب أن تكون سياسة الاستدامة صريحة:
required أن النواة يجب أن تفشل بإغلاق عندما لا تستطيع كتابة القصد المستدام.
يمكن لـ best_effort المتابعة عندما يكون الحفظ غير متاح. يحافظ disabled على
سلوك الإرسال المباشر القديم. أثناء الترحيل، تكون الأغلفة القديمة ومساعدات
التوافق العامة افتراضيًا على disabled؛ ويجب ألا تستنتج required من
مجرد أن قناة لديها مهايئ صادر عام.
تمتلك سياقات الإرسال أيضًا الآثار المحلية للقناة بعد الإرسال. لا يكون الترحيل آمنًا
إذا تجاوز التسليم المستدام سلوكًا محليًا كان مرتبطًا سابقًا
بمسار الإرسال المباشر للقناة. تشمل الأمثلة مخازن منع صدى الذات المؤقتة،
وعلامات المشاركة في السلاسل، ومرتكزات التحرير الأصلية، وعرض توقيع النموذج،
وحواجز منع التكرار الخاصة بالمنصة. يجب نقل تلك الآثار إما إلى
مهايئ الإرسال، أو مهايئ العرض، أو خطاف سياق إرسال مسمى قبل أن تتمكن تلك
القناة من تفعيل التسليم النهائي العام المستدام.
يجب أن تعيد مساعدات الإرسال الإيصالات طوال الطريق إلى مستدعيها. لا يمكن
للأغلفة المستدامة ابتلاع معرّفات الرسائل أو استبدال نتيجة تسليم قناة بـ
undefined؛ إذ تستخدم المرسلات المخزنة مؤقتًا تلك المعرّفات لمرتكزات السلاسل، والتحريرات اللاحقة،
وإنهاء المعاينات، ومنع التكرار.
تعمل الإرسالات الاحتياطية على دفعات، لا على حمولات مفردة. يمكن لإعادة كتابة الردود الصامتة،
والاحتياط للوسائط، والاحتياط للبطاقات، وإسقاط التقسيم أن تنتج جميعًا أكثر من
رسالة واحدة قابلة للتسليم، لذا يجب على سياق الإرسال إما تسليم الدفعة
المسقطة كاملة أو توثيق سبب صلاحية حمولة واحدة فقط بشكل صريح.
unknown_after_send حتى يطابقها المهايئ.
السياق الحي
يجب أن تكون سلوكيات المعاينة، والتحرير، والتقدم، والبث دورة حياة اختيارية واحدة.- إرسال Telegram مع تحرير المعاينة، وإرسال نهائي جديد بعد تقادم عمر المعاينة.
- إرسال Discord مع تحرير المعاينة، والإلغاء عند الوسائط/الخطأ/الرد الصريح.
- بث Slack الأصلي أو معاينة مسودة حسب شكل السلسلة.
- إنهاء منشور مسودة Mattermost.
- إنهاء حدث مسودة Matrix أو تنقيحه عند عدم التطابق.
- بث تقدم Teams الأصلي.
- بث QQ Bot أو احتياط متراكم.
سطح المهايئ
يجب أن يكون هدف SDK العام مسارًا فرعيًا واحدًا:origin.decode بيانات وصفية ذات منشأ OpenClaw. يوفر مهايئ الاستقبال
حقائق المنصة مثل مؤلف البوت وشكل الغرفة؛ وتمتلك النواة قرار الإسقاط
والترتيب حتى لا تعيد القنوات تنفيذ مرشحات النص.
مهايئ المنشأ:
MessageOrigin. لا تفعل القنوات سوى ترجمته من وإلى
البيانات الوصفية الأصلية للنقل. يطابق Slack هذا إلى chat.postMessage({ metadata }) و
message.metadata الواردة؛ ويمكن لـ Matrix مطابقته إلى محتوى حدث إضافي؛ أما القنوات
التي لا تملك بيانات وصفية أصلية فيمكنها استخدام سجل إيصالات/صادر عندما يكون ذلك
أفضل تقريب متاح.
القدرات:
تقليل SDK العام
يجب أن يستوعب السطح العام الجديد هذه المجالات المفاهيمية أو يوقفها تدريجيًا:reply-runtimereply-dispatch-runtimereply-referencereply-chunkingreply-payloadinbound-reply-dispatchchannel-reply-pipeline- معظم الاستخدامات العامة لـ
outbound-runtime - مساعدات دورة حياة بث المسودات المخصصة
plugin-sdk/channel-outbound بمجرد وجوده.
العلاقة مع الوارد للقنوات
runtime.channel.inbound.* هو جسر وقت التشغيل أثناء الترحيل.
يجب أن يصبح مهايئ توافق:
channel.inbound.runPreparedReply أيضًا مبدئيًا:
channel.turn. يستخدم مستدعو وقت التشغيل
channel.inbound.*؛ وتستخدم وثائق القنوات ومسارات SDK الفرعية أسماء الوارد/الرسائل.
ضوابط التوافق
أثناء الترحيل، يكون التسليم العام المستدام اختياريًا لأي قناة يكون استدعاء التسليم الحالي لديها ذا آثار جانبية تتجاوز “أرسل هذه الحمولة”. نقاط الدخول القديمة غير مستدامة افتراضيًا:- يستخدم
channel.inbound.runوdispatchChannelInboundReplyاستدعاء التسليم الخاص بالقناة إلا إذا قدمت تلك القناة صراحة كائن سياسة/خيارات مستدامة ومدققة. - يبقى
channel.inbound.runPreparedReplyمملوكًا للقناة حتى يستدعي المرسل المحضر سياق الإرسال صراحة. - لا تحقن مساعدات التوافق العامة مثل
recordInboundSessionAndDispatchReply، وdispatchInboundReplyWithBase، ومساعدات الرسائل المباشرة أبدًا تسليمًا عامًا مستدامًا قبل استدعاءdeliverأوreplyالمقدم من المستدعي.
durable: undefined “غير مستدام”. لا يتم
تفعيل المسار المستدام إلا بقيمة سياسة/خيارات صريحة. يمكن أن تبقى durable: false كصياغة توافق، لكن يجب ألا يتطلب التنفيذ
من كل قناة غير مرَحّلة إضافتها.
يجب أن تبقي شيفرة الجسر الحالية قرار الاستدامة صريحًا:
- يعيد التسليم النهائي المتين حالة مميِّزة. يُعدّ
handled_visibleوhandled_no_sendحالتين نهائيتين؛ وقد يعودunsupportedوnot_applicableإلى التسليم المملوك للقناة؛ وينشرfailedفشل الإرسال. - يخضع التسليم النهائي المتين العام لإمكانات المحوّل، مثل التسليم الصامت، والحفاظ على هدف الرد، والحفاظ على الاقتباس الأصلي، وخطافات إرسال الرسائل. عند غياب التكافؤ، يجب اختيار التسليم المملوك للقناة، لا إرسال عام يغيّر السلوك المرئي للمستخدم.
- تعرض الإرسالات المتينة المدعومة بالطابور مرجع نية تسليم. يمكن لحقول الجلسة
الحالية
pendingFinalDelivery*حمل معرّف النية أثناء الانتقال؛ وتكون الحالة النهائية مخزنMessageSendIntentبدلا من نص رد مجمّد مع حقول سياق مرتجلة.
- ينفّذ محوّل الإرسال العام سلوك العرض والنقل نفسه الذي كان ينفذه المسار المباشر القديم.
- تُحفَظ الآثار الجانبية المحلية بعد الإرسال عبر سياق الإرسال.
- يعيد المحوّل إيصالات أو نتائج تسليم تتضمن كل معرّفات رسائل المنصة.
- إما أن تستدعي مسارات الموزّع المجهّزة سياق الإرسال الجديد، أو تبقى موثقة على أنها خارج ضمان المتانة.
- يعالج تسليم الرجوع كل حمولة متوقعة، وليس الحمولة الأولى فقط.
- يسجّل تسليم الرجوع المتين مصفوفة الحمولات المتوقعة كاملة كنية واحدة قابلة لإعادة التشغيل أو خطة دفعة.
- يسجّل تسليم مراقب iMessage الرسائل المرسلة في ذاكرة صدى مؤقتة بعد إرسال ناجح. يجب أن تستمر الإرسالات النهائية المتينة في تعبئة تلك الذاكرة المؤقتة، وإلا فقد يعيد OpenClaw ابتلاع ردوده النهائية نفسها كرسائل مستخدم واردة.
- يضيف Tlon توقيع نموذج اختياري ويسجّل السلاسل التي تمت المشاركة فيها بعد ردود المجموعات. يجب ألا يتجاوز التسليم المتين العام هذه الآثار؛ إما انقلها إلى محوّلات العرض/الإرسال/الإنهاء الخاصة بـ Tlon أو أبقِ Tlon على المسار المملوك للقناة.
- يملك Discord والموزّعون المجهّزون الآخرون بالفعل سلوك التسليم المباشر والمعاينة. ولا يشملهم ضمان المتانة للدورة المجمّعة حتى توجّه موزّعاتهم المجهّزة النهايات صراحة عبر سياق الإرسال.
- يجب أن يسلّم تسليم الرجوع الصامت في Telegram مصفوفة الحمولات المتوقعة كاملة. يمكن لاختصار حمولة واحدة أن يسقط حمولات رجوع إضافية بعد الإسقاط.
- قد تملك LINE وZalo وNostr وغيرها من المسارات المجمّعة/المساعدة الحالية معالجة رموز الرد، أو تمرير الوسائط عبر وكيل، أو ذاكرات تخزين مؤقت للرسائل المرسلة، أو تنظيف التحميل/الحالة، أو أهدافا مخصصة للاستدعاء فقط. تبقى هذه على التسليم المملوك للقناة حتى تمثَّل هذه الدلالات في محوّل الإرسال وتتحقق منها الاختبارات.
- يمكن أن تحتوي مساعدات الرسائل المباشرة على استدعاء رد يكون هو هدف النقل
الصحيح الوحيد. يجب ألا يخمّن الإرسال العام الصادر من
OriginatingToأوToويتجاوز ذلك الاستدعاء. - يجب أن يبقى خرج فشل OpenClaw gateway مرئيا للبشر، لكن يجب إسقاط أصداء الغرف
الموسومة والمؤلفة بواسطة بوت قبل تفويض
allowBots. يجب ألا تنفذ القنوات هذا بمرشحات بادئة نصية مرئية إلا كإجراء إيقاف طارئ قصير؛ عقد المتانة هو بيانات وصفية منظمة للأصل.
التخزين الداخلي
يجب أن يخزّن الطابور المتين نوايا إرسال الرسائل، لا حمولات الرد.فئات الفشل
تصنّف محوّلات القنوات إخفاقات النقل ضمن فئات مغلقة:- أعد محاولة
transientوrate_limit. - لا تعد محاولة
invalid_payloadإلا إذا كان هناك رجوع عرض. - لا تعد محاولة
authأوpermissionحتى يتغير الإعداد. - بالنسبة إلى
not_found، اسمح للإنهاء الحي بالرجوع من التحرير إلى إرسال جديد عندما تعلن القناة أن ذلك آمن. - بالنسبة إلى
conflict، استخدم قواعد الإيصال/الإديمبوتنسية لتحديد ما إذا كانت الرسالة موجودة بالفعل. - أي خطأ بعد أن يكون المحوّل قد أكمل ربما إدخال/إخراج المنصة ولكن قبل تثبيت الإيصال
يصبح
unknown_after_sendما لم يستطع المحوّل إثبات أن عملية المنصة لم تحدث.
تعيين القنوات
| القناة | الترحيل المستهدف |
|---|---|
| Telegram | تلقي سياسة الإقرار بالإضافة إلى عمليات إرسال نهائية متينة. يملك المحوّل المباشر الإرسال بالإضافة إلى تعديل المعاينة، والإرسال النهائي للمعاينة القديمة، والموضوعات، وتخطي معاينة الرد بالاقتباس، والرجوع الاحتياطي للوسائط، ومعالجة retry-after. |
| Discord | يغلّف محوّل الإرسال تسليم الحمولة المتينة الحالية. يملك المحوّل المباشر تعديل المسودة، ومسودة التقدم، وإلغاء معاينة الوسائط/الأخطاء، والحفاظ على هدف الرد، وإيصالات معرّفات الرسائل. راجع أصداء إخفاق Gateway المؤلفة من البوت في الغرف المشتركة؛ استخدم سجلًا صادرًا أو مكافئًا أصليًا آخر إذا كان Discord لا يستطيع حمل بيانات المنشأ الوصفية على الرسائل العادية. |
| Slack | يتعامل محوّل الإرسال مع منشورات الدردشة العادية. يختار المحوّل المباشر البث الأصلي عندما يدعم شكل السلسلة ذلك، وإلا يستخدم معاينة المسودة. تحفظ الإيصالات طوابع وقت السلاسل. يربط محوّل المنشأ إخفاقات Gateway في OpenClaw إلى Slack chat.postMessage.metadata ويسقط أصداء غرف البوتات الموسومة قبل تفويض allowBots. |
| يملك محوّل الإرسال إرسال النص/الوسائط مع نوايا نهائية متينة. يتعامل محوّل التلقي مع الإشارة إلى المجموعة وهوية المرسل. يمكن أن يبقى المحوّل المباشر غائبًا إلى أن يمتلك WhatsApp نقلًا قابلًا للتحرير. | |
| Matrix | يملك المحوّل المباشر تعديلات أحداث المسودة، والإنهاء، والتنقيح، وقيود الوسائط المشفرة، والرجوع الاحتياطي عند عدم تطابق هدف الرد. يملك محوّل التلقي إماهة الأحداث المشفرة وإزالة التكرار. ينبغي أن يرمّز محوّل المنشأ منشأ إخفاق Gateway في OpenClaw ضمن محتوى حدث Matrix ويسقط أصداء غرف البوتات المكوّنة قبل معالجة allowBots. |
| Mattermost | يملك المحوّل المباشر منشور مسودة واحدًا، وطي التقدم/الأدوات، والإنهاء في الموضع، والرجوع الاحتياطي إلى إرسال جديد. |
| Microsoft Teams | يملك المحوّل المباشر التقدم الأصلي وسلوك بث الكتل. يملك محوّل الإرسال الأنشطة وإيصالات المرفقات/البطاقات. |
| Feishu | يملك محوّل العرض تصيير النص/البطاقة/الخام. يملك المحوّل المباشر بطاقات البث وكبت النهائي المكرر. يملك محوّل الإرسال التعليقات، وجلسات الموضوعات، والوسائط، وكبت الصوت. |
| QQ Bot | يملك المحوّل المباشر بث C2C، ومهلة المجمّع، والإرسال النهائي الاحتياطي. يملك محوّل العرض وسوم الوسائط وتحويل النص إلى صوت. |
| Signal | تلقي بسيط بالإضافة إلى محوّل إرسال. لا محوّل مباشر إلا إذا أضاف signal-cli دعم تحرير موثوقًا. |
| iMessage | تلقي بسيط بالإضافة إلى محوّل إرسال. يجب أن يحافظ إرسال iMessage على تعبئة ذاكرة صدى المراقب المؤقتة قبل أن تتمكن النهائيات المتينة من تجاوز تسليم المراقب. |
| Google Chat | تلقي بسيط بالإضافة إلى محوّل إرسال مع ربط علاقة السلسلة بالمساحات ومعرّفات السلاسل. راجع سلوك غرفة allowBots=true لأصداء إخفاق Gateway في OpenClaw الموسومة. |
| LINE | تلقي بسيط بالإضافة إلى محوّل إرسال مع نمذجة قيود رمز الرد كإمكان هدف/علاقة. |
| Nextcloud Talk | جسر تلقي SDK بالإضافة إلى محوّل إرسال. |
| IRC | تلقي بسيط بالإضافة إلى محوّل إرسال، من دون إيصالات تحرير متينة. |
| Nostr | تلقي بالإضافة إلى محوّل إرسال للرسائل المباشرة المشفرة؛ الإيصالات هي معرّفات الأحداث. |
| QA Channel | محوّل اختبار عقد لسلوك التلقي، والإرسال، والبث المباشر، وإعادة المحاولة، والاسترداد. |
| Synology Chat | تلقي بسيط بالإضافة إلى محوّل إرسال. |
| Tlon | يجب أن يحافظ محوّل الإرسال على تصيير توقيع النموذج وتتبع السلاسل المشاركة قبل تمكين التسليم النهائي المتين العام. |
| Twitch | تلقي بسيط بالإضافة إلى محوّل إرسال مع تصنيف حدود المعدل. |
| Zalo | تلقي بسيط بالإضافة إلى محوّل إرسال. |
| Zalo Personal | تلقي بسيط بالإضافة إلى محوّل إرسال. |
خطة الترحيل
المرحلة 1: نطاق الرسائل الداخلي
- أضف أنواع
src/channels/message/*للرسائل، والأهداف، والعلاقات، والمناشئ، والإيصالات، والإمكانات، والنوايا المتينة، وسياق التلقي، وسياق الإرسال، والسياق المباشر، وفئات الإخفاق. - أضف
origin?: MessageOriginإلى نوع حمولة جسر الترحيل الذي يستخدمه تسليم الرد الحالي، ثم انقل ذلك الحقل إلىChannelMessageوأنواع الرسائل المصيّرة بينما تستبدل إعادة الهيكلة حمولات الرد. - أبقِ هذا داخليًا حتى تثبت المحوّلات والاختبارات الشكل.
- أضف اختبارات وحدة صرفة لانتقالات الحالة والتسلسل.
المرحلة 2: نواة الإرسال المتين
- انقل قائمة الانتظار الصادرة الحالية من متانة حمولة الرد إلى نوايا إرسال الرسائل المتينة.
- اسمح لنوايا الإرسال المتين بحمل مصفوفة حمولات مسقطة أو خطة دفعة، وليس حمولة رد واحدة فقط.
- حافظ على سلوك استرداد قائمة الانتظار الحالي عبر تحويل التوافق.
- اجعل
deliverOutboundPayloadsتستدعيmessages.send. - اجعل متانة الإرسال النهائي هي الافتراضية وافشل بصورة مغلقة عندما لا يمكن كتابة النية المتينة في دورة حياة الرسائل الجديدة، بعد أن يعلن المحوّل أمان إعادة التشغيل. تظل مسارات مشغّل الوارد الحالي وتوافق SDK إرسالًا مباشرًا افتراضيًا خلال هذه المرحلة.
- سجّل الإيصالات باتساق.
- أعد الإيصالات ونتائج التسليم إلى مستدعي المرسل الأصلي بدلًا من التعامل مع الإرسال المتين كأثر جانبي طرفي.
- استمر في حفظ منشأ الرسالة عبر نوايا الإرسال المتين حتى يحافظ الاسترداد، وإعادة التشغيل، وعمليات الإرسال المجزأة على المصدر التشغيلي لـ OpenClaw.
المرحلة 3: جسر وارد القناة
- أعد تنفيذ
channel.inbound.runوdispatchChannelInboundReplyفوقmessages.receiveوmessages.send. - أبقِ أنواع الحقائق الحالية مستقرة.
- حافظ على السلوك القديم افتراضيًا. لا تصبح قناة الدور المجمّع متينة إلا عندما يختار محوّلها ذلك صراحةً بسياسة متانة آمنة لإعادة التشغيل.
- أبقِ
durable: falseكمخرج توافق للمسارات التي تنهي التحريرات الأصلية ولا يمكنها إعادة التشغيل بأمان بعد، لكن لا تعتمد على علاماتfalseلحماية القنوات غير المرحّلة. - فعّل متانة الدور المجمّع افتراضيًا فقط في دورة حياة الرسائل الجديدة، بعد أن يثبت ربط القناة أن مسار الإرسال العام يحافظ على دلالات تسليم القناة القديمة.
المرحلة 4: جسر المرسل المحضّر
- استبدل
deliverDurableInboundReplyPayloadبجسر سياق إرسال. - أبقِ المساعد القديم كغلاف.
- انقل Telegram وWhatsApp وSlack وSignal وiMessage وDiscord أولاً لأن لديها بالفعل عمل نهائي دائم أو مسارات إرسال أبسط.
- تعامل مع كل موزّع مُحضَّر على أنه غير مغطى حتى يختار صراحةً استخدام سياق الإرسال. يجب أن تقول الوثائق ومدخلات سجل التغييرات “دورات القناة المُجمَّعة” أو أن تسمّي مسارات القنوات المُرحَّلة بدلاً من الادعاء بكل الردود النهائية التلقائية.
- أبقِ سلوك
recordInboundSessionAndDispatchReplyومساعدات الرسائل المباشرة ومساعدات التوافق العامة المشابهة محافظاً على السلوك. يمكنها أن تعرض لاحقاً اختياراً صريحاً لاستخدام سياق الإرسال، لكنها يجب ألا تحاول تلقائياً تنفيذ تسليم دائم عام قبل رد نداء التسليم المملوك للمتصل.
المرحلة 5: دورة حياة مباشرة موحّدة
- ابنِ
messages.liveمع محوّلي إثبات:- Telegram للإرسال والتحرير والإرسال النهائي المتقادم.
- Matrix لإنهاء المسودة مع بديل الحذف.
- ثم رحّل Discord وSlack وMattermost وTeams وQQ Bot وFeishu.
- احذف كود إنهاء المعاينة المكرر فقط بعد أن تحصل كل قناة على اختبارات تكافؤ.
المرحلة 6: SDK العام
- أضف
openclaw/plugin-sdk/channel-outbound. - وثّقه بصفته API Plugin القناة المفضّل.
- حدّث صادرات الحزمة، وجرد نقاط الدخول، وخطوط أساس API المولّدة، ووثائق SDK الخاصة بالـPlugin.
- ضمّن
MessageOrigin، وخطافات ترميز/فك ترميز الأصل، والمسند المشتركshouldDropOpenClawEchoفي سطح SDK الخاص بـchannel-outbound. - أبقِ أغلفة التوافق للمسارات الفرعية القديمة.
- علّم مساعدات SDK المسماة بالرد بأنها مهملة في الوثائق بعد ترحيل الـplugins المضمّنة.
المرحلة 7: كل المرسلين
انقل كل منتجي الخرج غير الردّي إلىmessages.send:
- إشعارات Cron وHeartbeat
- إكمالات المهام
- نتائج الخطافات
- مطالبات الموافقة ونتائج الموافقة
- عمليات إرسال أداة الرسائل
- إعلانات إكمال الوكلاء الفرعيين
- عمليات إرسال CLI أو Control UI الصريحة
- مسارات الأتمتة/البث
المرحلة 8: إزالة التوافق المسمّى بالدورة
- أبقِ الأغلفة المسماة بالوارد/الرسائل كنافذة توافق.
- انشر ملاحظات الترحيل.
- شغّل اختبارات توافق SDK الخاص بالـPlugin ضد الاستيرادات القديمة.
- أزل أو أخفِ المساعدات الداخلية القديمة فقط بعد ألا يحتاج إليها أي Plugin مضمّن وأن تكون لعقود الجهات الخارجية بدائل مستقرة.
خطة الاختبار
اختبارات الوحدات:- تسلسل واسترداد نية الإرسال الدائم.
- إعادة استخدام مفتاح التماثل وكبح التكرارات.
- تثبيت الإيصال وتجاوز إعادة التشغيل.
- استرداد
unknown_after_sendالذي يوفّق قبل إعادة التشغيل عندما يدعم المحوّل التوفيق. - سياسة تصنيف الإخفاقات.
- تسلسل سياسة إقرار الاستلام.
- تخطيط العلاقات لإرسالات الرد والمتابعة والنظام والبث.
- مصنع أصل إخفاق Gateway ومسند
shouldDropOpenClawEcho. - الحفاظ على الأصل عبر تطبيع الحمولة، والتقطيع، وتسلسل قائمة الانتظار الدائمة، والاسترداد.
- ما يزال محوّل
channel.inbound.runالبسيط يسجل ويرسل. - لا يصبح تسليم الحدث المُجمَّع القديم دائماً إلا إذا اختارت القناة ذلك صراحةً.
- ما يزال جسر
channel.inbound.runPreparedReplyيسجل وينهي. - تستدعي مساعدات التوافق العامة ردود نداء التسليم المملوكة للمتصل افتراضياً ولا تنفّذ إرسالاً عاماً قبل تلك الردود.
- يعيد تسليم البديل الدائم تشغيل مصفوفة الحمولات المسقطة كلها بعد إعادة التشغيل، ولا يمكنه ترك الحمولات اللاحقة غير مسجلة بعد تعطل مبكر.
- يعيد تسليم الحدث المُجمَّع الدائم معرّفات رسائل المنصة إلى الموزّع المخزّن مؤقتاً.
- ما تزال خطافات التسليم المخصصة تعيد معرّفات رسائل المنصة عندما يكون التسليم الدائم معطلاً أو غير متاح.
- ينجو الرد النهائي من إعادة التشغيل بين اكتمال المساعد وإرسال المنصة.
- تُنهى مسودة المعاينة في مكانها عندما يكون ذلك مسموحاً.
- تُلغى مسودة المعاينة أو تُحذف عندما يتطلب عدم تطابق الوسائط/الخطأ/هدف الرد تسليماً عادياً.
- لا يسلّم بث الكتل وبث المعاينة النص نفسه معاً.
- لا تُكرر الوسائط التي بُثت مبكراً في التسليم النهائي.
- رد موضوع Telegram مع تأخير إقرار الاستلام عبر الاقتراع حتى علامة الماء المكتملة الآمنة الخاصة بسياق الاستلام.
- استرداد اقتراع Telegram للتحديثات المقبولة لكن غير المسلّمة مغطى بنموذج الإزاحة الآمنة المكتملة المحفوظ.
- ترسل معاينة Telegram المتقادمة نتيجة نهائية جديدة وتنظف المعاينة.
- يرسل بديل Telegram الصامت كل حمولة بديلة مسقطة.
- تسجل ديمومة بديل Telegram الصامت مصفوفة البدائل المسقطة الكاملة ذرياً، وليس نية دائمة ذات حمولة واحدة لكل تكرار في الحلقة.
- إلغاء معاينة Discord عند وجود وسائط/خطأ/رد صريح.
- تمر نهائيات موزّع Discord المُحضَّر عبر سياق الإرسال قبل أن تزعم الوثائق أو سجل التغييرات ديمومة الرد النهائي في Discord.
- تملأ الإرسالات النهائية الدائمة في iMessage ذاكرة التخزين المؤقتة لصدى الرسالة المرسلة في المراقب.
- لا تتجاوز مسارات التسليم القديمة في LINE وZalo وNostr بالإرسال الدائم العام حتى توجد اختبارات تكافؤ لمحوّلاتها.
- يبقى تسليم رد النداء الخاص بالرسائل المباشرة/Nostr هو المرجع ما لم يُرحَّل صراحةً إلى هدف رسالة كامل ومحوّل إرسال آمن لإعادة التشغيل.
- تبقى رسائل إخفاق Gateway الموسومة من Slack وOpenClaw مرئية في الخرج،
وتسقط أصداء غرف البوتات الموسومة قبل
allowBots، وتظل رسائل البوتات غير الموسومة ذات النص المرئي نفسه تتبع تفويض البوت العادي. - بديل البث الأصلي في Slack إلى معاينة مسودة في الرسائل المباشرة ذات المستوى الأعلى.
- إنهاء معاينة Matrix وبديل الحذف.
- تسقط أصداء غرف إخفاق Gateway الموسومة من Matrix وOpenClaw من حسابات البوتات
المضبوطة قبل معالجة
allowBots. - تغطي تدقيقات سلسلة إخفاق Gateway في الغرف المشتركة بين Discord وGoogle Chat
أوضاع
allowBotsقبل ادعاء الحماية العامة هناك. - إنهاء مسودة Mattermost وبديل الإرسال الجديد.
- إنهاء تقدم Teams الأصلي.
- كبح النهائي المكرر في Feishu.
- بديل مهلة مُجمِّع QQ Bot.
- تحافظ الإرسالات النهائية الدائمة في Tlon على عرض توقيع النموذج وتتبع السلاسل التي تمت المشاركة فيها.
- إرسالات نهائية دائمة بسيطة في WhatsApp وSignal وiMessage وGoogle Chat وLINE وIRC وNostr وNextcloud Talk وSynology Chat وTlon وTwitch وZalo وZalo Personal.
- ملفات Vitest مستهدفة أثناء التطوير.
pnpm check:changedفي Testbox لكامل السطح المتغير.pnpm checkأوسع في Testbox قبل إنزال إعادة الهيكلة الكاملة أو بعد تغييرات SDK/التصدير العامة.- تجربة دخان مباشرة أو qa-channel لقناة واحدة على الأقل قادرة على التحرير وقناة واحدة بسيطة مخصصة للإرسال فقط قبل إزالة أغلفة التوافق.
أسئلة مفتوحة
- ما إذا كان ينبغي لـTelegram في النهاية استبدال مصدر مشغّل grammY بمصدر اقتراع دائم بالكامل يمكنه التحكم في إعادة التسليم على مستوى المنصة، وليس فقط علامة ماء إعادة التشغيل المحفوظة في OpenClaw.
- ما إذا كان يجب تخزين حالة المعاينة المباشرة الدائمة في سجل قائمة الانتظار نفسه مثل نية الإرسال النهائي أم في مخزن حالة مباشرة شقيق.
- مدة بقاء أغلفة التوافق موثقة بعد شحن
plugin-sdk/channel-outbound. - ما إذا كان ينبغي للـplugins التابعة لجهات خارجية تنفيذ محوّلات الاستلام
مباشرة أم تقديم خطافات التطبيع/الإرسال/المباشر فقط عبر
defineChannelMessageAdapter. - أي حقول الإيصالات آمنة للعرض في SDK العام مقارنة بحالة وقت التشغيل الداخلية.
- ما إذا كان يجب نمذجة الآثار الجانبية مثل ذاكرات صدى الذات المؤقتة وعلامات السلاسل التي تمت المشاركة فيها كخطافات سياق إرسال، أو خطوات إنهاء مملوكة للمحوّل، أو مشتركين في الإيصالات.
- أي القنوات لديها بيانات تعريف أصل أصلية، وأيها تحتاج سجلات خرج محفوظة، وأيها لا يمكنه تقديم كبح موثوق للصدى بين البوتات.
معايير القبول
- ترسل كل قناة رسائل مضمّنة الخرج النهائي المرئي عبر
messages.send. - تدخل كل قناة رسائل واردة عبر
messages.receiveأو غلاف توافق موثق. - تستخدم كل قناة معاينة/تحرير/بث
messages.liveلحالة المسودة والإنهاء. channel.inboundليس إلا غلافاً.- مساعدات SDK المسماة بالرد هي صادرات توافق، وليست المسار الموصى به.
- يستطيع الاسترداد الدائم إعادة تشغيل الإرسالات النهائية المعلقة بعد إعادة التشغيل دون فقدان الرد النهائي أو تكرار الإرسالات المثبتة مسبقاً؛ وتُوفَّق الإرسالات التي تكون نتيجتها على المنصة غير معروفة قبل إعادة التشغيل أو توثَّق على أنها مرة واحدة على الأقل لذلك المحوّل.
- تفشل الإرسالات النهائية الدائمة بشكل مغلق عندما لا يمكن كتابة النية الدائمة، ما لم يختر المتصل صراحةً وضعاً غير دائم موثقاً.
- تعود مساعدات توافق SDK القديمة افتراضياً إلى التسليم المباشر المملوك للقناة؛ ولا يكون الإرسال الدائم العام إلا اختياراً صريحاً.
- تحفظ الإيصالات كل معرّفات رسائل المنصة للتسليمات متعددة الأجزاء ومعرّفاً أساسياً لتسهيل السلاسل/التحرير.
- تحافظ الأغلفة الدائمة على الآثار الجانبية المحلية للقناة قبل استبدال ردود نداء التسليم المباشرة.
- لا تُحسب الموزّعات المُحضَّرة كدائمة حتى يستخدم مسار التسليم النهائي الخاص بها سياق الإرسال صراحةً.
- يتعامل تسليم البديل مع كل حمولة مسقطة.
- يسجل تسليم البديل الدائم كل حمولة مسقطة في نية واحدة قابلة لإعادة التشغيل أو خطة دفعات.
- يكون خرج إخفاق Gateway الصادر من OpenClaw مرئياً للبشر، لكن أصداء الغرف الموسومة والمكتوبة بواسطة البوتات تسقط قبل تفويض البوت على القنوات التي تعلن دعم عقد الأصل.
- تشرح الوثائق الإرسال، والاستلام، والمباشر، والحالة، والإيصالات، والعلاقات، وسياسة الإخفاق، والترحيل، وتغطية الاختبار.