Kanal-Plugins erstellen
Diese Anleitung führt Sie durch das Erstellen eines Kanal-Plugins, das OpenClaw mit einer Messaging-Plattform verbindet. Am Ende haben Sie einen funktionierenden Kanal mit DM-Sicherheit, Kopplung, Reply-Threading und ausgehenden Nachrichten.Wenn Sie noch nie ein OpenClaw-Plugin erstellt haben, lesen Sie zuerst
Erste Schritte für die grundlegende Paket-
Struktur und Manifest-Einrichtung.
So funktionieren Kanal-Plugins
Kanal-Plugins benötigen keine eigenen Sende-/Bearbeiten-/Reagieren-Tools. OpenClaw behält ein gemeinsam genutztesmessage-Tool im Core. Ihr Plugin besitzt:
- Konfiguration — Kontenauflösung und Einrichtungsassistent
- Sicherheit — DM-Richtlinie und Allowlists
- Kopplung — DM-Genehmigungsablauf
- Sitzungsgrammatik — wie anbieterspezifische Gesprächs-IDs auf Basis-Chats, Thread-IDs und Parent-Fallbacks abgebildet werden
- Ausgehend — Senden von Text, Medien und Umfragen an die Plattform
- Threading — wie Antworten in Threads organisiert werden
:thread:-Buchführung und den Versand.
Wenn Ihre Plattform zusätzlichen Geltungsbereich in Gesprächs-IDs speichert, behalten Sie dieses Parsing
im Plugin mit messaging.resolveSessionConversation(...). Das ist der
kanonische Hook für die Zuordnung von rawId zur Basis-Gesprächs-ID, einer optionalen Thread-
ID, einer expliziten baseConversationId und allen parentConversationCandidates.
Wenn Sie parentConversationCandidates zurückgeben, halten Sie deren Reihenfolge von dem
engsten Parent bis zum breitesten/Basis-Gespräch ein.
Gebündelte Plugins, die dasselbe Parsing benötigen, bevor die Kanal-Registry startet,
können auch eine Datei session-key-api.ts auf oberster Ebene mit einem passenden
Export resolveSessionConversation(...) bereitstellen. Der Core verwendet diese bootstrap-sichere Oberfläche
nur dann, wenn die Laufzeit-Plugin-Registry noch nicht verfügbar ist.
messaging.resolveParentConversationCandidates(...) bleibt als
Legacy-Kompatibilitäts-Fallback verfügbar, wenn ein Plugin nur Parent-Fallbacks zusätzlich
zur generischen/rohen ID benötigt. Wenn beide Hooks existieren, verwendet der Core
zuerst resolveSessionConversation(...).parentConversationCandidates und fällt nur
auf resolveParentConversationCandidates(...) zurück, wenn der kanonische Hook
sie auslässt.
Genehmigungen und Kanalfähigkeiten
Die meisten Kanal-Plugins benötigen keinen genehmigungsspezifischen Code.- Der Core besitzt
/approveim selben Chat, gemeinsam genutzte Payloads für Genehmigungsschaltflächen und generische Fallback-Zustellung. - Bevorzugen Sie ein einzelnes
approvalCapability-Objekt auf dem Kanal-Plugin, wenn der Kanal genehmigungsspezifisches Verhalten benötigt. ChannelPlugin.approvalswurde entfernt. Legen Sie Fakten zu Genehmigungszustellung/nativem Verhalten/Rendering/Auth inapprovalCapabilityab.plugin.authist nur für Login/Logout; der Core liest keine Genehmigungs-Auth-Hooks mehr aus diesem Objekt.approvalCapability.authorizeActorActionundapprovalCapability.getActionAvailabilityStatesind die kanonische Nahtstelle für Genehmigungs-Auth.- Verwenden Sie
approvalCapability.getActionAvailabilityStatefür die Verfügbarkeit von Genehmigungs-Auth im selben Chat. - Wenn Ihr Kanal native Exec-Genehmigungen bereitstellt, verwenden Sie
approvalCapability.getExecInitiatingSurfaceStatefür den initiierenden Oberflächen-/Native-Client-Status, wenn dieser sich von der Genehmigungs-Auth im selben Chat unterscheidet. Der Core verwendet diesen exec-spezifischen Hook, umenabledunddisabledzu unterscheiden, zu entscheiden, ob der initiierende Kanal native Exec-Genehmigungen unterstützt, und den Kanal in die Fallback-Hinweise für Native Clients aufzunehmen.createApproverRestrictedNativeApprovalCapability(...)füllt dies für den häufigen Fall aus. - Verwenden Sie
outbound.shouldSuppressLocalPayloadPromptoderoutbound.beforeDeliverPayloadfür kanalspezifisches Payload-Lifecycle-Verhalten, etwa das Ausblenden doppelter lokaler Genehmigungs-Prompts oder das Senden von Tippindikatoren vor der Zustellung. - Verwenden Sie
approvalCapability.deliverynur für natives Genehmigungs-Routing oder Unterdrückung von Fallbacks. - Verwenden Sie
approvalCapability.nativeRuntimefür kanalinterne native Fakten zu Genehmigungen. Halten Sie es auf Hot-Channel-Entrypoints lazy mitcreateLazyChannelApprovalNativeRuntimeAdapter(...), das Ihr Laufzeitmodul bei Bedarf importieren kann, während der Core weiterhin den Genehmigungs-Lifecycle zusammensetzt. - Verwenden Sie
approvalCapability.rendernur, wenn ein Kanal wirklich benutzerdefinierte Genehmigungs-Payloads statt des gemeinsam genutzten Renderers benötigt. - Verwenden Sie
approvalCapability.describeExecApprovalSetup, wenn der Kanal in der Disabled-Antwort die exakten Konfigurationsschalter erläutern soll, die zum Aktivieren nativer Exec-Genehmigungen nötig sind. Der Hook erhält{ channel, channelLabel, accountId }; Kanäle mit benannten Konten sollten kontobezogene Pfade wiechannels.<channel>.accounts.<id>.execApprovals.*statt Standardwerten auf oberster Ebene ausgeben. - Wenn ein Kanal stabile DM-Identitäten mit Owner-Charakter aus vorhandener Konfiguration ableiten kann, verwenden Sie
createResolvedApproverActionAuthAdapterausopenclaw/plugin-sdk/approval-runtime, um/approveim selben Chat einzuschränken, ohne genehmigungsspezifische Core-Logik hinzuzufügen. - Wenn ein Kanal native Genehmigungszustellung benötigt, konzentrieren Sie den Kanalcode auf Zielnormalisierung sowie Fakten zu Transport/Darstellung. Verwenden Sie
createChannelExecApprovalProfile,createChannelNativeOriginTargetResolver,createChannelApproverDmTargetResolverundcreateApproverRestrictedNativeApprovalCapabilityausopenclaw/plugin-sdk/approval-runtime. Platzieren Sie die kanalspezifischen Fakten hinterapprovalCapability.nativeRuntime, idealerweise übercreateChannelApprovalNativeRuntimeAdapter(...)odercreateLazyChannelApprovalNativeRuntimeAdapter(...), damit der Core den Handler zusammensetzen und Anforderungsfilterung, Routing, Deduplizierung, Ablauf, Gateway-Abonnement und Hinweise auf anderweitig geroutete Anfragen übernehmen kann.nativeRuntimeist in einige kleinere Schnittstellen aufgeteilt: availability— ob das Konto konfiguriert ist und ob eine Anfrage verarbeitet werden sollpresentation— Zuordnung des gemeinsam genutzten Genehmigungs-View-Models zu nativen Payloads für ausstehend/aufgelöst/abgelaufen oder zu finalen Aktionentransport— Ziele vorbereiten sowie native Genehmigungsnachrichten senden/aktualisieren/löscheninteractions— optionale Hooks zum Binden/Lösen/Löschen von Aktionen für native Buttons oder Reaktionenobserve— optionale Hooks für Zustellungsdiagnostik- Wenn der Kanal laufzeitinterne Objekte wie einen Client, Token, eine Bolt-App oder einen Webhook-Empfänger benötigt, registrieren Sie sie über
openclaw/plugin-sdk/channel-runtime-context. Die generische Laufzeitkontext-Registry ermöglicht es dem Core, capability-gesteuerte Handler aus dem Kanal-Startup-Zustand zu bootstrappen, ohne genehmigungsspezifischen Wrapper-Kleber hinzuzufügen. - Greifen Sie nur dann zu den Low-Level-Funktionen
createChannelApprovalHandlerodercreateChannelNativeApprovalRuntime, wenn die capability-gesteuerte Schnittstelle noch nicht ausdrucksstark genug ist. - Native Genehmigungskanäle müssen sowohl
accountIdals auchapprovalKinddurch diese Helfer leiten.accountIdhält Richtlinien für Multi-Account-Genehmigungen auf das richtige Bot-Konto beschränkt, undapprovalKindhält Exec- gegenüber Plugin-Genehmigungsverhalten für den Kanal verfügbar, ohne hart codierte Verzweigungen im Core. - Der Core besitzt jetzt auch Hinweise zur Umleitung von Genehmigungen. Kanal-Plugins sollten daher keine eigenen Folgenachrichten wie „Genehmigung ging an DMs / einen anderen Kanal“ aus
createChannelNativeApprovalRuntimesenden; stattdessen sollten sie korrektes Routing von Ursprung + Genehmiger-DM über die gemeinsam genutzten Helfer für Genehmigungs-Capabilities bereitstellen, damit der Core tatsächliche Zustellungen aggregieren kann, bevor er einen Hinweis zurück in den initiierenden Chat sendet. - Bewahren Sie die Art der zugestellten Genehmigungs-ID durchgängig. Native Clients sollten das Routing von Exec- gegenüber Plugin-Genehmigungen nicht aus kanal-lokalem Zustand erraten oder umschreiben.
- Verschiedene Genehmigungsarten können absichtlich unterschiedliche native Oberflächen bereitstellen.
Aktuelle gebündelte Beispiele:
- Slack hält natives Genehmigungs-Routing sowohl für Exec- als auch für Plugin-IDs verfügbar.
- Matrix behält dasselbe native DM-/Kanal-Routing und dieselbe Reaktions-UX für Exec- und Plugin-Genehmigungen bei, lässt Auth jedoch weiterhin je nach Genehmigungsart unterschiedlich sein.
createApproverRestrictedNativeApprovalAdapterexistiert weiterhin als Kompatibilitäts-Wrapper, neuer Code sollte jedoch den Capability-Builder bevorzugen undapprovalCapabilityauf dem Plugin bereitstellen.
openclaw/plugin-sdk/approval-auth-runtimeopenclaw/plugin-sdk/approval-client-runtimeopenclaw/plugin-sdk/approval-delivery-runtimeopenclaw/plugin-sdk/approval-gateway-runtimeopenclaw/plugin-sdk/approval-handler-adapter-runtimeopenclaw/plugin-sdk/approval-handler-runtimeopenclaw/plugin-sdk/approval-native-runtimeopenclaw/plugin-sdk/approval-reply-runtimeopenclaw/plugin-sdk/channel-runtime-context
openclaw/plugin-sdk/setup-runtime,
openclaw/plugin-sdk/setup-adapter-runtime,
openclaw/plugin-sdk/reply-runtime,
openclaw/plugin-sdk/reply-dispatch-runtime,
openclaw/plugin-sdk/reply-reference und
openclaw/plugin-sdk/reply-chunking, wenn Sie die breitere
Oberfläche nicht benötigen.
Speziell für Setup:
openclaw/plugin-sdk/setup-runtimedeckt die laufzeitsicheren Setup-Helfer ab: import-sichere Setup-Patch-Adapter (createPatchedAccountSetupAdapter,createEnvPatchedAccountSetupAdapter,createSetupInputPresenceValidator), Ausgabe von Lookup-Hinweisen,promptResolvedAllowFrom,splitSetupEntriesund die delegierten Setup-Proxy-Builderopenclaw/plugin-sdk/setup-adapter-runtimeist die schmale, env-bewusste Adapter- Schnittstelle fürcreateEnvPatchedAccountSetupAdapteropenclaw/plugin-sdk/channel-setupdeckt die Setup-Builder für optionale Installationen sowie einige setup-sichere Primitive ab:createOptionalChannelSetupSurface,createOptionalChannelSetupAdapter,
channelEnvVars. Behalten Sie Runtime-envVars des Kanals oder lokale
Konstanten nur für operatorseitige Texte bei.
createOptionalChannelSetupWizard, DEFAULT_ACCOUNT_ID,
createTopLevelChannelDmPolicy, setSetupChannelEnabled und
splitSetupEntries
- verwenden Sie die breitere Schnittstelle
openclaw/plugin-sdk/setupnur dann, wenn Sie auch die schwergewichtigeren gemeinsam genutzten Setup-/Konfigurationshelfer benötigen, etwamoveSingleAccountChannelSectionToDefaultAccount(...)
createOptionalChannelSetupSurface(...). Der generierte
Adapter/Assistent schlägt bei Konfigurationsschreibvorgängen und Finalisierung fail-closed fehl und verwendet
dieselbe Meldung „Installation erforderlich“ für Validierung, Finalisierung und Docs-Link-Text.
Für andere Hot-Channel-Pfade sollten Sie die schmalen Helfer gegenüber breiteren Legacy-
Oberflächen bevorzugen:
openclaw/plugin-sdk/account-core,openclaw/plugin-sdk/account-id,openclaw/plugin-sdk/account-resolutionundopenclaw/plugin-sdk/account-helpersfür Multi-Account-Konfiguration und Fallback auf das Standardkontoopenclaw/plugin-sdk/inbound-envelopeundopenclaw/plugin-sdk/inbound-reply-dispatchfür die Verkabelung von eingehender Route/Envelope sowie Record-and-Dispatchopenclaw/plugin-sdk/messaging-targetsfür Ziel-Parsing/-Matchingopenclaw/plugin-sdk/outbound-mediaundopenclaw/plugin-sdk/outbound-runtimefür Medienladen sowie Delegates für ausgehende Identität/Sendenopenclaw/plugin-sdk/thread-bindings-runtimefür den Thread-Binding-Lifecycle und die Adapter-Registrierungopenclaw/plugin-sdk/agent-media-payloadnur dann, wenn weiterhin ein Legacy-Agent-/Media- Payload-Feldlayout erforderlich istopenclaw/plugin-sdk/telegram-command-configfür die Normalisierung benutzerdefinierter Telegram-Befehle, Validierung von Duplikaten/Konflikten und einen fallback-stabilen Vertrag für Befehls- Konfiguration
Richtlinie für eingehende Erwähnungen
Halten Sie die Behandlung eingehender Erwähnungen in zwei Schichten getrennt:- plugin-eigene Sammlung von Belegen
- gemeinsam genutzte Richtlinienauswertung
openclaw/plugin-sdk/channel-inbound für die gemeinsam genutzte Schicht.
Geeignet für plugin-lokale Logik:
- Erkennung von Antworten an den Bot
- Erkennung von Zitaten des Bots
- Prüfungen auf Thread-Beteiligung
- Ausschlüsse von Service-/Systemnachrichten
- plattformspezifische Caches, die nötig sind, um die Beteiligung des Bots nachzuweisen
requireMention- explizites Erwähnungsergebnis
- Allowlist für implizite Erwähnungen
- Umgehung für Befehle
- endgültige Überspringen-Entscheidung
- Lokale Erwähnungsfakten berechnen.
- Diese Fakten an
resolveInboundMentionDecision({ facts, policy })übergeben. decision.effectiveWasMentioned,decision.shouldBypassMentionunddecision.shouldSkipin Ihrer Inbound-Gate-Logik verwenden.
api.runtime.channel.mentions stellt dieselben gemeinsam genutzten Erwähnungshelfer für
gebündelte Kanal-Plugins bereit, die bereits von Laufzeit-Injektion abhängen:
buildMentionRegexesmatchesMentionPatternsmatchesMentionWithExplicitimplicitMentionKindWhenresolveInboundMentionDecision
resolveMentionGating* bleiben auf
openclaw/plugin-sdk/channel-inbound nur als Kompatibilitäts-Exporte erhalten. Neuer Code
sollte resolveInboundMentionDecision({ facts, policy }) verwenden.
Schritt-für-Schritt-Anleitung
Paket und Manifest
Erstellen Sie die Standarddateien des Plugins. Das Feld
channel in package.json
macht dies zu einem Kanal-Plugin. Die vollständige Oberfläche der Paketmetadaten finden Sie
unter Plugin Setup and Config:Das Kanal-Plugin-Objekt erstellen
Die Schnittstelle
ChannelPlugin hat viele optionale Adapter-Oberflächen. Beginnen Sie mit
dem Minimum — id und setup — und fügen Sie Adapter nach Bedarf hinzu.Erstellen Sie src/channel.ts:src/channel.ts
Was createChatChannelPlugin für Sie übernimmt
Was createChatChannelPlugin für Sie übernimmt
Statt Low-Level-Adapter-Schnittstellen manuell zu implementieren, übergeben Sie
deklarative Optionen, und der Builder setzt sie zusammen:
Sie können auch rohe Adapter-Objekte statt der deklarativen Optionen übergeben,
wenn Sie vollständige Kontrolle benötigen.
| Option | Was verkabelt wird |
|---|---|
security.dm | Auf Konfigurationsfeldern basierender, bereichsbezogener DM-Sicherheits-Resolver |
pairing.text | Textbasierter DM-Kopplungsablauf mit Code-Austausch |
threading | Resolver für Reply-Modus (fest, kontoabhängig oder benutzerdefiniert) |
outbound.attachedResults | Sendefunktionen, die Ergebnis-Metadaten zurückgeben (Nachrichten-IDs) |
Den Einstiegspunkt verdrahten
Erstellen Sie Legen Sie kanalinterne CLI-Deskriptoren in
index.ts:index.ts
registerCliMetadata(...) ab, damit OpenClaw
sie in der Root-Hilfe anzeigen kann, ohne die vollständige Kanal-Laufzeit zu aktivieren,
während normale vollständige Ladevorgänge dieselben Deskriptoren weiterhin für die echte Befehls-
Registrierung übernehmen. Behalten Sie registerFull(...) für reine Laufzeitarbeit bei.
Wenn registerFull(...) Gateway-RPC-Methoden registriert, verwenden Sie ein
pluginspezifisches Präfix. Core-Admin-Namespaces (config.*,
exec.approvals.*, wizard.*, update.*) bleiben reserviert und werden immer
zu operator.admin aufgelöst.
defineChannelPluginEntry übernimmt die Aufteilung nach Registrierungsmodus automatisch. Alle
Optionen finden Sie unter Entry Points.Einen Setup-Eintrag hinzufügen
Erstellen Sie OpenClaw lädt dies statt des vollständigen Einstiegspunkts, wenn der Kanal deaktiviert
oder nicht konfiguriert ist. Dadurch wird vermieden, während Setup-Abläufen
schwergewichtigen Laufzeitcode zu laden. Einzelheiten finden Sie unter Setup and Config.
setup-entry.ts für leichtgewichtiges Laden während des Onboardings:setup-entry.ts
Eingehende Nachrichten verarbeiten
Ihr Plugin muss Nachrichten von der Plattform empfangen und an
OpenClaw weiterleiten. Das typische Muster ist ein Webhook, der die Anfrage verifiziert und
sie durch den Inbound-Handler Ihres Kanals weiterleitet:
Die Verarbeitung eingehender Nachrichten ist kanalspezifisch. Jedes Kanal-Plugin besitzt
seine eigene Inbound-Pipeline. Sehen Sie sich gebündelte Kanal-Plugins an
(zum Beispiel das Plugin-Paket für Microsoft Teams oder Google Chat), um reale Muster zu sehen.
Testen
Schreiben Sie colocated Tests in Gemeinsam genutzte Testhelfer finden Sie unter Testing.
src/channel.test.ts:src/channel.test.ts
Dateistruktur
Fortgeschrittene Themen
Threading-Optionen
Feste, kontoabhängige oder benutzerdefinierte Reply-Modi
Integration des Message-Tools
describeMessageTool und Action Discovery
Zielauflösung
inferTargetChatType, looksLikeId, resolveTarget
Laufzeithelfer
TTS, STT, Medien, Subagent über api.runtime
Einige gebündelte Hilfs-Schnittstellen existieren weiterhin für die Wartung gebündelter Plugins und
für Kompatibilität. Sie sind nicht das empfohlene Muster für neue Kanal-Plugins;
bevorzugen Sie die generischen Unterpfade channel/setup/reply/runtime aus der gemeinsamen SDK-
Oberfläche, sofern Sie nicht direkt diese gebündelte Plugin-Familie warten.
Nächste Schritte
- Provider Plugins — wenn Ihr Plugin auch Modelle bereitstellt
- SDK Overview — vollständige Referenz für Subpath-Importe
- SDK Testing — Test-Utilities und Vertragstests
- Plugin Manifest — vollständiges Manifest-Schema