Plugin maintainer reference
API исходящих сообщений канала
Плагины каналов предоставляют поведение для исходящих сообщений из
openclaw/plugin-sdk/channel-outbound. Используйте
openclaw/plugin-sdk/channel-inbound для оркестрации
получения, контекста и диспетчеризации.
Ядро отвечает за очереди, надёжное хранение, общую политику повторных попыток, хуки, квитанции и
общий инструмент message. Плагин отвечает за нативные вызовы отправки, редактирования и удаления,
нормализацию адресата, платформенные ветки обсуждений, выбранные цитаты, флаги
уведомлений, состояние учётной записи и побочные эффекты, зависящие от платформы.
Адаптер
Большинство плагинов определяют один адаптер 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, }), }; }, },});Объявляйте только те возможности, которые нативный транспорт действительно сохраняет. Покройте каждую объявленную возможность отправки, квитанций, интерактивного предпросмотра и подтверждения получения контрактными вспомогательными функциями, экспортируемыми из этого подпути.
Очистка обычного текста
Используйте sanitizeForPlainText(...), когда адаптеру исходящих сообщений требуется преобразовать
поддерживаемые HTML-теги форматирования в облегчённую текстовую разметку. По умолчанию сохраняются
существующие маркеры полужирного и зачёркнутого текста в стиле чатов. Передавайте
{ style: "markdown" } только тогда, когда канал повторно разбирает результат как Markdown:
const chatText = sanitizeForPlainText(text);const markdownText = sanitizeForPlainText(text, { style: "markdown" });Стиль Markdown использует **bold** и ~~strikethrough~~; курсив и встроенный
код сохраняют _italic_ и маркеры обратных кавычек в обоих стилях. Выбирайте стиль на
границе канала, а не переписывайте текст маркеров после очистки.
Свидетельства доставки
MessageReceipt записывает результат, возвращённый адаптером канала. Конкретные
идентификаторы сообщений платформы показывают, что путь отправки платформы принял
сообщение; они не доказывают, что устройство получателя отобразило или прочитало его.
Квитанции без идентификаторов сообщений платформы являются только локальными метаданными квитанции.
Каналы с квитанциями о прочтении или состоянием доставки на устройство должны отслеживать эти факты
через отдельный путь, специфичный для канала.
Если адаптер канала может доказать, что повторная попытка после сбоя не может продублировать
видимую получателю отправку и вызов, способный выполнить финализацию, ещё не начинался, выбросьте
new PlatformMessageNotDispatchedError("...", { cause: error }) из
openclaw/plugin-sdk/error-runtime. Тогда ядро сможет очистить устаревшие
свидетельства попытки отправки и безопасно повторить поставленное в очередь намерение. Такое утверждение может делать только адаптер, которому принадлежит
граница окончательной диспетчеризации. Никогда не используйте маркер после начала
вызова финализации или отправки либо после получения неоднозначного результата; ошибочная маркировка может
привести к дублированию сообщений.
Существующие адаптеры исходящих сообщений
Если у канала уже есть совместимый адаптер outbound, создайте на его основе
адаптер сообщений вместо дублирования кода отправки:
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 и phase со значением live или
recovery.
Верните { status: "allowed" }, чтобы продолжить. Верните
{ status: "permanent_rejection", reason }, если доставку нельзя
сохранять, отправлять напрямую или воспроизводить. Отклонение в реальном времени приводит к сбою до создания
очереди, вызова хуков сообщений или работы с платформой. Отклонение при восстановлении помечает
запись в очереди как неудачную и пропускает согласование и воспроизведение. Отсутствие хука
означает разрешение.
Хук принимает синхронное решение о допуске, а не выполняет отправку. Читайте только
уже загруженную конфигурацию или состояние среды выполнения; не выполняйте сетевой, файловый или
иной асинхронный ввод-вывод. Контрактные тесты должны проверять обе фазы и оба
варианта результата через ChannelMessageDurableFinalAdapter из
openclaw/plugin-sdk/channel-outbound.
Диспетчеризация для совместимости
Формируйте диспетчеризацию входящих ответов через dispatchChannelInboundReply(...)
из channel-inbound. Оставляйте платформенную доставку в адаптере доставки; используйте
channel-outbound для адаптеров сообщений, надёжных отправок, квитанций, интерактивного
предпросмотра и параметров конвейера ответов.