Plugins
عرض الرسائل
عرض الرسائل هو العقد المشترك في OpenClaw لواجهة الدردشة الصادرة الغنية. يتيح للوكلاء، وأوامر CLI، وتدفقات الموافقة، وPlugins وصف مقصد الرسالة مرة واحدة، بينما يعرض كل Plugin قناة أفضل شكل أصلي ممكن لديه.
استخدم العرض لواجهة رسائل قابلة للنقل:
- أقسام نصية
- نص سياق/تذييل صغير
- فواصل
- أزرار
- قوائم اختيار
- عنوان البطاقة ونبرتها
لا تضف حقولًا أصلية خاصة بالمزوّد مثل Discord components، أو Slack
blocks، أو Telegram buttons، أو Teams card، أو Feishu card إلى أداة
الرسائل المشتركة. هذه مخرجات عرض يملكها Plugin القناة.
العقد
يستورد مؤلفو Plugin العقد العام من:
MessagePresentation,
ReplyPayloadDelivery,
} from "openclaw/plugin-sdk/interactive-runtime";
الشكل:
type MessagePresentation = {
title?: string;
tone?: "neutral" | "info" | "success" | "warning" | "danger";
blocks: MessagePresentationBlock[];
};
type MessagePresentationBlock =
| { type: "text"; text: string }
| { type: "context"; text: string }
| { type: "divider" }
| { type: "buttons"; buttons: MessagePresentationButton[] }
| { type: "select"; placeholder?: string; options: MessagePresentationOption[] };
type MessagePresentationButton = {
label: string;
value?: string;
url?: string;
style?: "primary" | "secondary" | "success" | "danger";
};
type MessagePresentationOption = {
label: string;
value: string;
};
type ReplyPayloadDelivery = {
pin?:
| boolean
| {
enabled: boolean;
notify?: boolean;
required?: boolean;
};
};
دلالات الأزرار:
valueهي قيمة إجراء تطبيق تُوجّه مرة أخرى عبر مسار التفاعل الحالي في القناة عندما تدعم القناة عناصر تحكم قابلة للنقر.urlهو زر رابط. يمكن أن يوجد من دونvalue.labelمطلوب ويُستخدم أيضًا في النص الاحتياطي.styleإرشادي. ينبغي أن يربط العارضون الأنماط غير المدعومة بقيمة افتراضية آمنة، لا أن يفشلوا الإرسال.
دلالات الاختيار:
options[].valueهي قيمة التطبيق المحددة.placeholderإرشادي وقد تتجاهله القنوات التي لا تدعم الاختيار أصليًا.- إذا كانت القناة لا تدعم الاختيارات، يسرد النص الاحتياطي التسميات.
أمثلة المنتجين
بطاقة بسيطة:
{
"title": "Deploy approval",
"tone": "warning",
"blocks": [
{ "type": "text", "text": "Canary is ready to promote." },
{ "type": "context", "text": "Build 1234, staging passed." },
{
"type": "buttons",
"buttons": [
{ "label": "Approve", "value": "deploy:approve", "style": "success" },
{ "label": "Decline", "value": "deploy:decline", "style": "danger" }
]
}
]
}
زر رابط بعنوان URL فقط:
{
"blocks": [
{ "type": "text", "text": "Release notes are ready." },
{
"type": "buttons",
"buttons": [{ "label": "Open notes", "url": "https://example.com/release" }]
}
]
}
قائمة اختيار:
{
"title": "Choose environment",
"blocks": [
{
"type": "select",
"placeholder": "Environment",
"options": [
{ "label": "Canary", "value": "env:canary" },
{ "label": "Production", "value": "env:prod" }
]
}
]
}
إرسال عبر CLI:
openclaw message send --channel slack \
--target channel:C123 \
--message "Deploy approval" \
--presentation '{"title":"Deploy approval","tone":"warning","blocks":[{"type":"text","text":"Canary is ready."},{"type":"buttons","buttons":[{"label":"Approve","value":"deploy:approve","style":"success"},{"label":"Decline","value":"deploy:decline","style":"danger"}]}]}'
تسليم مثبّت:
openclaw message send --channel telegram \
--target -1001234567890 \
--message "Topic opened" \
--pin
تسليم مثبّت مع JSON صريح:
{
"pin": {
"enabled": true,
"notify": true,
"required": false
}
}
عقد العارض
تعلن Plugins القنوات دعم العرض على محوّلها الصادر:
const adapter: ChannelOutboundAdapter = {
deliveryMode: "direct",
presentationCapabilities: {
supported: true,
buttons: true,
selects: true,
context: true,
divider: true,
},
deliveryCapabilities: {
pin: true,
},
renderPresentation({ payload, presentation, ctx }) {
return renderNativePayload(payload, presentation, ctx);
},
async pinDeliveredMessage({ target, messageId, pin }) {
await pinNativeMessage(target, messageId, { notify: pin.notify === true });
},
};
حقول القدرات هي قيم منطقية بسيطة عن قصد. فهي تصف ما يستطيع العارض جعله تفاعليًا، لا كل حد في المنصة الأصلية. يظل العارضون مالكين للحدود الخاصة بالمنصة، مثل الحد الأقصى لعدد الأزرار، وعدد الكتل، وحجم البطاقة.
تدفق العرض في النواة
عندما يتضمن ReplyPayload أو إجراء رسالة presentation، تقوم النواة بما يلي:
- تطبّع حمولة العرض.
- تحل محوّل القناة الصادر للقناة الهدف.
- تقرأ
presentationCapabilities. - تستدعي
renderPresentationعندما يستطيع المحوّل عرض الحمولة. - تعود إلى نص محافظ عندما يكون المحوّل غائبًا أو غير قادر على العرض.
- ترسل الحمولة الناتجة عبر مسار تسليم القناة المعتاد.
- تطبق بيانات تعريف التسليم مثل
delivery.pinبعد أول رسالة مُرسلة بنجاح.
تملك النواة سلوك الرجوع الاحتياطي حتى يتمكن المنتجون من البقاء محايدين تجاه القنوات. وتملك Plugins القنوات العرض الأصلي ومعالجة التفاعلات.
قواعد التدهور
يجب أن يكون العرض آمنًا للإرسال على القنوات المحدودة.
يتضمن النص الاحتياطي:
titleكسطر أول- كتل
textكفقرات عادية - كتل
contextكأسطر سياق مضغوطة - كتل
dividerكفاصل بصري - تسميات الأزرار، بما في ذلك عناوين URL لأزرار الروابط
- تسميات خيارات الاختيار
ينبغي أن تتدهور عناصر التحكم الأصلية غير المدعومة بدلًا من إفشال عملية الإرسال كلها. أمثلة:
- يرسل Telegram نصًا احتياطيًا عندما تكون الأزرار المضمنة معطلة.
- القناة التي لا تدعم الاختيار تسرد خيارات الاختيار كنص.
- يصبح زر URL فقط إما زر رابط أصليًا أو سطر URL احتياطيًا.
- إخفاقات التثبيت الاختيارية لا تفشل الرسالة المسلّمة.
الاستثناء الرئيسي هو delivery.pin.required: true؛ إذا طُلب التثبيت باعتباره
مطلوبًا ولم تستطع القناة تثبيت الرسالة المرسلة، يبلّغ التسليم عن فشل.
ربط المزوّد
العارضون المضمّنون الحاليون:
| القناة | هدف العرض الأصلي | ملاحظات |
|---|---|---|
| Discord | المكونات وحاويات المكونات | يحافظ على channelData.discord.components القديم لمنتجي الحمولات الأصلية الخاصة بالمزوّد الحاليين، لكن عمليات الإرسال المشتركة الجديدة ينبغي أن تستخدم presentation. |
| Slack | Block Kit | يحافظ على channelData.slack.blocks القديم لمنتجي الحمولات الأصلية الخاصة بالمزوّد الحاليين، لكن عمليات الإرسال المشتركة الجديدة ينبغي أن تستخدم presentation. |
| Telegram | نص مع لوحات مفاتيح مضمنة | تتطلب الأزرار/الاختيارات قدرة الأزرار المضمنة على السطح الهدف؛ وإلا يُستخدم النص الاحتياطي. |
| Mattermost | نص مع خصائص تفاعلية | تتدهور الكتل الأخرى إلى نص. |
| Microsoft Teams | Adaptive Cards | يُضمّن نص message العادي مع البطاقة عند توفيرهما معًا. |
| Feishu | بطاقات تفاعلية | يمكن أن يستخدم رأس البطاقة title؛ ويتجنب المتن تكرار ذلك العنوان. |
| القنوات العادية | نص احتياطي | تحصل القنوات التي لا تملك عارضًا على مخرجات قابلة للقراءة رغم ذلك. |
توافق الحمولات الأصلية الخاصة بالمزوّد تسهيل انتقالي لمنتجي الردود الحاليين. وليس سببًا لإضافة حقول أصلية مشتركة جديدة.
العرض مقابل InteractiveReply
InteractiveReply هو المجموعة الفرعية الداخلية الأقدم التي تستخدمها مساعدات
الموافقة والتفاعل. وهو يدعم:
- النص
- الأزرار
- الاختيارات
MessagePresentation هو عقد الإرسال المشترك المعتمد. ويضيف:
- العنوان
- النبرة
- السياق
- الفاصل
- أزرار URL فقط
- بيانات تعريف تسليم عامة عبر
ReplyPayload.delivery
استخدم المساعدات من openclaw/plugin-sdk/interactive-runtime عند وصل الشفرة
الأقدم:
interactiveReplyToPresentation,
normalizeMessagePresentation,
presentationToInteractiveReply,
renderMessagePresentationFallbackText,
} from "openclaw/plugin-sdk/interactive-runtime";
ينبغي أن تقبل الشفرة الجديدة MessagePresentation أو تنتجه مباشرة.
تثبيت التسليم
التثبيت سلوك تسليم، وليس عرضًا. استخدم delivery.pin بدلًا من الحقول الأصلية
الخاصة بالمزوّد مثل channelData.telegram.pin.
الدلالات:
pin: trueيثبت أول رسالة تُسلّم بنجاح.- القيمة الافتراضية لـ
pin.notifyهيfalse. - القيمة الافتراضية لـ
pin.requiredهيfalse. - إخفاقات التثبيت الاختيارية تتدهور وتترك الرسالة المرسلة سليمة.
- إخفاقات التثبيت المطلوبة تفشل التسليم.
- تثبّت الرسائل المجزأة أول جزء مُسلّم، وليس الجزء الأخير.
ما زالت إجراءات الرسائل اليدوية pin وunpin وpins موجودة للرسائل الحالية
عندما يدعم المزوّد هذه العمليات.
قائمة تحقق مؤلف Plugin
- أعلن
presentationمنdescribeMessageTool(...)عندما تستطيع القناة عرض العرض الدلالي أو تدهوره بأمان. - أضف
presentationCapabilitiesإلى محوّل وقت التشغيل الصادر. - نفّذ
renderPresentationفي شفرة وقت التشغيل، لا في شفرة إعداد Plugin لمستوى التحكم. - أبق مكتبات واجهة المستخدم الأصلية خارج مسارات الإعداد/الفهرس الساخنة.
- حافظ على حدود المنصة في العارض والاختبارات.
- أضف اختبارات رجوع احتياطي للأزرار غير المدعومة، والاختيارات، وأزرار URL،
وتكرار العنوان/النص، وعمليات الإرسال المختلطة التي تجمع
messageمعpresentation. - أضف دعم تثبيت التسليم عبر
deliveryCapabilities.pinوpinDeliveredMessageفقط عندما يستطيع المزوّد تثبيت معرّف الرسالة المرسلة. - لا تعرض حقول بطاقات/كتل/مكونات/أزرار أصلية جديدة خاصة بالمزوّد عبر مخطط إجراء الرسائل المشتركة.