#WhatsApp Outbound

1 messages · Page 1 of 1 (latest)

sinful thunder
#

What's the best way to have OpenClaw message external contacts on WhatsApp for both inbound and outbound?

weak ravenBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

sinful thunder
#

@shy orchid

shy orchidBOT
#

Best practice is:

  1. Run the built-in WhatsApp Web channel (Baileys) on a dedicated WhatsApp number, link it once via QR, and keep inbound locked down with pairing/allowlists.
  2. Use openclaw message send (CLI) or the agent’s message tool for proactive outbound to any E.164 number (and optionally require human confirmation in your workflow).
  3. For inbound replies from new external contacts, use DM pairing so they can’t just start talking to your bot without approval.

1) Configure inbound policy (recommended: pairing)

{
  channels: {
    whatsapp: {
      dmPolicy: "pairing",        // safest default for “external contacts”
      allowFrom: ["+15551234567"] // you (so you can always DM it)
    }
  }
}
#

Docs: https://docs.openclaw.ai/channels/whatsapp (Access control + activation)

2) Link WhatsApp (QR)

openclaw channels login --channel whatsapp

3) Outbound (proactive) messaging to an external contact

openclaw message send --channel whatsapp --target +15555550123 --message "Hi!"

Docs: https://docs.openclaw.ai/cli/message (target formats include WhatsApp E.164)

4) Let them reply inbound (and approve once)

If you’re in dmPolicy: "pairing", unknown senders get a code; approve them:

#
openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>

Docs: https://docs.openclaw.ai/channels/pairing


Rule of thumb:

  • If you want to message new people outbound and safely accept inbound when they reply → dmPolicy: "pairing" is the sweet spot.
  • If you want inbound without approvals (not recommended) → dmPolicy: "open" + allowFrom: ["*"].

If you tell me whether your outbound is manual (you trigger it) or automated (agent decides + sends), I can suggest the cleanest pattern (CLI-only vs skill + confirmation gate).

#

Yep — ping received.

A couple key clarifications for WhatsApp in OpenClaw:

  • Inbound controls (dmPolicy, allowFrom, pairing) only gate who is allowed to talk to the bot.
  • Outbound is best done via openclaw message send (or the agent message tool), and it can target any E.164 number (and group JIDs) as long as the WhatsApp account is linked + the Gateway has an active listener.

Concrete “best practice” setup:

  1. Link a dedicated WhatsApp number (recommended operationally)

    openclaw channels login --channel whatsapp
    
  2. Set dmPolicy: "pairing" so when a new external contact replies, you approve them once:

#
   openclaw pairing list whatsapp
   openclaw pairing approve whatsapp <CODE>
  1. Send outbound:
    openclaw message send --channel whatsapp --target +15555550123 --message "Hi!"
    
    (If you have multiple WA accounts configured: add --account work.)

Two questions so I can point you at the cleanest pattern:

  1. Do you want outbound to be manual (you trigger each send) or automated (agent decides + sends)?
  2. Is this 1 WhatsApp account or multiple (personal + work)?
sinful thunder
#

For example, I want to ask OpenClaw to research and message the top 3 spas in my area. How would we best go about that?

shy orchidBOT
#

To do “research + WhatsApp the top 3 spas near me” cleanly in OpenClaw, treat it as a 2-phase workflow:

  1. Research + shortlist + draft
  2. Human approval → then send 3 outbound WhatsApps

That avoids accidental spam / wrong recipients, and it’s way easier to sanity-check phone numbers + wording.

One-time setup (so outreach convos don’t all merge)

By default, WhatsApp DMs can collapse into one shared “main” session. If you’re going to chat with multiple spas at once, set secure DM scoping so each business gets its own context:

{
  session: {
    dmScope: "per-channel-peer",
  },
  channels: {
#
    whatsapp: {
      dmPolicy: "pairing", // recommended so unknown numbers can’t just DM your bot
    },
  },
}

Docs:

Day-to-day usage (what you actually type)

Send a single instruction like:

“I’m in [your city / zip]. Find the top 3 spas within 5km (high ratings + good reviews). For each, extract a WhatsApp-capable number (prefer wa.me links or ‘WhatsApp us’ buttons), website, and a 1‑line reason it’s top. Draft a short message asking for availability next week. Do not send anything until I approve.”

#

Then the agent should respond with a table like:

  • Spa name + link
  • WhatsApp number (or “no WhatsApp found”)
  • Draft message text

You reply: “Send all 3” (or “Send 1 and 2, skip 3”).

Sending outbound (what it uses under the hood)

Outbound WhatsApp sends are done via the normal message action (same as the CLI):

openclaw message send --channel whatsapp --target +15555550123 --message "Hi 
"

Docs: https://docs.openclaw.ai/cli/message

Two gotchas to expect

#
  • Not every phone number is on WhatsApp. Many businesses list landlines; sending may fail. That’s why “prefer wa.me links / WhatsApp buttons” is important.
  • If you keep dmPolicy: "pairing", when a spa replies inbound you may need to approve that sender once (then you’re good).

If you tell me what “my area” means for you (city/zip) and whether you want this to be one-off or a repeatable “outreach” workflow, I can suggest the best prompt template + config (and whether to spin up a separate “outreach agent” so it never mixes with personal chats).

sinful thunder
#

So OpenClaw can send WhatsApp to any number? What if the number replies?

shy orchidBOT
#

Yes—outbound, OpenClaw can attempt to send a WhatsApp message to any E.164 phone number (e.g. +49123456789), as long as:

  • your WhatsApp account is linked (openclaw channels login --channel whatsapp)
  • the Gateway has an active WhatsApp listener
  • and the target number is actually on WhatsApp (if it’s not, the send will fail)

Docs: https://docs.openclaw.ai/cli/message (WhatsApp targets)

What happens if the number replies?

That’s controlled by your inbound DM policy:

  • dmPolicy: "pairing" (recommended):
    Their reply will trigger a pairing code and won’t be processed until you approve them.
    Approve via:
    openclaw pairing list whatsapp
    
#
  openclaw pairing approve whatsapp <CODE>

Docs: https://docs.openclaw.ai/channels/pairing

  • dmPolicy: "allowlist":
    Their reply will be ignored/blocked unless you add them to channels.whatsapp.allowFrom.

  • dmPolicy: "open" (not recommended for public numbers):
    Their reply will be accepted immediately (high prompt-injection / “random people can DM your bot” risk).

Docs: https://docs.openclaw.ai/channels/whatsapp (Access control and activation)

Strongly recommended if you’re chatting with multiple businesses

Set DM sessions to not all merge together:

#
{
  session: { dmScope: "per-channel-peer" }
}

Docs: https://docs.openclaw.ai/concepts/session (dmScope)

If you share your current channels.whatsapp config block (redact tokens), I can tell you exactly which mode you’re in and what will happen on replies.

sinful thunder
#

Overall I want to achieve the following:
1.⁠ ⁠I message OpenClaw (set up on its own number) from my personal number to research and send to certain clients
2.⁠ ⁠⁠OpenClaw drafts the messages and gets the numbers and sends them to me for approval
3.⁠ ⁠⁠Once approved OpenClaw sends the messages from my personal number

shy orchidBOT
#

You can get almost all of that, with one important constraint:

OpenClaw can only send WhatsApp messages from numbers that are actually linked to the Gateway.
It can’t “send from your personal number” unless you also link your personal WhatsApp to OpenClaw (as another WhatsApp account/device). No spoofing.

Two workable patterns

Option A (safest / simplest): bot drafts, you manually send

  1. You DM the bot number with: “research + draft these 3 outreach messages”
  2. OpenClaw returns (a) the 3 targets + numbers and (b) the exact message texts
  3. You copy/paste and send from your personal WhatsApp

This avoids giving the Gateway access to your personal WhatsApp and avoids any “oops it sent something” risk.

Option B (fully automated send from your personal number): link personal WhatsApp as a 2nd account

  1. Keep OpenClaw on its own number for “control chat” (where you talk to the agent).
  2. Also link your personal WhatsApp to the same Gateway as another account (multi-account).
#
  1. After you approve, the agent sends using the personal account.

Docs that show multi-account login exists:

Approval flow (how to do step 2 reliably)

In your agent instructions/prompt, enforce something like:

  • “Do not send any outbound messages until I explicitly reply APPROVE 1,2,3.”
  • “Before sending, show me the exact To: numbers and the final message text.”

If you want extra safety when you start doing lots of outbound, set DM session isolation so each client chat doesn’t bleed context into another:

{
  session: {
#
    dmScope: "per-account-channel-peer" // best if you use multiple WhatsApp accounts
  }
}

Docs: https://docs.openclaw.ai/concepts/session

What happens when clients reply?

If you send from your personal account, replies come back to that same (personal) WhatsApp account on the Gateway. Then your inbound policy decides what happens:

  • dmPolicy: "pairing" → first reply requires your approval (good for outbound-to-new-contacts)
  • dmPolicy: "allowlist" → only pre-added client numbers can be processed

Docs: https://docs.openclaw.ai/channels/whatsapp and https://docs.openclaw.ai/channels/pairing


#

If you want, paste (redacting tokens) your current channels.whatsapp config or tell me whether you’re comfortable linking your personal WhatsApp to the Gateway. Then I can suggest the cleanest exact setup for Option B (accounts + dmPolicy + dmScope) without over-opening inbound.

sinful thunder
#

What about WA CLI or WhatsApp Business API?

shy orchidBOT
#

WA CLI: If you mean “send WhatsApps from a command line,” OpenClaw already is that CLI:

openclaw message send --channel whatsapp --target +49123456789 --message "Hi!"

Under the hood this uses OpenClaw’s WhatsApp Web channel (Baileys). There isn’t a separate “official WhatsApp CLI” that’s better/cleaner—most “WhatsApp CLIs” you’ll find are just wrappers around WhatsApp Web too (same general fragility / ToS risk profile).

Docs: https://docs.openclaw.ai/cli/message
WhatsApp channel scope note: https://docs.openclaw.ai/channels/whatsapp (it’s explicitly Web-based; no built-in Twilio/Business channel)


WhatsApp Business API (Meta Cloud API / Twilio / 360dialog)

That’s a different beast:

  • Different account/number (it’s not your personal WhatsApp number)
#
  • Policy constraints (templates for business-initiated messages, 24h customer-care window, opt-in expectations, etc.)
  • More reliable + compliant for real outbound at scale

OpenClaw does not currently ship a built-in WhatsApp Business API channel. If you want Business API, the “best way” today is an integration pattern:

Recommended architecture

  1. OpenClaw does research + drafting + approval workflow
  2. On approval, you call your own “send service” that uses WhatsApp Business API
  3. Incoming replies from Business API webhooks get forwarded into OpenClaw for handling

The glue for (2)/(3) is usually OpenClaw Webhooks:

So: OpenClaw = brain + approval UX, Business API service = compliant transport.


#

Important for your earlier goal (“send from my personal number”)

Business API won’t help you send from your personal number. It sends from the business number attached to the Business account. To send from your personal number, you must link that personal WhatsApp Web session to the Gateway (as another account).

If you tell me whether your priority is (A) send-from-personal-number or (B) scalable/compliant outbound, I can recommend which route to implement first and what the config/workflow should look like.

sinful thunder
#

How can we set it up like this?

1.⁠ OpenClaw sends outbound from my personal number (after approval)
2.⁠ ⁠Business replies to that number
3.⁠ ⁠OpenClaw sees the reply
4.⁠ ⁠It forwards it to me with draft options A/B/C
5.⁠ ⁠I approve
6.⁠ ⁠OpenClaw sends my approved reply back to the business

shy orchidBOT
#

You can build that exact loop, but it’s not a single “checkbox feature” — it’s a routing + policy + workflow setup:

  • Your personal WhatsApp is the “business-facing transport” (inbound + outbound).
  • A separate control chat is where you approve A/B/C (best: a second WhatsApp number that OpenClaw runs, or at least your WhatsApp self‑chat).

The key trick is: don’t let the agent auto-reply in the business DMs. Make it only draft + forward to you, and only send after an explicit approval command.


0) Non-negotiable constraint

To “send from my personal number”, that number must be linked to OpenClaw via WhatsApp Web (Baileys). No spoofing.

Docs: https://docs.openclaw.ai/channels/whatsapp


1) Recommended topology (2 WhatsApp accounts on one Gateway)

#
  • Account A (personal) = your personal number (talks to businesses)
  • Account B (control) = OpenClaw’s own number (you approve here)

Config skeleton:

{
  session: {
    dmScope: "per-account-channel-peer",
  },

  channels: {
    whatsapp: {
      accounts: {
        personal: {},
        control: {},
#

2) Link both numbers

Run these on the Gateway host (you’ll scan two QR codes, one per account):

openclaw channels login --channel whatsapp --account personal
openclaw channels login --channel whatsapp --account control

(From docs: https://docs.openclaw.ai/channels/whatsapp)


3) Pick the inbound policy for “business replies”

This is where most people trip up:

#

Option 3A — dmPolicy: "allowlist" (recommended)

  • Businesses will only be “seen by the bot” if their number is in allowFrom.
  • Good if you’re messaging “certain clients” (known list).
  • For new recipients, you add them to allowFrom before you start the thread.

Option 3B — dmPolicy: "open" (high risk)

  • Lets OpenClaw process anyone who messages your personal number.
  • Requires: allowFrom: ["*"]
  • This is basically “turn my personal WhatsApp inbox into a bot inbox” — doable, but you need strong safety/approval discipline.

Avoid dmPolicy: "pairing" for outreach

Because the pairing code gets sent to the business, which is awkward/confusing in real conversations.

Policy docs: https://docs.openclaw.ai/channels/pairing and https://docs.openclaw.ai/channels/whatsapp


#

4) The actual A/B/C approval workflow

You implement this as operating procedure (and ideally as a small “outreach agent” prompt):

Outbound initiation (you → control chat)

You DM the control number something like:

  • “Draft outreach to +49
 about X. Don’t send until I approve. Give A/B/C.”

Bot replies with:

  • Recipient number
  • Context summary
  • Draft A / Draft B / Draft C
  • “Reply with APPROVE A / APPROVE B / APPROVE C”

Sending after approval

When you reply APPROVE B, OpenClaw sends using the personal account:

  • CLI equivalent:
#
  openclaw message send --channel whatsapp --account personal --target +49... --message "..."

Docs: https://docs.openclaw.ai/cli/message

Inbound reply (business → personal number)

When a business replies to your personal number:

  1. OpenClaw reads it (if allowed by dmPolicy)
  2. It sends you a message in the control chat: “They said X. Here are reply options A/B/C.”
  3. You approve one option
  4. OpenClaw sends the approved reply back via the personal account

5) Extra safety (optional but smart)

If you want to make it harder for the agent to ever “accidentally reply” in the business DM thread, you can use send policy rules to block automatic delivery for the personal-account DM session keys, and only send via explicit outbound commands.

#

Session send policy docs: https://docs.openclaw.ai/concepts/session (Send policy section)

(I’m mentioning this as an option because it depends on your exact routing + how you want to operate.)


Two questions that determine the best exact config

  1. Are you only messaging known clients (small fixed set), or do you want cold outreach to new numbers regularly?
  2. Do you want approvals to happen on WhatsApp (control number) or would Telegram be acceptable as the approval/control channel?

Answer those and I’ll give you a concrete “copy/paste” config + the exact message templates to use for the approval loop.

sinful thunder
#

Ok but how do we make sure you don't reply when a business replies to my personal number?

shy orchidBOT
#

You make it a hard guarantee with two layers:

  1. Block auto-delivery back to the business DM (even if the model “tries to answer”)
  2. Remove the message tool from the business-facing agent so it can’t “manually send” either

The clean way to do this is: two WhatsApp accounts + two agents + routing.


A) Two WhatsApp accounts

  • personal = your personal number (business-facing)
  • control = the OpenClaw/bot number (where you do approvals)
{
  channels: {
#
    whatsapp: {
      accounts: {
        personal: {},
        control: {},
      },
    },
  },
}

Docs: https://docs.openclaw.ai/channels/whatsapp


B) Make session keys include the accountId

This lets us target “personal account DMs” precisely:

#
    list: [
      { id: "control", default: true, name: "Control" },
      {
        id: "inbox",
        name: "Business Inbox (no-reply)",
        tools: {
          profile: "minimal",
          allow: ["sessions_send"], // can forward internally
          deny: ["message"],        // cannot send WhatsApp/Telegram/etc
        },
      },
    ],
  },

  bindings: [
#
    { match: { channel: "whatsapp", accountId: "personal" }, agentId: "inbox" },
    { match: { channel: "whatsapp", accountId: "control" }, agentId: "control" },
  ],
}

Docs:


D) Fail-safe: deny any reply delivery in personal-account DM sessions

Because dmScope=per-account-channel-peer, the business DM session keys look like:

agent:<agentId>:whatsapp:<accountId>:dm:<peerId>

#

So you can block delivery for the entire personal account DM space:

{
  session: {
    sendPolicy: {
      rules: [
        { action: "deny", match: { keyPrefix: "agent:inbox:whatsapp:personal:dm:" } },
      ],
      default: "allow",
    },
  },
}

Docs: https://docs.openclaw.ai/concepts/session (Send policy)