Plugin maintainer reference

चैनल आउटबाउंड API

Channel Plugin, आउटबाउंड संदेश व्यवहार को openclaw/plugin-sdk/channel-outbound से उजागर करते हैं। प्राप्ति/कॉन्टेक्स्ट/डिस्पैच ऑर्केस्ट्रेशन के लिए openclaw/plugin-sdk/channel-inbound का उपयोग करें।

कोर क्यूइंग, टिकाऊपन, टिकाऊ इनग्रेस मॉनिटर और ड्रेन (createChannelIngressMonitor, createChannelIngressDrain, और openChannelIngressDrain), सामान्य पुनःप्रयास नीति, टर्न-अडॉप्शन जीवनचक्र (turnAdoptionLifecycle / bindIngressLifecycleToReplyOptions), हुक, रसीदें, और साझा message टूल का स्वामी है। Plugin नेटिव भेजने/संपादित करने/हटाने की कॉल, लक्ष्य सामान्यीकरण, प्लेटफ़ॉर्म थ्रेडिंग, चयनित उद्धरण, सूचना फ़्लैग, अकाउंट स्थिति, इनग्रेस निरीक्षण और पेलोड एन्कोडिंग, लेन कुंजियाँ, पुनःप्रयास-न-योग्य प्रेडिकेट, वैकल्पिक सुपरसीड प्राधिकरण, और प्लेटफ़ॉर्म-विशिष्ट दुष्प्रभावों का स्वामी है।

टिकाऊ इनग्रेस मॉनिटर

जब किसी चैनल को स्वीकार किए गए ट्रांसपोर्ट इवेंट डिस्पैच से पहले स्थायी रखने हों, तब createChannelIngressMonitor(...) का उपयोग करें। यह चैनल इनग्रेस क्यू और ड्रेन को साझा प्रवेश, पोलिंग, प्रूनिंग, डिलीवरी, और शटडाउन जीवनचक्र के साथ संयोजित करता है। निचले स्तर के createChannelIngressDrain(...) का उपयोग केवल तब करें, जब ट्रांसपोर्ट किसी मूलतः भिन्न प्रवेश या पंप अनुबंध का स्वामी हो।

आवश्यक विकल्प ये हैं:

विकल्प अनुबंध
queue एक ChannelIngressQueue, या अकाउंट-स्कोप वाली क्यू खोलने वाली लेज़ी फ़ैक्टरी।
inspect(raw, context) स्थिर eventId और क्रमबद्ध laneKey, या अनदेखा किए गए इवेंट के लिए null लौटाता है। क्लेम-समय के तथ्य स्थायी आईडी और लेन से मेल खाने चाहिए।
payload पेलोड संस्करण के साथ बॉडी क्रमबद्धता/विक्रमबद्धता प्रदान करता है। मानक { version, rawEvent } स्ट्रिंग एनवलप के लिए storage: "raw-event" का उपयोग करें, या किसी मौजूदा चैनल-विशिष्ट आकार के लिए कस्टम एन्कोड/डीकोड कॉलबैक दें। createClaimError अमान्य संस्करणों या बदली हुई पहचान का वर्गीकरण करता है।
deliver(raw, lifecycle, claim) एक डीकोड किए गए इवेंट को डिस्पैच करता है और संपूर्ण अडॉप्शन जीवनचक्र प्राप्त करता है। यह completed, deferred, failed-retryable, या कुछ भी नहीं लौटा सकता है।
pollIntervalMs मॉनिटर के चलने के दौरान रिकवरी/ड्रेन पोल शेड्यूल करता है।
retention प्रून आवृत्ति तथा पूर्ण/विफल TTL और प्रविष्टि सीमाएँ प्रदान करता है।

मॉनिटर प्रवेशों को क्रमिक बनाता है, ताकि एपेंड बैकऑफ़ किसी लेन का क्रम उलट न सके। डिफ़ॉल्ट सीमित एपेंड विलंब 0, 100, और 300 ms हैं; इनके समाप्त होने पर ट्रांसपोर्ट कॉलबैक अस्वीकार हो जाता है, बजाय ऐसे इवेंट को डिस्पैच करने के जिसे टिकाऊ नहीं बनाया गया था। क्लेम के समय यह संस्करणित पेलोड को डीकोड करता है, inspect को फिर से चलाता है, और डिलीवरी से पहले आईडी या लेन के बेमेल होने को अस्वीकार करता है।

deliver को onAdopted, onDeferred, onAdoptionFinalizing, onAbandoned, और abortSignal मिलते हैं। स्पष्ट हैंडऑफ़ के बिना लौटने पर टर्मिनल नो-डिस्पैच इवेंट को अपनाया हुआ चिह्नित किया जाता है। admission हमेशा exclusive होता है। स्थगित हैंडऑफ़ क्लेम को होल्ड रखता है, जबकि शटडाउन या निरस्तीकरण अपनाए न गए कार्य को पुनःप्रयास योग्य बनाए रखता है। मॉनिटर डिलीवरी को क्लेम निपटान से स्वतंत्र रूप से ट्रैक करता है, क्योंकि चैनल का डिलीवरी प्रॉमिस लौटने से पहले अडॉप्शन किसी पंक्ति को टूम्बस्टोन कर सकता है।

वैकल्पिक सेटिंग में कस्टम एपेंड विलंब, उन्नत ड्रेन क्रम/समवर्तीता/पुनःप्रयास नीति के लिए drain विकल्प ब्लॉक, बाहरी abortSignal, एक क्लॉक, पंप त्रुटि रिपोर्टिंग, रुकी हुई त्रुटि की फ़ैक्टरी, और प्रवेश नीति शामिल हैं। लौटाया गया मॉनिटर admit, start, pause, stop, waitForIdle, isRunning, और isStopped उजागर करता है। stop पहले स्वीकार किए गए प्रवेशों का निपटान करता है, फिर ड्रेन को निरस्त और डिस्पोज़ करता है, पंप और सक्रिय डिलीवरी की प्रतीक्षा करता है, और लेज़ी-निर्माण रेस को बंद करने के लिए फिर से डिस्पोज़ करता है।

ट्रांसपोर्ट-विशिष्ट रिडैक्शन, रॉ-एनवलप सत्यापन, पुनःप्रयास-न-योग्य वर्गीकरण, और स्थायी पेलोड आकार को Plugin में रखें। Webhook ट्रांसपोर्ट को केवल admit के समाधान के बाद अभिस्वीकृति देनी चाहिए; गैर-रीप्ले ट्रांसपोर्ट को चुपचाप डिस्पैच करने के बजाय टिकाऊ एपेंड समाप्ति को सामने लाना चाहिए।

अडैप्टर

अधिकांश Plugin एक message अडैप्टर परिभाषित करते हैं:

ts
   defineChannelMessageAdapter,  createMessageReceiptFromOutboundResults,} from "openclaw/plugin-sdk/channel-outbound"; export const demoMessageAdapter = defineChannelMessageAdapter({  id: "demo",  durableFinal: {    capabilities: {      text: true,      replyTo: true,      thread: true,      messageSendingHooks: true,    },  },  send: {    text: async ({ cfg, to, text, accountId, replyToId, threadId, signal }) => {      const sent = await sendDemoMessage({        cfg,        to,        text,        accountId: accountId ?? undefined,        replyToId: replyToId ?? undefined,        threadId: threadId == null ? undefined : String(threadId),        signal,      });       return {        receipt: createMessageReceiptFromOutboundResults({          results: [{ channel: "demo", messageId: sent.id, conversationId: to }],          kind: "text",          threadId: threadId == null ? undefined : String(threadId),          replyToId: replyToId ?? undefined,        }),      };    },  },});

केवल उन्हीं क्षमताओं की घोषणा करें जिन्हें नेटिव ट्रांसपोर्ट वास्तव में संरक्षित रखता है। घोषित प्रत्येक प्रेषण, रसीद, लाइव-प्रीव्यू, और प्राप्ति-अभिस्वीकृति क्षमता को इस सबपाथ से निर्यात किए गए अनुबंध सहायकों से कवर करें।

आउटबाउंड इको दमन

जब कोई प्लेटफ़ॉर्म Plugin के अपने आउटबाउंड संदेश को इनबाउंड के रूप में फिर से डिलीवर कर सकता हो, तब चैनल, अकाउंट, वार्तालाप, और स्थिर प्लेटफ़ॉर्म संदेश या स्रोत पहचान के साथ recordOutboundMessageIdentity(...) को कॉल करें। साझा इनबाउंड टर्न पाथ, सेशन रिकॉर्डिंग या एजेंट डिस्पैच से पहले सीमित 30-सेकंड विंडो तक मेल खाती पहचानों को छोड़ देता है; डिलीवरी रेस बंद करने के लिए स्रोत पहचान को भेजने से पहले आरक्षित किया जा सकता है या चैनल रूट हटाए जाने पर रीफ़्रेश किया जा सकता है। isRecentOutboundMessageIdentity(...) चैनल निदान और परीक्षणों के लिए वही क्वेरी उजागर करता है। उसी स्थिर पहचान के लिए समानांतर चैनल-स्थानीय TTL कैश न बनाए रखें।

प्लेन-टेक्स्ट सैनिटाइज़ेशन

जब किसी आउटबाउंड अडैप्टर को समर्थित HTML फ़ॉर्मैटिंग टैग को हल्के टेक्स्ट मार्कअप में बदलना हो, तब sanitizeForPlainText(...) का उपयोग करें। डिफ़ॉल्ट मौजूदा चैट-शैली के बोल्ड और स्ट्राइकथ्रू मार्कर बनाए रखता है। { style: "markdown" } केवल तब पास करें, जब चैनल परिणाम को Markdown के रूप में फिर से पार्स करता हो:

ts
 const chatText = sanitizeForPlainText(text);const markdownText = sanitizeForPlainText(text, { style: "markdown" });

Markdown शैली **bold** और ~~strikethrough~~ का उपयोग करती है; इटैलिक और इनलाइन कोड दोनों शैलियों में _italic_ और बैकटिक मार्कर बनाए रखते हैं। सैनिटाइज़ेशन के बाद मार्कर टेक्स्ट दोबारा लिखने के बजाय चैनल सीमा पर शैली चुनें।

डिलीवरी साक्ष्य

एक MessageReceipt चैनल अडैप्टर द्वारा लौटाए गए परिणाम को रिकॉर्ड करता है। ठोस प्लेटफ़ॉर्म संदेश पहचानकर्ता दिखाते हैं कि प्लेटफ़ॉर्म प्रेषण पाथ ने संदेश स्वीकार किया; वे यह सिद्ध नहीं करते कि प्राप्तकर्ता के डिवाइस ने उसे प्रदर्शित किया या पढ़ा। प्लेटफ़ॉर्म संदेश पहचानकर्ताओं के बिना रसीदें केवल स्थानीय रसीद मेटाडेटा हैं। रीड रसीदों या डिवाइस-डिलीवरी स्थिति वाले चैनलों को उन तथ्यों को एक अलग चैनल-विशिष्ट पाथ से ट्रैक करना चाहिए।

यदि कोई चैनल अडैप्टर सिद्ध कर सकता है कि किसी विफलता के पुनःप्रयास से प्राप्तकर्ता को दिखाई देने वाला प्रेषण डुप्लिकेट नहीं हो सकता और अंतिम रूप देने में सक्षम कोई कॉल शुरू नहीं हुई, तो openclaw/plugin-sdk/error-runtime से new PlatformMessageNotDispatchedError("...", { cause: error }) थ्रो करें। तब कोर पुराने प्रेषण-प्रयास साक्ष्य को साफ़ करके क्यू किए गए इरादे का सुरक्षित रूप से पुनःप्रयास कर सकता है। केवल अंतिम डिस्पैच सीमा का स्वामी अडैप्टर ही यह दावा कर सकता है। अंतिम रूप देने/प्रेषण कॉल शुरू होने या अस्पष्ट परिणाम लौटाने के बाद मार्कर का कभी उपयोग न करें; गलत चिह्नांकन से संदेश डुप्लिकेट हो सकते हैं।

मौजूदा आउटबाउंड अडैप्टर

यदि चैनल के पास पहले से संगत outbound अडैप्टर है, तो प्रेषण कोड की नकल करने के बजाय उसी से संदेश अडैप्टर प्राप्त करें:

ts
 export const messageAdapter = createChannelMessageAdapterFromOutbound({  id: "demo",  outbound,  durableFinal: {    capabilities: {      text: true,      media: true,    },  },});

टिकाऊ प्रेषण

रनटाइम प्रेषण सहायक भी channel-outbound पर उपलब्ध हैं:

  • sendDurableMessageBatch(...)
  • withDurableMessageSendContext(...)
  • deliverInboundReplyWithMessageSendContext(...)
  • ड्राफ़्ट स्ट्रीमिंग/प्रगति सहायक, जैसे resolveChannelDraftStreamingChunking(...)

sendDurableMessageBatch(...) एक स्पष्ट परिणाम लौटाता है:

परिणाम अर्थ
sent प्लेटफ़ॉर्म प्रेषण पाथ ने कम-से-कम एक दृश्यमान प्लेटफ़ॉर्म संदेश स्वीकार किया
suppressed किसी प्लेटफ़ॉर्म संदेश को अनुपलब्ध नहीं माना जाना चाहिए
partial_failed बाद के पेलोड या दुष्प्रभाव की विफलता से पहले कम-से-कम एक प्लेटफ़ॉर्म संदेश स्वीकार किया गया
failed कोई प्लेटफ़ॉर्म रसीद उत्पन्न नहीं हुई

जब कोई बैच भेजे गए, दबाए गए, और विफल पेलोड को मिलाता हो, तब payloadOutcomes का उपयोग करें। खाली पुराने प्रत्यक्ष-डिलीवरी परिणाम से हुक निरस्तीकरण का अनुमान न लगाएँ।

स्थगित डिलीवरी प्रवेश

जब कोई समाधान किया गया अकाउंट कोर-प्रबंधित आउटबाउंड या स्थगित डिलीवरी को सुरक्षित रूप से स्वीकार नहीं कर सकता, तब message.durableFinal.admitDeferredDelivery(...) का उपयोग करें। कोर लाइव आउटबाउंड कार्य से पहले इस हुक को समकालिक रूप से कॉल करता है, जिसमें क्यू स्थायित्व छोड़ने वाले पाथ भी शामिल हैं, और पुनर्प्राप्त इरादे को रीप्ले करने से पहले इसे फिर कॉल करता है। कॉन्टेक्स्ट में cfg, channel, to, accountId, और live या recovery का एक phase शामिल है।

जारी रखने के लिए { status: "allowed" } लौटाएँ। जब डिलीवरी को स्थायी, सीधे भेजा, या रीप्ले नहीं किया जाना चाहिए, तब { status: "permanent_rejection", reason } लौटाएँ। लाइव अस्वीकृति क्यू निर्माण, संदेश हुक, या प्लेटफ़ॉर्म कार्य से पहले विफल हो जाती है। रिकवरी अस्वीकृति क्यू किए गए रिकॉर्ड को विफल चिह्नित करती है और मिलान तथा रीप्ले छोड़ देती है। हुक न देना अनुमति के समान है।

हुक एक समकालिक प्रवेश निर्णय है, भेजने का पथ नहीं। केवल पहले से लोड किए गए कॉन्फ़िगरेशन या रनटाइम स्थिति को पढ़ें; नेटवर्क, फ़ाइल सिस्टम, या अन्य अतुल्यकालिक I/O न करें। अनुबंध परीक्षणों को openclaw/plugin-sdk/channel-outbound से ChannelMessageDurableFinalAdapter के माध्यम से दोनों चरणों और दोनों परिणाम प्रकारों का परीक्षण करना चाहिए।

संगतता प्रेषण

channel-inbound से dispatchChannelInboundReply(...) के माध्यम से इनबाउंड उत्तर प्रेषण संयोजित करें। प्लेटफ़ॉर्म डिलीवरी को डिलीवरी अडैप्टर में रखें; संदेश अडैप्टर, टिकाऊ प्रेषण, प्राप्ति-पुष्टियों, लाइव पूर्वावलोकन और उत्तर पाइपलाइन विकल्पों के लिए channel-outbound का उपयोग करें।

Was this useful?
On this page

On this page