Langsung ke konten utama

WhatsApp (Web channel)

Status: siap produksi melalui WhatsApp Web (Baileys). Gateway memiliki sesi tertaut.

Instal (sesuai kebutuhan)

  • Onboarding (openclaw onboard) dan openclaw channels add --channel whatsapp akan meminta Anda menginstal plugin WhatsApp saat pertama kali memilihnya.
  • openclaw channels login --channel whatsapp juga menawarkan alur instalasi saat plugin belum tersedia.
  • Dev channel + checkout git: default ke path plugin lokal.
  • Stable/Beta: default ke paket npm @openclaw/whatsapp.
Instalasi manual tetap tersedia:
openclaw plugins install @openclaw/whatsapp

Pairing

Kebijakan DM default adalah pairing untuk pengirim yang tidak dikenal.

Channel troubleshooting

Diagnostik lintas channel dan panduan perbaikan.

Gateway configuration

Pola dan contoh config channel lengkap.

Penyiapan cepat

1

Konfigurasikan kebijakan akses WhatsApp

{
  channels: {
    whatsapp: {
      dmPolicy: "pairing",
      allowFrom: ["+15551234567"],
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
    },
  },
}
2

Tautkan WhatsApp (QR)

openclaw channels login --channel whatsapp
Untuk akun tertentu:
openclaw channels login --channel whatsapp --account work
3

Mulai gateway

openclaw gateway
4

Setujui permintaan pairing pertama (jika menggunakan mode pairing)

openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
Permintaan pairing kedaluwarsa setelah 1 jam. Permintaan tertunda dibatasi hingga 3 per channel.
OpenClaw merekomendasikan menjalankan WhatsApp pada nomor terpisah jika memungkinkan. (Metadata channel dan alur penyiapan dioptimalkan untuk penyiapan tersebut, tetapi penyiapan nomor pribadi juga didukung.)

Pola deployment

Ini adalah mode operasional yang paling bersih:
  • identitas WhatsApp terpisah untuk OpenClaw
  • allowlist DM dan batas perutean yang lebih jelas
  • kemungkinan kebingungan obrolan sendiri yang lebih rendah
Pola kebijakan minimal:
{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"],
    },
  },
}
Onboarding mendukung mode nomor pribadi dan menulis baseline yang ramah obrolan sendiri:
  • dmPolicy: "allowlist"
  • allowFrom mencakup nomor pribadi Anda
  • selfChatMode: true
Dalam runtime, perlindungan obrolan sendiri bergantung pada nomor diri tertaut dan allowFrom.
Channel platform pesan berbasis WhatsApp Web (Baileys) dalam arsitektur channel OpenClaw saat ini.Tidak ada channel pesan Twilio WhatsApp terpisah dalam registry channel obrolan bawaan.

Model runtime

  • Gateway memiliki socket WhatsApp dan loop reconnect.
  • Pengiriman keluar memerlukan listener WhatsApp aktif untuk akun target.
  • Obrolan status dan siaran diabaikan (@status, @broadcast).
  • Obrolan langsung menggunakan aturan sesi DM (session.dmScope; default main menggabungkan DM ke sesi utama agen).
  • Sesi grup diisolasi (agent:<agentId>:whatsapp:group:<jid>).

Kontrol akses dan aktivasi

channels.whatsapp.dmPolicy mengontrol akses obrolan langsung:
  • pairing (default)
  • allowlist
  • open (memerlukan allowFrom untuk menyertakan "*")
  • disabled
allowFrom menerima nomor bergaya E.164 (dinormalisasi secara internal).Override multi-akun: channels.whatsapp.accounts.<id>.dmPolicy (dan allowFrom) lebih diprioritaskan daripada default tingkat channel untuk akun tersebut.Detail perilaku runtime:
  • pairing disimpan di allow-store channel dan digabungkan dengan allowFrom yang dikonfigurasi
  • jika tidak ada allowlist yang dikonfigurasi, nomor diri tertaut diizinkan secara default
  • DM keluar fromMe tidak pernah dipair otomatis

Perilaku nomor pribadi dan obrolan sendiri

Saat nomor diri tertaut juga ada di allowFrom, perlindungan obrolan sendiri WhatsApp aktif:
  • lewati tanda baca untuk giliran obrolan sendiri
  • abaikan perilaku pemicu otomatis mention-JID yang sebaliknya akan meming diri Anda sendiri
  • jika messages.responsePrefix tidak diatur, balasan obrolan sendiri default ke [{identity.name}] atau [openclaw]

Normalisasi pesan dan konteks

Pesan WhatsApp masuk dibungkus dalam envelope masuk bersama.Jika ada balasan kutipan, konteks ditambahkan dalam bentuk ini:
[Replying to <sender> id:<stanzaId>]
<quoted body or media placeholder>
[/Replying]
Bidang metadata balasan juga diisi jika tersedia (ReplyToId, ReplyToBody, ReplyToSender, sender JID/E.164).
Pesan masuk yang hanya berisi media dinormalisasi dengan placeholder seperti:
  • <media:image>
  • <media:video>
  • <media:audio>
  • <media:document>
  • <media:sticker>
Payload lokasi dan kontak dinormalisasi menjadi konteks tekstual sebelum perutean.
Untuk grup, pesan yang belum diproses dapat dibuffer dan disisipkan sebagai konteks saat bot akhirnya dipicu.
  • batas default: 50
  • config: channels.whatsapp.historyLimit
  • fallback: messages.groupChat.historyLimit
  • 0 menonaktifkan
Penanda injeksi:
  • [Chat messages since your last reply - for context]
  • [Current message - respond to this]
Tanda baca diaktifkan secara default untuk pesan WhatsApp masuk yang diterima.Nonaktifkan secara global:
{
  channels: {
    whatsapp: {
      sendReadReceipts: false,
    },
  },
}
Override per akun:
{
  channels: {
    whatsapp: {
      accounts: {
        work: {
          sendReadReceipts: false,
        },
      },
    },
  },
}
Giliran obrolan sendiri melewati tanda baca bahkan saat diaktifkan secara global.

Pengiriman, pemotongan, dan media

  • batas potongan default: channels.whatsapp.textChunkLimit = 4000
  • channels.whatsapp.chunkMode = "length" | "newline"
  • mode newline mengutamakan batas paragraf (baris kosong), lalu fallback ke pemotongan aman berdasarkan panjang
  • mendukung payload gambar, video, audio (PTT voice-note), dan dokumen
  • audio/ogg ditulis ulang menjadi audio/ogg; codecs=opus untuk kompatibilitas voice-note
  • pemutaran GIF animasi didukung melalui gifPlayback: true pada pengiriman video
  • caption diterapkan pada item media pertama saat mengirim payload balasan multi-media
  • sumber media dapat berupa HTTP(S), file://, atau path lokal
  • batas penyimpanan media masuk: channels.whatsapp.mediaMaxMb (default 50)
  • batas pengiriman media keluar: channels.whatsapp.mediaMaxMb (default 50)
  • override per akun menggunakan channels.whatsapp.accounts.<accountId>.mediaMaxMb
  • gambar dioptimalkan otomatis (resize/quality sweep) agar sesuai dengan batas
  • saat pengiriman media gagal, fallback item pertama mengirim peringatan teks alih-alih diam-diam membuang respons

Tingkat reaction

channels.whatsapp.reactionLevel mengontrol seberapa luas agen menggunakan reaction emoji di WhatsApp:
LevelReaction ackReaction yang dimulai agenDeskripsi
"off"TidakTidakTidak ada reaction sama sekali
"ack"YaTidakHanya reaction ack (tanda terima pra-balasan)
"minimal"YaYa (konservatif)Ack + reaction agen dengan panduan konservatif
"extensive"YaYa (didorong)Ack + reaction agen dengan panduan yang didorong
Default: "minimal". Override per akun menggunakan channels.whatsapp.accounts.<id>.reactionLevel.
{
  channels: {
    whatsapp: {
      reactionLevel: "ack",
    },
  },
}

Reaction acknowledgment

WhatsApp mendukung reaction ack segera saat penerimaan masuk melalui channels.whatsapp.ackReaction. Reaction ack dibatasi oleh reactionLevel — reaction ini ditekan saat reactionLevel adalah "off".
{
  channels: {
    whatsapp: {
      ackReaction: {
        emoji: "👀",
        direct: true,
        group: "mentions", // always | mentions | never
      },
    },
  },
}
Catatan perilaku:
  • dikirim segera setelah pesan masuk diterima (pra-balasan)
  • kegagalan dicatat dalam log tetapi tidak memblokir pengiriman balasan normal
  • mode grup mentions bereaksi pada giliran yang dipicu mention; aktivasi grup always bertindak sebagai bypass untuk pemeriksaan ini
  • WhatsApp menggunakan channels.whatsapp.ackReaction (messages.ackReaction legacy tidak digunakan di sini)

Multi-akun dan kredensial

  • id akun berasal dari channels.whatsapp.accounts
  • pemilihan akun default: default jika ada, jika tidak id akun pertama yang dikonfigurasi (diurutkan)
  • id akun dinormalisasi secara internal untuk lookup
  • path autentikasi saat ini: ~/.openclaw/credentials/whatsapp/<accountId>/creds.json
  • file cadangan: creds.json.bak
  • autentikasi default legacy di ~/.openclaw/credentials/ masih dikenali/dimigrasikan untuk alur akun default
openclaw channels logout --channel whatsapp [--account <id>] menghapus status autentikasi WhatsApp untuk akun tersebut.Dalam direktori autentikasi legacy, oauth.json dipertahankan sementara file autentikasi Baileys dihapus.

Alat, action, dan penulisan config

  • Dukungan alat agen mencakup action reaction WhatsApp (react).
  • Pembatasan action:
    • channels.whatsapp.actions.reactions
    • channels.whatsapp.actions.polls
  • Penulisan config yang dimulai channel diaktifkan secara default (nonaktifkan melalui channels.whatsapp.configWrites=false).

Pemecahan masalah

Gejala: status channel melaporkan belum tertaut.Perbaikan:
openclaw channels login --channel whatsapp
openclaw channels status
Gejala: akun tertaut dengan disconnect berulang atau upaya reconnect.Perbaikan:
openclaw doctor
openclaw logs --follow
Jika perlu, tautkan ulang dengan channels login.
Pengiriman keluar gagal cepat saat tidak ada listener gateway aktif untuk akun target.Pastikan gateway berjalan dan akun tertaut.
Periksa dalam urutan ini:
  • groupPolicy
  • groupAllowFrom / allowFrom
  • entri allowlist groups
  • pembatasan mention (requireMention + pola mention)
  • kunci duplikat di openclaw.json (JSON5): entri terakhir menggantikan entri sebelumnya, jadi gunakan satu groupPolicy per cakupan
Runtime gateway WhatsApp seharusnya menggunakan Node. Bun ditandai tidak kompatibel untuk operasi gateway WhatsApp/Telegram yang stabil.

Penunjuk referensi konfigurasi

Referensi utama: Bidang WhatsApp dengan sinyal tinggi:
  • akses: dmPolicy, allowFrom, groupPolicy, groupAllowFrom, groups
  • pengiriman: textChunkLimit, chunkMode, mediaMaxMb, sendReadReceipts, ackReaction, reactionLevel
  • multi-akun: accounts.<id>.enabled, accounts.<id>.authDir, override tingkat akun
  • operasi: configWrites, debounceMs, web.enabled, web.heartbeatSeconds, web.reconnect.*
  • perilaku sesi: session.dmScope, historyLimit, dmHistoryLimit, dms.<id>.historyLimit

Terkait