Back to Skills
    🦞

    whatsapp-ultimate

    Complete WhatsApp integration — messages, media, polls, stickers, voice notes, reactions, FTS5 history search, voice transcription. Native Baileys, zero Docker.

    By @globalcaos
    View on GitHub
    SKILL.md
    ---
    name: whatsapp-ultimate
    version: 1.8.1
    description: "Complete WhatsApp integration for OpenClaw agents — send messages, media, polls, stickers, voice notes, reactions & replies. Search chat history with full-text search (SQLite + FTS5). Download & transcribe voice messages. Import chat exports. Full history resync. NEW: 🤔 Thinking Reaction — visible progress indicator that works in groups (workaround for WhatsApp's broken typing indicator on linked devices). Owner voice messages bypass prefix filters. Native Baileys — zero Docker, zero external tools. Works alongside OpenClaw's built-in WhatsApp channel."
    homepage: https://github.com/globalcaos/clawdbot-moltbot-openclaw
    repository: https://github.com/globalcaos/clawdbot-moltbot-openclaw
    metadata:
      openclaw:
        emoji: "📱"
        requires:
          channels: ["whatsapp"]
        tags:
          - whatsapp
          - messaging
          - chat
          - voice-notes
          - group-management
          - message-history
          - search
          - media
          - polls
          - stickers
          - reactions
          - thinking-indicator
          - progress-indicator
          - typing-indicator
          - voice-messages
          - baileys
    ---
    
    # WhatsApp Ultimate
    
    **Send messages, media, polls, voice notes, and manage groups — all from your AI agent. Search your entire WhatsApp history instantly.**
    
    The most complete WhatsApp skill for OpenClaw. Native Baileys integration — no Docker, no CLI tools, no external services. Just connect and go.
    
    ---
    
    ## Prerequisites
    
    - OpenClaw with WhatsApp channel configured
    - WhatsApp account linked via QR code (`openclaw whatsapp login`)
    
    ---
    
    ## Capabilities Overview
    
    | Category         | Features                                                                    |
    | ---------------- | --------------------------------------------------------------------------- |
    | **Messaging**    | Text, media, polls, stickers, voice notes, GIFs                             |
    | **Interactions** | Reactions, replies/quotes, edit, unsend                                     |
    | **Groups**       | Create, rename, icon, description, participants, admin, invite links        |
    | **Progress**     | 🤔 Thinking reaction (visible processing indicator for groups)              |
    | **Media Bypass** | Owner voice/media messages bypass prefix filters in groups                  |
    | **History**      | Persistent SQLite storage, FTS5 full-text search, import historical exports |
    | **Resync**       | Full history re-sync via re-link, automatic backup & restore                |
    
    **Total: 24 distinct actions + searchable history**
    
    ---
    
    ## 🤔 Thinking Reaction (Progress Indicator)
    
    **The problem:** WhatsApp linked devices (Baileys, Web API) cannot show "typing..." indicators in group chats. This is a WhatsApp server-side limitation — the protocol sends the `chatstate` XML node correctly, but WhatsApp's servers don't relay composing presence from companion devices to group participants. Confirmed in [Baileys #866](https://github.com/WhiskeySockets/Baileys/issues/866).
    
    **The solution:** When your agent starts processing a message, it instantly reacts with 🤔 on the triggering message. When the reply is ready, the reaction is automatically removed. This gives users immediate visual feedback that the agent is working — no more wondering if your message was received.
    
    **How it works:**
    1. Message arrives → agent reacts with 🤔 (instant, <100ms)
    2. Agent processes (tools, thinking, API calls...)
    3. Reply delivered → 🤔 removed automatically
    
    **Works in:** Groups ✅ | DMs ✅ | All chat types
    
    This is the **only WhatsApp skill** that solves the invisible-typing-indicator problem. Every other WhatsApp integration leaves users staring at silence while the agent thinks.
    
    ---
    
    ## Owner Media Bypass
    
    Voice messages and media from the bot owner now bypass the `triggerPrefix` filter in groups. Previously, a voice note sent in a group with `triggerPrefix: "Jarvis"` would be silently dropped because audio can't carry a text prefix. Now owner media messages are automatically routed to the agent.
    
    ---
    
    ## Messaging
    
    ### Send Text
    
    ```
    message action=send channel=whatsapp to="+34612345678" message="Hello!"
    ```
    
    ### Send Media (Image/Video/Document)
    
    ```
    message action=send channel=whatsapp to="+34612345678" message="Check this out" filePath=/path/to/image.jpg
    ```
    
    Supported: JPG, PNG, GIF, MP4, PDF, DOC, etc.
    
    ### Send Poll
    
    ```
    message action=poll channel=whatsapp to="+34612345678" pollQuestion="What time?" pollOption=["3pm", "4pm", "5pm"]
    ```
    
    ### Send Sticker
    
    ```
    message action=sticker channel=whatsapp to="+34612345678" filePath=/path/to/sticker.webp
    ```
    
    Must be WebP format, ideally 512x512.
    
    ### Send Voice Note
    
    ```
    message action=send channel=whatsapp to="+34612345678" filePath=/path/to/audio.ogg asVoice=true
    ```
    
    **Critical:** Use OGG/Opus format for WhatsApp voice notes. MP3 may not play correctly.
    
    ### Send GIF
    
    ```
    message action=send channel=whatsapp to="+34612345678" filePath=/path/to/animation.mp4 gifPlayback=true
    ```
    
    Convert GIF to MP4 first (WhatsApp requires this):
    
    ```bash
    ffmpeg -i input.gif -movflags faststart -pix_fmt yuv420p -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" output.mp4 -y
    ```
    
    ---
    
    ## Interactions
    
    ### Add Reaction
    
    ```
    message action=react channel=whatsapp chatJid="34612345678@s.whatsapp.net" messageId="ABC123" emoji="🚀"
    ```
    
    ### Remove Reaction
    
    ```
    message action=react channel=whatsapp chatJid="34612345678@s.whatsapp.net" messageId="ABC123" remove=true
    ```
    
    ### Reply/Quote Message
    
    ```
    message action=reply channel=whatsapp to="34612345678@s.whatsapp.net" replyTo="QUOTED_MSG_ID" message="Replying to this!"
    ```
    
    ### Edit Message (Own Messages Only)
    
    ```
    message action=edit channel=whatsapp chatJid="34612345678@s.whatsapp.net" messageId="ABC123" message="Updated text"
    ```
    
    ### Unsend/Delete Message
    
    ```
    message action=unsend channel=whatsapp chatJid="34612345678@s.whatsapp.net" messageId="ABC123"
    ```
    
    ---
    
    ## Group Management
    
    ### Create Group
    
    ```
    message action=group-create channel=whatsapp name="Project Team" participants=["+34612345678", "+34687654321"]
    ```
    
    ### Rename Group
    
    ```
    message action=renameGroup channel=whatsapp groupId="123456789@g.us" name="New Name"
    ```
    
    ### Set Group Icon
    
    ```
    message action=setGroupIcon channel=whatsapp groupId="123456789@g.us" filePath=/path/to/icon.jpg
    ```
    
    ### Set Group Description
    
    ```
    message action=setGroupDescription channel=whatsapp groupJid="123456789@g.us" description="Team chat for Q1 project"
    ```
    
    ### Add Participant
    
    ```
    message action=addParticipant channel=whatsapp groupId="123456789@g.us" participant="+34612345678"
    ```
    
    ### Remove Participant
    
    ```
    message action=removeParticipant channel=whatsapp groupId="123456789@g.us" participant="+34612345678"
    ```
    
    ### Promote to Admin
    
    ```
    message action=promoteParticipant channel=whatsapp groupJid="123456789@g.us" participants=["+34612345678"]
    ```
    
    ### Demote from Admin
    
    ```
    message action=demoteParticipant channel=whatsapp groupJid="123456789@g.us" participants=["+34612345678"]
    ```
    
    ### Leave Group
    
    ```
    message action=leaveGroup channel=whatsapp groupId="123456789@g.us"
    ```
    
    ### Get Invite Link
    
    ```
    message action=getInviteCode channel=whatsapp groupJid="123456789@g.us"
    ```
    
    Returns: `https://chat.whatsapp.com/XXXXX`
    
    ### Revoke Invite Link
    
    ```
    message action=revokeInviteCode channel=whatsapp groupJid="123456789@g.us"
    ```
    
    ### Get Group Info
    
    ```
    message action=getGroupInfo channel=whatsapp groupJid="123456789@g.us"
    ```
    
    Returns: name, description, participants, admins, creation date.
    
    ---
    
    ## Access Control
    
    ### DM Policy
    
    Control who can DM your agent in `openclaw.json`:
    
    ```json
    {
      "channels": {
        "whatsapp": {
          "dmPolicy": "allowlist",
          "allowFrom": ["+34612345678", "+14155551234"],
          "triggerPrefix": "Jarvis"
        }
      }
    }
    ```
    
    | Policy        | Behavior                                |
    | ------------- | --------------------------------------- |
    | `"open"`      | Anyone can DM                           |
    | `"allowlist"` | Only numbers in `allowFrom` can DM      |
    | `"pairing"`   | Unknown senders get pairing code prompt |
    | `"disabled"`  | No DMs accepted                         |
    
    ### Group Policy
    
    ```json
    {
      "channels": {
        "whatsapp": {
          "groupPolicy": "open",
          "groupAllowFrom": ["+34612345678", "+14155551234"]
        }
      }
    }
    ```
    
    | Policy        | Behavior                              |
    | ------------- | ------------------------------------- |
    | `"open"`      | Responds to mentions in any group     |
    | `"allowlist"` | Only from senders in `groupAllowFrom` |
    | `"disabled"`  | Ignores all group messages            |
    
    ### Self-Chat Mode
    
    ```json
    {
      "channels": {
        "whatsapp": {
          "selfChatMode": true
        }
      }
    }
    ```
    
    Allows messaging yourself (your "Note to Self" chat) to interact with the agent.
    
    ### Trigger Prefix
    
    ```json
    {
      "channels": {
        "whatsapp": {
          "triggerPrefix": "Jarvis"
        }
      }
    }
    ```
    
    Messages must start with this prefix to trigger the agent. Works in:
    
    - Self-chat
    - Allowed DMs
    - Any DM where you (the owner) message with the prefix
    
    ---
    
    ## JID Formats
    
    WhatsApp uses JIDs (Jabber IDs) internally:
    
    | Type       | Format                    | Example                      |
    | ---------- | ------------------------- | ---------------------------- |
    | Individual | `<number>@s.whatsapp.net` | `34612345678@s.whatsapp.net` |
    | Group      | `<id>@g.us`               | `123456789012345678@g.us`    |
    
    When using `to=` with phone numbers, OpenClaw auto-converts to JID format.
    
    ---
    
    ## Tips
    
    ### Resolving Group Names
    
    The history database often has `NULL` for `chat_name`. To get a group's display name, use:
    
    ```
    message action=getGroupInfo channel=whatsapp target="<group-jid>"
    ```
    
    Returns: `subject` (group name), `description`, full participant list with admin roles.
    
    **Always refer to groups by name when talking to humans** — JIDs are internal identifiers only.
    
    ### Voice Notes
    
    Always use OGG/Opus format:
    
    ```bash
    ffmpeg -i input.wav -c:a libopus -b:a 64k outp
    
    ... (truncated)