Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

WhatsApp

Connect OpenCrabs to WhatsApp via QR code pairing.

Setup

Configure via the Onboarding Wizard

Run /onboard:channels (or /onboard and navigate to the Channels step):

  1. Use / to focus WhatsApp
  2. Press Space to toggle it on
  3. Press Enter to open the WhatsApp setup screen
  4. The setup screen has two fields:
    • Connection — shows the QR code or connection status
    • Phone Allowlist — comma-separated phone numbers in E.164 format (e.g. +15551234567). Leave empty to accept all messages.
  5. When not yet paired, a QR code appears in the terminal:
    • Open WhatsApp on your phone → Settings → Linked Devices → Link a Device
    • Scan the QR code
    • The status updates to “Connected” automatically
  6. When already paired, press R on the Connection field to reset and re-pair
  7. Press Enter to save

The pairing session persists across restarts — no need to re-scan.

Manual Configuration (advanced)

# config.toml
[channels.whatsapp]
enabled = true
allowed_phones = ["+15551234567"]

Configuration

WhatsApp options live under [channels.whatsapp] in ~/.opencrabs/config.toml:

[channels.whatsapp]
enabled = true
allowed_phones = ["+15551234567"]      # E.164 format
session_idle_hours = 24.0              # idle timeout for non-owner sessions
FieldDefaultDescription
enabledfalseEnable the WhatsApp channel
allowed_phones[] (open replies under auto, but never owner rights)E.164 phone numbers. Since v0.5.1 an empty list no longer makes every sender the bot owner — owner commands (/evolve, /rebuild, /exit, /cd) and approval answers need the self-chat, bot_owner, or the resolver over bot_owner + allowed_phones
session_idle_hoursNone (no timeout)Idle timeout for non-owner sessions. Owner sessions never expire
response_policy"auto"Who the bot responds to. auto: reply to all while there is at most one active sender, then switch to mention-only once a second unique sender appears. owner_only: only the bot owner. allowlist: only allowed phones. open: everyone
bot_ownerNone (auto-seeded from allowed_phones[0])Phone number of the bot owner in E.164 format. The owner gets access that other allowlisted users do not. Commands that expose personal data or the host system are owner-only

How it works

One account per instance. Each OpenCrabs instance supports one WhatsApp account (one companion device). You run the bot AS whatever account you scan: your own number (talk via “Message Yourself”), or any other number you own, including a WhatsApp Business account.

The bot talks to itself. If you message the bot’s own paired number, the bot replies to you. This is by design. The paired account’s self-chat is always allowed, regardless of response_policy or allowed_phones.

Allowlist behavior. Anyone messaging the paired number who is on the allowed_phones list gets a reply. The response_policy controls who else can interact beyond the allowlist.

Ownership (v0.5.1, deny-by-default). Before v0.5.1 an empty allowed_phones under response_policy = "auto" answered every contact and elevated them all to owner — one forgotten allowlist away from handing strangers /evolve and /cd. That elevation is gone: being answered no longer means being in charge. Owner status comes from the paired account’s self-chat, a configured bot_owner, or ownership resolution over allowed_phones + bot_owner — never from an empty list. Tool-approval replies (Yes/Always/No/YOLO) resolve only for the owner on all four channels.

  • Personal and group chats — Works in DMs and group conversations
  • Image support — Send and receive images
  • Voice messages — STT transcription + TTS response
  • Plain text UI — No buttons (WhatsApp limitation), uses text-based menus
  • Slash commands — All built-in and custom commands work

Outbound rate limiting

WhatsApp is the channel with the heaviest ban consequences, so every outbound send goes through a budget (since v0.5.1):

[channels.whatsapp.rate_limit]
messages_per_minute = 30   # token bucket: sustained sends per minute
daily_cap = 800            # rolling 24h hard cap
MechanismBehavior
Per-minute pacingA token bucket sized to messages_per_minute (default 30) refills continuously. An over-budget send is paced, not dropped: the caller sleeps for the refill gap and then sends. Set 0 to disable pacing.
Rolling daily capThe 24h window allows daily_cap sends (default 800). On saturation further sends park in a FIFO queue; a background drainer flushes them as the window slides. A queued quote-reply loses its quote context — the text still arrives. Set 0 to disable the cap.
Owner alertThe first send queued in a saturation episode alerts the bot owner exactly once (through the WhatsApp session), and the alert re-arms when traffic drops back under the cap.
Owner bypassMessages addressed to the owner skip budget consumption entirely, so you always get fast replies; the saturation alert itself is also exempt.

Streaming answers used to post every chunk as its own message — exactly the volume pattern Meta’s heuristics hunt. Outbound replies now edit one message in place (since v0.5.1), which keeps chunked turns well inside the budget; the limiter is the safety net underneath.

Formatting Notes

  • No markdown tables — use bullet lists
  • No headers — use bold or CAPS for emphasis
  • Links render natively

Voice Message Handling

When receiving a voice message:

  1. Agent downloads and transcribes via STT
  2. Sends text response first (searchable)
  3. Optionally generates TTS audio response

Features

  • Personal and group chats — Works in DMs and group conversations
  • Image support — Send and receive images
  • Voice messages — STT transcription + TTS response
  • Plain text UI — No buttons (WhatsApp limitation), uses text-based menus
  • Slash commands — All built-in and custom commands work

Troubleshooting

Wrong number replying

Each OpenCrabs instance supports one WhatsApp account (one companion device). If you connected multiple numbers or the wrong number is replying, you need a full reset. The bot always uses the last number you connected.

Critical: Always reset the connection before connecting a new number. OpenCrabs only keeps the last paired number.

Full reset steps:

  1. Remove ALL linked devices from WhatsApp. Open WhatsApp on your phone, go to Settings > Linked Devices, and remove every device in the list. Don’t bother hunting for the opencrabs one. A stale device left over from an earlier pairing is the usual reason the old number keeps replying, so the reliable fix is to clear them all and start fresh.
  2. Reset the connection in OpenCrabs — in the TUI or from a channel, go to /onboard:channels and press R to reset the WhatsApp connection. Wait for confirmation that the reset is complete.
  3. Re-pair from scratch — after the reset is confirmed, go to WhatsApp > Settings > Linked Devices > Link a Device and scan the new QR code shown by OpenCrabs.

If the bot still shows the old number after resetting, make sure you completed step 1 (removing the device from WhatsApp) before step 2.

Common issues

SymptomCauseFix
Old number still replyingA stale linked device is still pairedRemove ALL linked devices from WhatsApp > Settings > Linked Devices, then press R in /onboard:channels and re-pair
QR code doesn’t appearAgent is still connected (no restart triggered)Press R in /onboard:channels to force a restart, then wait for the new QR
Bot doesn’t reply to anyoneresponse_policy is too restrictiveSet response_policy = "allowlist" and add phone numbers to allowed_phones in config.toml
Bot replies to everyoneresponse_policy is openSet response_policy = "allowlist" or "owner_only" in config.toml
Bot doesn’t reply to self-chatallowed_phones doesn’t include the paired numberThe paired number’s self-chat is always allowed, regardless of allowed_phones. If it’s not working, check that response_policy isn’t too restrictive