Membangun Plugin Channel
Panduan ini memandu Anda membangun plugin channel yang menghubungkan OpenClaw ke platform pesan. Pada akhirnya Anda akan memiliki channel yang berfungsi dengan keamanan DM, pairing, reply threading, dan pesan keluar.Jika Anda belum pernah membangun plugin OpenClaw sebelumnya, baca
Memulai terlebih dahulu untuk struktur paket
dasar dan penyiapan manifes.
Cara kerja plugin channel
Plugin channel tidak memerlukan tool send/edit/react mereka sendiri. OpenClaw menjaga satu toolmessage bersama di inti. Plugin Anda memiliki:
- Config — resolusi akun dan wizard penyiapan
- Security — kebijakan DM dan allowlist
- Pairing — alur persetujuan DM
- Session grammar — bagaimana id percakapan khusus provider dipetakan ke chat dasar, id thread, dan fallback parent
- Outbound — mengirim teks, media, dan polling ke platform
- Threading — bagaimana balasan di-thread
:thread: generik, dan dispatch.
Jika channel Anda menambahkan param message-tool yang membawa sumber media, tampilkan
nama param tersebut melalui describeMessageTool(...).mediaSourceParams. Inti menggunakan
daftar eksplisit itu untuk normalisasi path sandbox dan kebijakan akses media keluar,
sehingga plugin tidak memerlukan kasus khusus shared-core untuk
param avatar, lampiran, atau gambar sampul yang khusus provider.
Sebaiknya kembalikan map berindeks action seperti
{ "set-profile": ["avatarUrl", "avatarPath"] } agar action yang tidak terkait tidak
mewarisi argumen media milik action lain. Array datar tetap berfungsi untuk param yang
sengaja dibagikan di setiap action yang diekspos.
Jika platform Anda menyimpan cakupan tambahan di dalam id percakapan, simpan parsing itu
di plugin dengan messaging.resolveSessionConversation(...). Itu adalah hook kanonis
untuk memetakan rawId ke id percakapan dasar, id thread opsional,
baseConversationId eksplisit, dan parentConversationCandidates.
Saat Anda mengembalikan parentConversationCandidates, pertahankan urutannya dari
parent yang paling sempit ke percakapan parent/dasar yang paling luas.
Plugin bawaan yang memerlukan parsing yang sama sebelum registri channel aktif
juga dapat mengekspos file tingkat atas session-key-api.ts dengan ekspor
resolveSessionConversation(...) yang cocok. Inti menggunakan permukaan yang aman untuk bootstrap itu
hanya ketika registri plugin runtime belum tersedia.
messaging.resolveParentConversationCandidates(...) tetap tersedia sebagai
fallback kompatibilitas lama ketika plugin hanya memerlukan fallback parent di atas
id generik/raw. Jika kedua hook ada, inti menggunakan
resolveSessionConversation(...).parentConversationCandidates terlebih dahulu dan hanya
fallback ke resolveParentConversationCandidates(...) ketika hook kanonis
mengabaikannya.
Persetujuan dan capability channel
Sebagian besar plugin channel tidak memerlukan kode khusus persetujuan.- Inti memiliki
/approvechat yang sama, payload tombol persetujuan bersama, dan pengiriman fallback generik. - Sebaiknya gunakan satu objek
approvalCapabilitypada plugin channel ketika channel memerlukan perilaku khusus persetujuan. ChannelPlugin.approvalsdihapus. Letakkan fakta pengiriman/native/render/auth persetujuan diapprovalCapability.plugin.authhanya untuk login/logout; inti tidak lagi membaca hook auth persetujuan dari objek itu.approvalCapability.authorizeActorActiondanapprovalCapability.getActionAvailabilityStateadalah seam auth persetujuan kanonis.- Gunakan
approvalCapability.getActionAvailabilityStateuntuk ketersediaan auth persetujuan chat yang sama. - Jika channel Anda mengekspos persetujuan exec native, gunakan
approvalCapability.getExecInitiatingSurfaceStateuntuk status initiating-surface/native-client ketika berbeda dari auth persetujuan chat yang sama. Inti menggunakan hook khusus exec itu untuk membedakanenabledvsdisabled, memutuskan apakah channel pemicu mendukung persetujuan exec native, dan menyertakan channel itu dalam panduan fallback native-client.createApproverRestrictedNativeApprovalCapability(...)mengisi ini untuk kasus umum. - Gunakan
outbound.shouldSuppressLocalPayloadPromptatauoutbound.beforeDeliverPayloaduntuk perilaku siklus hidup payload khusus channel seperti menyembunyikan prompt persetujuan lokal duplikat atau mengirim indikator mengetik sebelum pengiriman. - Gunakan
approvalCapability.deliveryhanya untuk routing persetujuan native atau penekanan fallback. - Gunakan
approvalCapability.nativeRuntimeuntuk fakta persetujuan native milik channel. Jaga agar tetap lazy pada entrypoint channel yang panas dengancreateLazyChannelApprovalNativeRuntimeAdapter(...), yang dapat mengimpor modul runtime Anda sesuai kebutuhan sambil tetap membiarkan inti merakit siklus hidup persetujuan. - Gunakan
approvalCapability.renderhanya ketika channel benar-benar memerlukan payload persetujuan kustom alih-alih renderer bersama. - Gunakan
approvalCapability.describeExecApprovalSetupketika channel ingin balasan jalur nonaktif menjelaskan knob config tepat yang dibutuhkan untuk mengaktifkan persetujuan exec native. Hook menerima{ channel, channelLabel, accountId }; channel akun bernama harus merender path bercakupan akun sepertichannels.<channel>.accounts.<id>.execApprovals.*alih-alih default tingkat atas. - Jika channel dapat menyimpulkan identitas DM mirip pemilik yang stabil dari config yang ada, gunakan
createResolvedApproverActionAuthAdapterdariopenclaw/plugin-sdk/approval-runtimeuntuk membatasi/approvechat yang sama tanpa menambahkan logika inti khusus persetujuan. - Jika channel memerlukan pengiriman persetujuan native, jaga agar kode channel tetap fokus pada normalisasi target plus fakta transport/presentasi. Gunakan
createChannelExecApprovalProfile,createChannelNativeOriginTargetResolver,createChannelApproverDmTargetResolver, dancreateApproverRestrictedNativeApprovalCapabilitydariopenclaw/plugin-sdk/approval-runtime. Letakkan fakta khusus channel di balikapprovalCapability.nativeRuntime, idealnya melaluicreateChannelApprovalNativeRuntimeAdapter(...)ataucreateLazyChannelApprovalNativeRuntimeAdapter(...), sehingga inti dapat merakit handler dan memiliki pemfilteran request, routing, dedupe, kedaluwarsa, langganan gateway, dan pemberitahuan routed-elsewhere.nativeRuntimedibagi menjadi beberapa seam yang lebih kecil: availability— apakah akun dikonfigurasi dan apakah request harus ditanganipresentation— memetakan view model persetujuan bersama ke payload native pending/resolved/expired atau action finaltransport— menyiapkan target plus mengirim/memperbarui/menghapus pesan persetujuan nativeinteractions— hook bind/unbind/clear-action opsional untuk tombol atau reaksi nativeobserve— hook diagnostik pengiriman opsional- Jika channel memerlukan objek milik runtime seperti klien, token, aplikasi Bolt, atau penerima webhook, daftarkan objek itu melalui
openclaw/plugin-sdk/channel-runtime-context. Registri runtime-context generik memungkinkan inti melakukan bootstrap handler berbasis capability dari status startup channel tanpa menambahkan glue wrapper khusus persetujuan. - Gunakan
createChannelApprovalHandlerataucreateChannelNativeApprovalRuntimetingkat lebih rendah hanya ketika seam berbasis capability belum cukup ekspresif. - Channel persetujuan native harus merutekan
accountIddanapprovalKindmelalui helper tersebut.accountIdmenjaga kebijakan persetujuan multi-akun tetap bercakupan ke akun bot yang benar, danapprovalKindmenjaga perilaku persetujuan exec vs plugin tetap tersedia bagi channel tanpa cabang hardcoded di inti. - Inti kini juga memiliki pemberitahuan pengalihan persetujuan. Plugin channel tidak boleh mengirim pesan tindak lanjut mereka sendiri seperti “persetujuan dikirim ke DM / channel lain” dari
createChannelNativeApprovalRuntime; sebaliknya, tampilkan routing DM origin + approver yang akurat melalui helper capability persetujuan bersama dan biarkan inti mengagregasi pengiriman aktual sebelum memposting pemberitahuan kembali ke chat pemicu. - Pertahankan jenis id persetujuan yang dikirim dari awal sampai akhir. Klien native tidak boleh menebak atau menulis ulang routing persetujuan exec vs plugin dari status lokal channel.
- Jenis persetujuan yang berbeda dapat dengan sengaja mengekspos permukaan native yang berbeda.
Contoh bawaan saat ini:
- Slack menjaga routing persetujuan native tetap tersedia untuk id exec maupun plugin.
- Matrix menjaga routing DM/channel native dan UX reaksi yang sama untuk persetujuan exec dan plugin, sambil tetap memungkinkan auth berbeda menurut jenis persetujuan.
createApproverRestrictedNativeApprovalAdaptermasih ada sebagai wrapper kompatibilitas, tetapi kode baru sebaiknya menggunakan builder capability dan mengeksposapprovalCapabilitypada plugin.
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, dan
openclaw/plugin-sdk/reply-chunking ketika Anda tidak memerlukan
permukaan umbrella yang lebih luas.
Khusus untuk setup:
openclaw/plugin-sdk/setup-runtimemencakup helper setup yang aman untuk runtime: adapter patch setup yang aman diimpor (createPatchedAccountSetupAdapter,createEnvPatchedAccountSetupAdapter,createSetupInputPresenceValidator), output lookup-note,promptResolvedAllowFrom,splitSetupEntries, dan builder setup-proxy terdelegasiopenclaw/plugin-sdk/setup-adapter-runtimeadalah seam adapter sempit yang sadar env untukcreateEnvPatchedAccountSetupAdapteropenclaw/plugin-sdk/channel-setupmencakup builder setup opsional-install ditambah beberapa primitif yang aman untuk setup:createOptionalChannelSetupSurface,createOptionalChannelSetupAdapter,
channelEnvVars. Simpan envVars runtime channel atau konstanta lokal untuk salinan yang ditujukan kepada operator saja.
createOptionalChannelSetupWizard, DEFAULT_ACCOUNT_ID,
createTopLevelChannelDmPolicy, setSetupChannelEnabled, dan
splitSetupEntries
- gunakan seam
openclaw/plugin-sdk/setupyang lebih luas hanya ketika Anda juga memerlukan helper setup/config bersama yang lebih berat sepertimoveSingleAccountChannelSectionToDefaultAccount(...)
createOptionalChannelSetupSurface(...). Adapter/wizard yang dihasilkan gagal tertutup pada penulisan config dan finalisasi, dan menggunakan ulang pesan install-required yang sama di seluruh validasi, finalisasi, dan salinan tautan docs.
Untuk jalur channel panas lainnya, sebaiknya gunakan helper sempit alih-alih
permukaan lama yang lebih luas:
openclaw/plugin-sdk/account-core,openclaw/plugin-sdk/account-id,openclaw/plugin-sdk/account-resolution, danopenclaw/plugin-sdk/account-helpersuntuk config multi-akun dan fallback akun defaultopenclaw/plugin-sdk/inbound-envelopedanopenclaw/plugin-sdk/inbound-reply-dispatchuntuk wiring route/envelope inbound dan record-and-dispatchopenclaw/plugin-sdk/messaging-targetsuntuk parsing/pencocokan targetopenclaw/plugin-sdk/outbound-mediadanopenclaw/plugin-sdk/outbound-runtimeuntuk pemuatan media plus delegasi identitas/kirim keluar dan perencanaan payloadopenclaw/plugin-sdk/thread-bindings-runtimeuntuk siklus hidup thread-binding dan pendaftaran adapteropenclaw/plugin-sdk/agent-media-payloadhanya ketika tata letak field payload agen/media lama masih diperlukanopenclaw/plugin-sdk/telegram-command-configuntuk normalisasi custom-command Telegram, validasi duplikat/konflik, dan kontrak config perintah yang stabil sebagai fallback
Kebijakan mention inbound
Pertahankan penanganan mention inbound tetap terpisah dalam dua lapisan:- pengumpulan bukti milik plugin
- evaluasi kebijakan bersama
openclaw/plugin-sdk/channel-mention-gating untuk keputusan kebijakan mention.
Gunakan openclaw/plugin-sdk/channel-inbound hanya ketika Anda memerlukan barrel helper inbound
yang lebih luas.
Cocok untuk logika lokal plugin:
- deteksi balasan-ke-bot
- deteksi kutipan-bot
- pemeriksaan partisipasi thread
- pengecualian pesan layanan/sistem
- cache native platform yang diperlukan untuk membuktikan partisipasi bot
requireMention- hasil mention eksplisit
- allowlist mention implisit
- bypass perintah
- keputusan skip final
- Hitung fakta mention lokal.
- Oper fakta tersebut ke
resolveInboundMentionDecision({ facts, policy }). - Gunakan
decision.effectiveWasMentioned,decision.shouldBypassMention, dandecision.shouldSkipdi gerbang inbound Anda.
api.runtime.channel.mentions mengekspos helper mention bersama yang sama untuk
plugin channel bawaan yang sudah bergantung pada injeksi runtime:
buildMentionRegexesmatchesMentionPatternsmatchesMentionWithExplicitimplicitMentionKindWhenresolveInboundMentionDecision
implicitMentionKindWhen dan
resolveInboundMentionDecision, impor dari
openclaw/plugin-sdk/channel-mention-gating untuk menghindari memuat helper runtime inbound lain yang tidak terkait.
Helper lama resolveMentionGating* tetap ada di
openclaw/plugin-sdk/channel-inbound hanya sebagai ekspor kompatibilitas. Kode baru
sebaiknya menggunakan resolveInboundMentionDecision({ facts, policy }).
Panduan langkah demi langkah
Paket dan manifes
Buat file plugin standar. Field
channel di package.json adalah
yang menjadikan ini plugin channel. Untuk permukaan metadata paket lengkap,
lihat Penyiapan dan Config Plugin:Bangun objek plugin channel
Antarmuka
ChannelPlugin memiliki banyak permukaan adaptor opsional. Mulailah dengan
yang minimum — id dan setup — lalu tambahkan adaptor sesuai kebutuhan.Buat src/channel.ts:src/channel.ts
Apa yang dilakukan createChatChannelPlugin untuk Anda
Apa yang dilakukan createChatChannelPlugin untuk Anda
Alih-alih mengimplementasikan antarmuka adaptor tingkat rendah secara manual, Anda meneruskan
opsi deklaratif dan builder akan menyusunnya:
Anda juga dapat meneruskan objek adaptor mentah alih-alih opsi deklaratif
jika memerlukan kontrol penuh.
| Option | What it wires |
|---|---|
security.dm | Resolver keamanan DM bercakupan dari field config |
pairing.text | Alur pairing DM berbasis teks dengan pertukaran kode |
threading | Resolver mode reply-to (tetap, bercakupan akun, atau kustom) |
outbound.attachedResults | Fungsi kirim yang mengembalikan metadata hasil (ID pesan) |
Hubungkan entry point
Buat Letakkan descriptor CLI milik channel di
index.ts:index.ts
registerCliMetadata(...) agar OpenClaw
dapat menampilkannya di bantuan root tanpa mengaktifkan runtime channel penuh,
sementara muatan penuh normal tetap mengambil descriptor yang sama untuk pendaftaran
perintah nyata. Pertahankan registerFull(...) untuk pekerjaan yang hanya runtime.
Jika registerFull(...) mendaftarkan metode gateway RPC, gunakan
prefix khusus plugin. Namespace admin inti (config.*,
exec.approvals.*, wizard.*, update.*) tetap dicadangkan dan selalu
di-resolve ke operator.admin.
defineChannelPluginEntry menangani pemisahan mode registrasi secara otomatis. Lihat
Entry Points untuk semua
opsi.Tambahkan entri setup
Buat OpenClaw memuat ini alih-alih entri penuh saat channel dinonaktifkan
atau belum dikonfigurasi. Ini menghindari menarik kode runtime berat selama alur setup.
Lihat Setup dan Config untuk detail.Channel workspace bawaan yang memisahkan ekspor aman-setup ke modul sidecar
dapat menggunakan
setup-entry.ts untuk pemuatan ringan selama onboarding:setup-entry.ts
defineBundledChannelSetupEntry(...) dari
openclaw/plugin-sdk/channel-entry-contract ketika juga memerlukan
setter runtime eksplisit saat setup.Tangani pesan inbound
Plugin Anda perlu menerima pesan dari platform dan meneruskannya ke
OpenClaw. Pola yang umum adalah webhook yang memverifikasi request dan
mendispatch-nya melalui handler inbound channel Anda:
Penanganan pesan inbound bersifat khusus channel. Setiap plugin channel memiliki
pipeline inbound-nya sendiri. Lihat plugin channel bawaan
(misalnya paket plugin Microsoft Teams atau Google Chat) untuk pola nyata.
Uji
Tulis test yang diletakkan berdampingan di Untuk helper test bersama, lihat Testing.
src/channel.test.ts:src/channel.test.ts
Struktur file
Topik lanjutan
Opsi threading
Mode balasan tetap, bercakupan akun, atau kustom
Integrasi tool message
describeMessageTool dan penemuan action
Resolusi target
inferTargetChatType, looksLikeId, resolveTarget
Helper runtime
TTS, STT, media, subagen melalui api.runtime
Beberapa seam helper bawaan masih ada untuk pemeliharaan plugin bawaan dan
kompatibilitas. Itu bukan pola yang disarankan untuk plugin channel baru;
sebaiknya gunakan subpath channel/setup/reply/runtime generik dari permukaan SDK
umum kecuali Anda memang memelihara keluarga plugin bawaan itu secara langsung.
Langkah berikutnya
- Plugin Provider — jika plugin Anda juga menyediakan model
- Ringkasan SDK — referensi impor subpath lengkap
- SDK Testing — utilitas test dan test kontrak
- Manifes Plugin — skema manifes lengkap