#How to enforce a strict allowlist for WhatsApp to prevent auto-replies to strangers?

1 messages · Page 1 of 1 (latest)

heady harbor
#

Hi I need some help configuring my WhatsApp gateway.

The Problem:
Currently, I want my bot to only talk to me on WhatsApp. However, when unauthorized numbers send a message, the bot automatically replies with a message containing a permission code. I want to completely disable this auto-reply behavior and enforce a strict allowlist (similar to what I have set up for Discord with "dmPolicy": "allowlist"), so the bot completely ignores unknown numbers without processing their messages.

My Environment:

  • OpenClaw Version: 2026.4.14 * Gateway Mode: local * Primary Model: anthropic/claude-haiku-4-5

Current Config Snippet (openclaw.json):

"channels": {
"whatsapp": {
"accounts": {
"default": {
"enabled": true
}
},
"enabled": true
}
}

Side Note / Additional Question:
In my console logs, I also notice that the WhatsApp gateway disconnects with status 499 and reconnects exactly every 30 minutes due to inactivity. Is this the expected behavior for the local gateway?

How can I update my configuration to properly whitelist my own number and drop all other incoming messages silently? Thanks in advance!

rough pumiceBOT
lime ferryBOT
#

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

rough pumiceBOT
heady harbor
#

What you’re trying to do:
I want to set up a strict allowlist for my WhatsApp gateway. The goal is for the bot to only communicate with my number and completely ignore messages from unknown numbers (no processing, no permission codes).

What happened instead:
When unauthorized numbers send a message, the bot automatically replies with a permission code. I also noticed the WhatsApp gateway disconnects exactly every 30 minutes due to inactivity (status 499).

What you ran or clicked:
My openclaw.json lacks an allowlist policy for WhatsApp (unlike my Discord config, which uses "dmPolicy": "allowlist" ).
JSON

"channels": {
"whatsapp": {
"accounts": {
"default": {
"enabled": true
}
},
"enabled": true
}
}

Your environment:

OS: Linux (running from /home/santos/ )

OpenClaw Version: 2026.4.14 

Gateway Mode: local 

Primary Model: anthropic/claude-haiku-4-5 

Relevant logs:

12:50:41 [whatsapp] No messages received in 30m - restarting connection
12:50:41 [whatsapp] Web connection closed (status 499). Retry 1/12 in 2.45s… (status=499)

#

@modern ridge

modern ridgeBOT
#

Got it. I’ve confirmed the DM policy part from the docs/source. I’m doing one quick pass on the 499 behavior so I don’t hand-wave that bit.

#

Your current config is defaulting to dmPolicy: "pairing", so unknown numbers get the pairing code reply.

For strict silent ignore, use:

{
  channels: {
    whatsapp: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"], // your number in E.164 format
      groupPolicy: "disabled",     // optional, blocks all group inbound
      accounts: {
        default: {
          enabled: true,
        },
#
      },
    },
  },
}

A few important bits:

  • dmPolicy: "allowlist" is the setting you want.
  • Unknown DM senders are blocked, not paired, so no permission-code auto-reply.
  • In allowlist mode, WhatsApp uses configured allowFrom only. Old pairing-store approvals are ignored.
  • allowFrom must be non-empty, or config validation will complain.
  • Including your own number in allowFrom also enables the WhatsApp self-chat safeguards.

If you want account-scoped config instead, you can also put dmPolicy and allowFrom under channels.whatsapp.accounts.default.

#

About the 499 every 30 minutes:

  • yes, that looks expected for the current WhatsApp Web monitor
  • the extension has a watchdog that forces a reconnect after about 30 minutes with no inbound messages
  • it closes with internal status 499 and reconnects, which is different from a real logout/conflict

So if it reconnects cleanly and messaging still works, I would not treat that as a failure by itself.

Docs:

If you want, paste your full channels.whatsapp block and I’ll sanity-check it before you restart. Glad that helped! 🎉
If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution.
This helps Answer Overflow index the solution for future users.

heady harbor
#

that would be in my openclaw.json right?

modern ridgeBOT
#

Yep, exactly, that goes in your openclaw.json.

For a single WhatsApp account, this is the right shape:

{
  channels: {
    whatsapp: {
      enabled: true,
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"],
      groupPolicy: "disabled",
      accounts: {
        default: {
          enabled: true,
        },
#
      },
    },
  },
}

Then restart the gateway:

openclaw gateway restart

A couple of quick notes:

  • use your full number in E.164 format in allowFrom (+countrycode...)
  • groupPolicy: "disabled" is optional, but good if you want WhatsApp to be DM-only
#
  • if you already use config includes, the same block can live in an included file too, but yes, openclaw.json is the normal place

If you want, paste your updated channels.whatsapp block and I’ll sanity-check it before you restart.

heady harbor
#

"whatsapp": {
"accounts": {
"default": {
"enabled": true
}
},
"enabled": true
}
},

this is before the changes you suggested

modern ridgeBOT
#

Yep, so you’d change that block to this:

"whatsapp": {
  "enabled": true,
  "dmPolicy": "allowlist",
  "allowFrom": ["+15551234567"],
  "groupPolicy": "disabled",
  "accounts": {
    "default": {
      "enabled": true
    }
  }
}

Just replace +15551234567 with your own WhatsApp number in E.164 format.

#

So the diff is basically:

  • add dmPolicy: "allowlist"
  • add allowFrom: ["your-number"]
  • add groupPolicy: "disabled" if you want no group interaction at all

Then save and run:

openclaw gateway restart

If you want, paste the full updated channels section and I’ll do a quick final check.

heady harbor
#

ok

modern ridgeBOT
#

Nice. Then the next step is just:

openclaw gateway restart

After that, test from:

  • your own number → should work
  • another number not in allowFrom → should be silently ignored, no pairing code

If it still sends pairing codes after restart, the usual next checks are:

openclaw status
openclaw logs --follow
#

and confirm the gateway is loading the config file you edited.

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.

heady harbor
modern ridgeBOT
#

Ah, yep, I see the problem.

Your default account still has:

"dmPolicy": "pairing",
"groupPolicy": "allowlist"

and account-level WhatsApp settings override the channel-level ones for that account.

So even though you set:

"dmPolicy": "allowlist"
#

at the top level, accounts.default.dmPolicy = "pairing" wins for the default account, which is why you still get pairing codes.

Fix: remove those two keys from accounts.default, or change them to match.

This should work:

{
  "channels": {
    "whatsapp": {
      "accounts": {
        "default": {
          "enabled": true,
          "debounceMs": 0
        }
      },
#
      "enabled": true,
      "dmPolicy": "allowlist",
      "groupPolicy": "disabled",
      "allowFrom": ["+351XXXXXXXXX"],
      "debounceMs": 0,
      "mediaMaxMb": 50
    }
  }
}

Or, if you want to keep the policy inside accounts.default, then make it:

"default": {
#
  "enabled": true,
  "dmPolicy": "allowlist",
  "groupPolicy": "disabled",
  "allowFrom": ["+351XXXXXXXXX"],
  "debounceMs": 0
}

My recommendation: for one account, keep it simple and remove the per-account dmPolicy / groupPolicy.

Then restart:

openclaw gateway restart
#

That should stop the pairing-code replies. If you want, send the updated block and I’ll do one more quick pass.

heady harbor
#
  {  
    "channels": {
      "whatsapp": {                  
        "accounts": {                   
          "default": {                   
            "enabled": true                  
          }                     
        "enabled": true,                   
        "dmPolicy": "allowlist",                   
        "groupPolicy": "disabled",                    
        "allowFrom": [                 
          "+351XXXXXXXXX"                        
        ]                           
      }                           
    }                           
  }                               

looks like this now, is there maybe a way to test this without needing someone to send me a message to see if they get that prompt?

modern ridgeBOT
#

You’re very close, but one important thing first: the snippet you pasted looks malformed. I think Discord ate some braces/commas.

It should look like this:

{
  "channels": {
    "whatsapp": {
      "accounts": {
        "default": {
          "enabled": true
        }
      },
      "enabled": true,
      "dmPolicy": "allowlist",
      "groupPolicy": "disabled",
#
      "allowFrom": [
        "+351XXXXXXXXX"
      ]
    }
  }
}

About testing it:

  • There isn’t really a built-in dry-run for “unknown WhatsApp sender” that I trust enough to recommend.
  • The only true end-to-end test is a message from a number not in allowFrom.

Best options:

  • use a second number you control
  • ask a friend to send one test message
#
  • or do an indirect check:
openclaw gateway restart
openclaw status
openclaw logs --follow

What I’d expect after the fix:

  • your number works
  • unknown number gets silently blocked
  • no pairing code is sent

So, short version: yes, but only a real outside number fully proves it.

If you want, paste the full channels block again and I’ll check the JSON structure too, because I think the version in your message is missing a closing }, after accounts.default.

heady harbor
#

will this cost me tokens every time someone sends me a message? does that silent blocking mean the AI will still do needless checks to see if that person is in the list or not?

modern ridgeBOT
#

No, that should not burn AI tokens for random strangers.

With dmPolicy: "allowlist":

  • OpenClaw checks the sender locally
  • if the sender is not in allowFrom, it gets blocked before the message is processed by the agent/model
  • so there should be no LLM request, which means no model token cost for that blocked message

So yes, there is still a tiny local runtime check like:

  • receive inbound message
  • normalize sender ID
  • compare against allowFrom
  • drop it

But that’s just normal gateway logic, not an AI/model call.

#

That “silent blocking” is exactly what you want here: cheap local filtering, no pairing reply, no agent run, no wasted tokens.

Docs wording for this is basically that DM policy gates inbound DMs before the message is processed:
https://docs.openclaw.ai/gateway/security#dm-access-model-pairing-allowlist-open-disabled

If this fixed it, please right-click the solution message → Apps → ✅ Mark Solution so Answer Overflow can index it.

heady harbor
#

I will mark this as complete once im able to test it thank you