#WhatsApp Outbound
1 messages · Page 1 of 1 (latest)
@shy orchid
Best practice is:
- 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.
- Use
openclaw message send(CLI) or the agentâsmessagetool for proactive outbound to any E.164 number (and optionally require human confirmation in your workflow). - 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 agentmessagetool), 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:
-
Link a dedicated WhatsApp number (recommended operationally)
openclaw channels login --channel whatsapp -
Set
dmPolicy: "pairing"so when a new external contact replies, you approve them once:
openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
- Send outbound:
(If you have multiple WA accounts configured: addopenclaw message send --channel whatsapp --target +15555550123 --message "Hi!"--account work.)
Two questions so I can point you at the cleanest pattern:
- Do you want outbound to be manual (you trigger each send) or automated (agent decides + sends)?
- Is this 1 WhatsApp account or multiple (personal + work)?
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?
To do âresearch + WhatsApp the top 3 spas near meâ cleanly in OpenClaw, treat it as a 2-phase workflow:
- Research + shortlist + draft
- 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:
- Sessions / dmScope: https://docs.openclaw.ai/concepts/session
- WhatsApp channel: https://docs.openclaw.ai/channels/whatsapp
- Pairing approvals: https://docs.openclaw.ai/channels/pairing
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.melinks 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.melinks / 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).
So OpenClaw can send WhatsApp to any number? What if the number replies?
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 tochannels.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.
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
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
- You DM the bot number with: âresearch + draft these 3 outreach messagesâ
- OpenClaw returns (a) the 3 targets + numbers and (b) the exact message texts
- 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
- Keep OpenClaw on its own number for âcontrol chatâ (where you talk to the agent).
- Also link your personal WhatsApp to the same Gateway as another account (multi-account).
- After you approve, the agent sends using the personal account.
Docs that show multi-account login exists:
- WhatsApp login supports
--account: https://docs.openclaw.ai/channels/whatsapp - Outbound send: https://docs.openclaw.ai/cli/message
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.
What about WA CLI or WhatsApp Business API?
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
- OpenClaw does research + drafting + approval workflow
- On approval, you call your own âsend serviceâ that uses WhatsApp Business API
- 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.
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
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: {},
},
// Inbound policy choice (see section 3)
dmPolicy: "allowlist",
allowFrom: ["+YOUR_PERSONAL_NUMBER", "+CLIENT_1", "+CLIENT_2"],
},
},
}
dmScope is important so each business gets its own isolated thread:
https://docs.openclaw.ai/concepts/session
Multi-account WhatsApp is documented here:
https://docs.openclaw.ai/gateway/configuration-reference#whatsapp (see âMulti-account WhatsAppâ)
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
allowFrombefore 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:
- OpenClaw reads it (if allowed by
dmPolicy) - It sends you a message in the control chat: âThey said X. Here are reply options A/B/C.â
- You approve one option
- 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
- Are you only messaging known clients (small fixed set), or do you want cold outreach to new numbers regularly?
- 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.
Ok but how do we make sure you don't reply when a business replies to my personal number?
You make it a hard guarantee with two layers:
- Block auto-delivery back to the business DM (even if the model âtries to answerâ)
- Remove the
messagetool 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:
{
session: {
dmScope: "per-account-channel-peer",
},
}
Docs: https://docs.openclaw.ai/concepts/session
C) Route inbound âpersonal accountâ messages to a no-reply triage agent
{
agents: {
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:
- Routing/bindings: https://docs.openclaw.ai/channels/channel-routing
- Tool deny/allow: https://docs.openclaw.ai/tools (see
group:messagingâmessage)
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)