Plugin maintainer reference
API in uscita del canale
I Plugin di canale espongono il comportamento dei messaggi in uscita da
openclaw/plugin-sdk/channel-outbound. Usa
openclaw/plugin-sdk/channel-inbound per l'orchestrazione di
ricezione/contesto/inoltro.
Il core gestisce accodamento, persistenza, criteri generici per i nuovi
tentativi, hook, ricevute e lo strumento message condiviso. Il Plugin gestisce
le chiamate native di invio/modifica/eliminazione, la normalizzazione della
destinazione, i thread della piattaforma, le citazioni selezionate, i flag di
notifica, lo stato dell'account e gli effetti collaterali specifici della
piattaforma.
Adattatore
La maggior parte dei Plugin definisce un adattatore message:
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, }), }; }, },});Dichiara solo le funzionalità effettivamente preservate dal trasporto nativo. Copri ogni funzionalità dichiarata di invio, ricevuta, anteprima in tempo reale e conferma di ricezione con gli helper di contratto esportati da questo sottopercorso.
Sanitizzazione del testo normale
Usa sanitizeForPlainText(...) quando un adattatore in uscita deve convertire i
tag di formattazione HTML supportati in una sintassi testuale leggera. Per
impostazione predefinita vengono mantenuti i marcatori esistenti in stile chat
per grassetto e barrato. Passa { style: "markdown" } solo quando il canale
analizza nuovamente il risultato come Markdown:
const chatText = sanitizeForPlainText(text);const markdownText = sanitizeForPlainText(text, { style: "markdown" });Lo stile Markdown usa **bold** e ~~strikethrough~~; il corsivo e il codice
inline mantengono rispettivamente i marcatori _italic_ e gli apici inversi in
entrambi gli stili. Seleziona lo stile al confine del canale anziché riscrivere
il testo dei marcatori dopo la sanitizzazione.
Evidenza di consegna
Un MessageReceipt registra il risultato restituito da un adattatore di
canale. Gli identificatori concreti dei messaggi della piattaforma mostrano che
il percorso di invio della piattaforma ha accettato il messaggio; non dimostrano
che il dispositivo del destinatario lo abbia visualizzato o letto. Le ricevute
prive di identificatori dei messaggi della piattaforma sono solo metadati di
ricevuta locali. I canali con conferme di lettura o stato di consegna al
dispositivo devono registrare tali informazioni tramite un percorso separato
specifico del canale.
Se un adattatore di canale può dimostrare che un nuovo tentativo dopo un errore
non può duplicare un invio visibile al destinatario e che non è iniziata alcuna
chiamata in grado di finalizzare l'operazione, genera
new PlatformMessageNotDispatchedError("...", { cause: error }) da
openclaw/plugin-sdk/error-runtime. Il core può quindi eliminare le evidenze
obsolete del tentativo di invio e riprovare in sicurezza l'intento accodato.
Solo l'adattatore responsabile del confine di inoltro finale può fare questa
asserzione. Non usare mai il marcatore dopo l'inizio di una chiamata di
finalizzazione/invio o quando questa restituisce un risultato ambiguo; una
marcatura errata può duplicare i messaggi.
Adattatori in uscita esistenti
Se il canale dispone già di un adattatore outbound compatibile, ricava
l'adattatore di messaggio anziché duplicare il codice di invio:
export const messageAdapter = createChannelMessageAdapterFromOutbound({ id: "demo", outbound, durableFinal: { capabilities: { text: true, media: true, }, },});Invii persistenti
Anche gli helper di invio a runtime si trovano in channel-outbound:
sendDurableMessageBatch(...)withDurableMessageSendContext(...)deliverInboundReplyWithMessageSendContext(...)- helper per lo streaming delle bozze/l'avanzamento, come
resolveChannelDraftStreamingChunking(...)
sendDurableMessageBatch(...) restituisce uno dei seguenti esiti espliciti:
| Esito | Significato |
|---|---|
sent |
almeno un messaggio visibile della piattaforma è stato accettato dal percorso di invio |
suppressed |
nessun messaggio della piattaforma deve essere considerato mancante |
partial_failed |
almeno un messaggio è stato accettato prima dell'errore di un payload o effetto collaterale successivo |
failed |
non è stata prodotta alcuna ricevuta della piattaforma |
Usa payloadOutcomes quando un batch combina payload inviati, soppressi e non
riusciti. Non dedurre l'annullamento da parte di un hook da un risultato vuoto
del precedente sistema di consegna diretta.
Ammissione della consegna differita
Usa message.durableFinal.admitDeferredDelivery(...) quando un account risolto
non può accettare in sicurezza la consegna in uscita o differita gestita dal
core. Il core chiama questo hook in modo sincrono prima dell'elaborazione in
tempo reale dei messaggi in uscita, inclusi i percorsi che ignorano la
persistenza della coda, e nuovamente prima di riprodurre un intento recuperato.
Il contesto include cfg, channel, to, accountId e una phase pari a
live o recovery.
Restituisci { status: "allowed" } per continuare. Restituisci
{ status: "permanent_rejection", reason } quando la consegna non deve essere
persistita, inviata direttamente o riprodotta. Un rifiuto in tempo reale causa
un errore prima della creazione della coda, degli hook dei messaggi o delle
operazioni sulla piattaforma. Un rifiuto durante il recupero contrassegna come
non riuscito il record accodato e ignora riconciliazione e riproduzione.
L'omissione dell'hook equivale a un'autorizzazione.
L'hook è una decisione sincrona di ammissione, non un percorso di invio. Leggi
solo la configurazione o lo stato di runtime già caricati; non eseguire
operazioni di rete, sul file system o altre operazioni di I/O asincrone. I test
del contratto devono coprire entrambe le fasi ed entrambe le varianti di
risultato tramite ChannelMessageDurableFinalAdapter da
openclaw/plugin-sdk/channel-outbound.
Inoltro per compatibilità
Componi l'inoltro delle risposte in ingresso tramite
dispatchChannelInboundReply(...) da channel-inbound. Mantieni la consegna
alla piattaforma nell'adattatore di consegna; usa channel-outbound per gli
adattatori di messaggio, gli invii persistenti, le ricevute, l'anteprima in
tempo reale e le opzioni della pipeline di risposta.