Skip to main content
Mibyan connects to WhatsApp through a built-in bridge based on Baileys. This works by emulating a WhatsApp Web session — not through the official WhatsApp Business API. No Meta developer account or Business verification is required.
Run mibyan gateway setup and pick WhatsApp for a guided walk-through.
Two WhatsApp integrationsThis page is for the Baileys bridge — quick to set up, personal accounts, no public URL needed, ban risk.If you’re running a real business bot and want stability, see the WhatsApp Business Cloud API guide instead. It’s the official Meta-supported path: no account ban risk, but requires a Meta Business account and a public webhook URL.The two adapters can also run in parallel against different phone numbers if you have a reason to.
Unofficial API — Ban RiskWhatsApp does not officially support third-party bots outside the Business API. Using a third-party bridge carries a small risk of account restrictions. To minimize risk:
  • Use a dedicated phone number for the bot (not your personal number)
  • Don’t send bulk/spam messages — keep usage conversational
  • Don’t automate outbound messaging to people who haven’t messaged first
WhatsApp Web Protocol UpdatesWhatsApp periodically updates their Web protocol, which can temporarily break compatibility with third-party bridges. When this happens, Mibyan will update the bridge dependency. If the bot stops working after a WhatsApp update, pull the latest Mibyan version and re-pair.

Two Modes


Prerequisites

  • Node.js v18+ and npm — the WhatsApp bridge runs as a Node.js process
  • A phone with WhatsApp installed (for scanning the QR code)
Unlike older browser-driven bridges, the current Baileys-based bridge does not require a local Chromium or Puppeteer dependency stack.

Step 1: Run the Setup Wizard

The wizard will:
  1. Ask which mode you want (bot or self-chat)
  2. Install bridge dependencies if needed
  3. Display a QR code in your terminal
  4. Wait for you to scan it
To scan the QR code:
  1. Open WhatsApp on your phone
  2. Go to Settings → Linked Devices
  3. Tap Link a Device
  4. Point your camera at the terminal QR code
Once paired, the wizard confirms the connection and exits. Your session is saved automatically.
If the QR code looks garbled, make sure your terminal is at least 60 columns wide and supports Unicode. You can also try a different terminal emulator.

Step 2: Getting a Second Phone Number (Bot Mode)

For bot mode, you need a phone number that isn’t already registered with WhatsApp. Three options: After getting the number:
  1. Install WhatsApp on a phone (or use WhatsApp Business app with dual-SIM)
  2. Register the new number with WhatsApp
  3. Run mibyan whatsapp and scan the QR code from that WhatsApp account

Step 3: Configure Mibyan

Add the following to your ~/.mibyan/.env file:
Allow-all shorthandSetting WHATSAPP_ALLOWED_USERS=* allows all senders (equivalent to WHATSAPP_ALLOW_ALL_USERS=true). This is consistent with Signal group allowlists. To use the pairing flow instead, remove both variables and rely on the DM pairing system.
Optional behavior settings in ~/.mibyan/config.yaml:
  • unauthorized_dm_behavior: pair is the global default. Unknown DM senders get a pairing code.
  • whatsapp.unauthorized_dm_behavior: ignore makes WhatsApp stay silent for unauthorized DMs, which is usually the better choice for a private number.

Group chats (bot mode)

Groups are gated by group policy, not by the DM allowlist. WHATSAPP_GROUP_POLICY / whatsapp.group_policy defaults to pairing, which forwards nothing from groups. allowlist plus WHATSAPP_GROUP_ALLOWED_USERS / whatsapp.group_allow_from (comma-separated group JIDs, e.g. 120363001234567890@g.us) admits the listed groups; open admits every group the bot is a member of. The sender is then checked like any other gateway principal: with WHATSAPP_ALLOWED_USERS set, a participant must be on it (or paired) — a sender WhatsApp addresses by LID matches through the phone number Baileys supplies alongside it, so a first contact with no lid-mapping file yet is not dropped; with no sender allowlist, allowlist trusts the group-JID list alone and admits every participant of a listed group, while open still needs the participant paired or WHATSAPP_ALLOW_ALL_USERS=true. By default the bot answers every admitted group message; set require_mention: true / WHATSAPP_REQUIRE_MENTION=true to answer only @mentions, replies to the bot, or /commands (groups in free_response_chats are exempt). Then start the gateway:
The gateway starts the WhatsApp bridge automatically using the saved session.

Session Persistence

The Baileys bridge saves its session under ~/.mibyan/platforms/whatsapp/session. This means:
  • Sessions survive restarts — you don’t need to re-scan the QR code every time
  • The session data includes encryption keys and device credentials
  • Do not share or commit this session directory — it grants full access to the WhatsApp account

Re-pairing

If the session breaks (phone reset, WhatsApp update, manually unlinked), you’ll see connection errors in the gateway logs. To fix it:
This generates a fresh QR code. Scan it again and the session is re-established. The gateway handles temporary disconnections (network blips, phone going offline briefly) automatically with reconnection logic.

Voice Messages

Mibyan supports voice on WhatsApp:
  • Incoming: Voice messages (.ogg opus) are automatically transcribed using the configured STT provider: local faster-whisper, Groq Whisper (GROQ_API_KEY), or OpenAI Whisper (VOICE_TOOLS_OPENAI_KEY)
  • Outgoing: TTS responses are sent as MP3 audio file attachments
  • Agent responses are prefixed with ”☤ Mibyan” by default. You can customize or disable this in config.yaml:
When send_read_receipts is true, the adapter marks policy-accepted inbound messages as read after DM/group/mention filtering passes. Rejected messages (e.g., from non-allowlisted senders) are not marked read. Disabled by default for privacy. Changing this setting automatically restarts the bridge subprocess on the next connection.

Message Formatting & Delivery

WhatsApp supports streaming (progressive) responses — the bot edits its message in real-time as the AI generates text, just like Discord and Telegram. Internally, WhatsApp is classified as a TIER_MEDIUM platform for delivery capabilities.

Chunking

Long responses are automatically split into multiple messages at 4,096 characters per chunk (WhatsApp’s practical display limit). You don’t need to configure anything — the gateway handles splitting and sends chunks sequentially.

WhatsApp-Compatible Markdown

Standard Markdown in AI responses is automatically converted to WhatsApp’s native formatting: Code blocks and inline code are preserved as-is since WhatsApp supports triple-backtick formatting natively.

Tool Progress

When the agent calls tools (web search, file operations, etc.), WhatsApp displays real-time progress indicators showing which tool is running. This is enabled by default — no configuration needed.

Native Polls, Clarify-as-Poll, and Locations

The Baileys-bridge adapter (bot mode) supports several native WhatsApp message types:
  • Polls — the agent can send a native WhatsApp poll (question + options) via the bridge’s /send-poll endpoint. Poll votes flow back into the conversation.
  • Clarify questions as polls — when the agent asks a multiple-choice clarify question, it’s rendered as a native single-select poll; tapping an option answers the question. If the poll fails to send, the adapter falls back to a plain text question. Approval prompts are never mapped onto polls — polls are only used for genuine multiple-choice clarifies.
  • Location pins — the agent can send a native location pin (latitude/longitude, optional name/address) via /send-location, and incoming shared locations (including live locations) are delivered to the agent as location messages.
All of this works out of the box in bot (Baileys) mode; no configuration needed.

Message Batching (Debounce)

WhatsApp delivers each message individually, so a rapid burst (forwarded batches, paste-splits, multi-line text) would otherwise trigger a separate agent invocation per fragment — wasting tokens and producing several disjointed replies. The adapter buffers successive text messages from the same chat and dispatches them as one combined request after a short quiet period (default 0.3s, extended to 1s for very long fragments; capped at 2s / 4s). Tune via config.yaml:
Set text_batch_delay_seconds: 0 to dispatch each message immediately (disables batching).

Quoted Replies

Replying to (quoting) an earlier message gives the agent the quoted text as context. Quoting an image, voice note, video or document also attaches that file to the turn, so “what is this?” under a quoted image works — whether the attachment came from another person or from the bot itself (a cron-delivered chart, a generated image). WhatsApp only ships a thumbnail stub with a quote, so the file is resolved from the bridge’s download cache (inbound media, in-memory for the bridge’s lifetime) or from a local index of the bot’s own sends (last 1000 messages); quotes of anything older arrive without the attachment.

Troubleshooting


Security

Configure access control before going live. Set WHATSAPP_ALLOWED_USERS with specific phone numbers (including country code, without the +), use * to allow everyone, or set WHATSAPP_ALLOW_ALL_USERS=true. Without any of these, the gateway denies all incoming messages as a safety measure.
By default, unauthorized DMs still receive a pairing code reply. If you want a private WhatsApp number to stay completely silent to strangers, set:
  • The ~/.mibyan/platforms/whatsapp/session directory contains full session credentials — protect it like a password
  • Set file permissions: chmod 700 ~/.mibyan/platforms/whatsapp/session
  • Use a dedicated phone number for the bot to isolate risk from your personal account
  • If you suspect compromise, unlink the device from WhatsApp → Settings → Linked Devices
  • Phone numbers in logs are partially redacted, but review your log retention policy