Skip to content

feat(whatsapp): add dm_policy and group_policy parity with WeCom/Weixin/QQ adapters#11597

Closed
MassiveMassimo wants to merge 2 commits into
NousResearch:mainfrom
MassiveMassimo:feat/whatsapp-dm-group-policy
Closed

feat(whatsapp): add dm_policy and group_policy parity with WeCom/Weixin/QQ adapters#11597
MassiveMassimo wants to merge 2 commits into
NousResearch:mainfrom
MassiveMassimo:feat/whatsapp-dm-group-policy

Conversation

@MassiveMassimo

@MassiveMassimo MassiveMassimo commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Add `dm_policy` and `group_policy` to the WhatsApp adapter, bringing parity with the existing WeCom/Weixin/QQ adapters.

The WhatsApp adapter currently has no first-class DM/group gating — `allowed_users` conflates both, and there is no way to:

  • Disable DMs entirely while keeping groups active
  • Allow anyone in a group to trigger the bot without adding them all to `allowed_users`
  • Control DM and group access independently

Other platform adapters (WeCom, Weixin, QQ) already implement this pattern with `_dm_policy`, `_group_policy`, `allow_from`, and `group_allow_from`.

Changes

`gateway/platforms/whatsapp.py`

  • Added `_dm_policy`, `_allow_from`, `_group_policy`, `_group_allow_from` config properties
  • Added `_coerce_allow_list()` helper for flexible config formats (string, list)
  • Added `_is_dm_allowed(sender_id)` — checks dm_policy (open/allowlist/disabled)
  • Added `_is_group_allowed(chat_id)` — checks group_policy (open/allowlist)
  • Updated `_should_process_message()` with proper policy gates before mention/auth checks
  • Fixed bug where DMs could fall through to mention checks (early return after DM gate passes)

`gateway/config.py`

  • Added YAML → env bridging for `dm_policy`, `allow_from`, `group_policy`, `group_allow_from`
  • Values pass through via `load_from_yaml()` alongside existing WhatsApp config keys

Backward Compatibility

  • Default `dm_policy: open` — preserves previous behavior (all DMs processed)
  • Default `group_policy: open` — preserves previous behavior (all groups processed)
  • No config change required for existing deployments

Config Example

```yaml
whatsapp:
dm_policy: disabled # drop all DMs at adapter level
group_policy: allowlist # only respond in specified groups
group_allow_from:
- "123456789@g.us"
- "987654321@g.us"
require_mention: true
mention_patterns: ["botname"]
```

Tests

22 tests in `tests/gateway/test_whatsapp_group_gating.py` covering:

  • dm_policy: open / allowlist / disabled
  • group_policy: open / allowlist
  • Interaction with require_mention, free_response_chats
  • Edge cases (empty allowlist, invalid policy values)

Full gateway suite: 3046 passed, 6 failed (3 pre-existing whatsapp_connect session-lock, 3 unrelated telegram approval — same on main branch).

Related Issues

Closes #7992
Addresses #7269
Related #8389 (bridge-level allowlist default)
Related #2991 (LID resolution — separate but overlapping scope)

…in/QQ adapters

WhatsApp adapter was missing dm_policy and group_policy configuration
options that already exist in WeCom, Weixin, and QQ adapters. This
forces users to rely on fragile local patches or the global
WHATSAPP_ALLOWED_USERS env var, which cannot distinguish between DM
and group access.

Changes:
- whatsapp.py: add _dm_policy, _allow_from, _group_policy,
  _group_allow_from with _is_dm_allowed() and _is_group_allowed()
- whatsapp.py: update _should_process_message() to enforce both
  policies before mention/free-response checks
- config.py: bridge dm_policy, allow_from, group_policy,
  group_allow_from from YAML to env vars (WHATSAPP_DM_POLICY,
  WHATSAPP_ALLOWED_USERS, WHATSAPP_GROUP_POLICY,
  WHATSAPP_GROUP_ALLOWED_USERS)
- config.py: bridge the same keys in load_from_yaml() platform
  config passthrough
- tests: 12 new test cases covering all policy modes + 2 config
  bridging tests

Supported modes:
  dm_policy: "open" | "allowlist" | "disabled" (default: "open")
  group_policy: "open" | "allowlist" | "disabled" (default: "open")

This matches the interface of WeCom/Weixin/QQ adapters exactly.
Group messages already passed the adapter's group_policy gate
(_should_process_message), so the sender is implicitly authorized
by virtue of being in an allowed group. Without this bypass,
_is_user_authorized() would reject group participants who aren't
in an explicit user allowlist, making group_policy: allowlist
only half-functional.
teknium1 pushed a commit that referenced this pull request Apr 20, 2026
…in/QQ adapters

Add dm_policy and group_policy to the WhatsApp adapter, bringing parity
with WeCom/Weixin/QQ. Allows independent control of DM and group access:
disable DMs entirely, allowlist specific senders/groups, or keep open.

- dm_policy: open (default) | allowlist | disabled
- group_policy: open (default) | allowlist | disabled
- Config bridging for YAML → env vars
- 22 tests covering all policy combinations

Backward compatible — defaults preserve existing behavior.

Cherry-picked from PR #11597 by @MassiveMassimo.
Dropped the run.py group auth bypass (would have skipped user auth
for ALL platforms, not just WhatsApp).
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #13151 (#13151). Your adapter-level dm_policy/group_policy implementation was cherry-picked onto current main with your authorship preserved via rebase-merge. Dropped the run.py group auth bypass — it would have skipped user authorization for all platforms, not just WhatsApp. Thanks for the contribution!

@teknium1 teknium1 closed this Apr 20, 2026
ulasbilgen pushed a commit to ulasbilgen/hermes-adhd-agent that referenced this pull request May 1, 2026
…in/QQ adapters

Add dm_policy and group_policy to the WhatsApp adapter, bringing parity
with WeCom/Weixin/QQ. Allows independent control of DM and group access:
disable DMs entirely, allowlist specific senders/groups, or keep open.

- dm_policy: open (default) | allowlist | disabled
- group_policy: open (default) | allowlist | disabled
- Config bridging for YAML → env vars
- 22 tests covering all policy combinations

Backward compatible — defaults preserve existing behavior.

Cherry-picked from PR NousResearch#11597 by @MassiveMassimo.
Dropped the run.py group auth bypass (would have skipped user auth
for ALL platforms, not just WhatsApp).
aj-nt pushed a commit to aj-nt/hermes-agent that referenced this pull request May 1, 2026
…in/QQ adapters

Add dm_policy and group_policy to the WhatsApp adapter, bringing parity
with WeCom/Weixin/QQ. Allows independent control of DM and group access:
disable DMs entirely, allowlist specific senders/groups, or keep open.

- dm_policy: open (default) | allowlist | disabled
- group_policy: open (default) | allowlist | disabled
- Config bridging for YAML → env vars
- 22 tests covering all policy combinations

Backward compatible — defaults preserve existing behavior.

Cherry-picked from PR NousResearch#11597 by @MassiveMassimo.
Dropped the run.py group auth bypass (would have skipped user auth
for ALL platforms, not just WhatsApp).
Luminet2023 pushed a commit to Luminet2023/hermes-agent that referenced this pull request May 1, 2026
…in/QQ adapters

Add dm_policy and group_policy to the WhatsApp adapter, bringing parity
with WeCom/Weixin/QQ. Allows independent control of DM and group access:
disable DMs entirely, allowlist specific senders/groups, or keep open.

- dm_policy: open (default) | allowlist | disabled
- group_policy: open (default) | allowlist | disabled
- Config bridging for YAML → env vars
- 22 tests covering all policy combinations

Backward compatible — defaults preserve existing behavior.

Cherry-picked from PR NousResearch#11597 by @MassiveMassimo.
Dropped the run.py group auth bypass (would have skipped user auth
for ALL platforms, not just WhatsApp).
02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
…in/QQ adapters

Add dm_policy and group_policy to the WhatsApp adapter, bringing parity
with WeCom/Weixin/QQ. Allows independent control of DM and group access:
disable DMs entirely, allowlist specific senders/groups, or keep open.

- dm_policy: open (default) | allowlist | disabled
- group_policy: open (default) | allowlist | disabled
- Config bridging for YAML → env vars
- 22 tests covering all policy combinations

Backward compatible — defaults preserve existing behavior.

Cherry-picked from PR NousResearch#11597 by @MassiveMassimo.
Dropped the run.py group auth bypass (would have skipped user auth
for ALL platforms, not just WhatsApp).
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…in/QQ adapters

Add dm_policy and group_policy to the WhatsApp adapter, bringing parity
with WeCom/Weixin/QQ. Allows independent control of DM and group access:
disable DMs entirely, allowlist specific senders/groups, or keep open.

- dm_policy: open (default) | allowlist | disabled
- group_policy: open (default) | allowlist | disabled
- Config bridging for YAML → env vars
- 22 tests covering all policy combinations

Backward compatible — defaults preserve existing behavior.

Cherry-picked from PR NousResearch#11597 by @MassiveMassimo.
Dropped the run.py group auth bypass (would have skipped user auth
for ALL platforms, not just WhatsApp).
Egavasyug pushed a commit to Egavasyug/hermes-agent that referenced this pull request Jun 10, 2026
…in/QQ adapters

Add dm_policy and group_policy to the WhatsApp adapter, bringing parity
with WeCom/Weixin/QQ. Allows independent control of DM and group access:
disable DMs entirely, allowlist specific senders/groups, or keep open.

- dm_policy: open (default) | allowlist | disabled
- group_policy: open (default) | allowlist | disabled
- Config bridging for YAML → env vars
- 22 tests covering all policy combinations

Backward compatible — defaults preserve existing behavior.

Cherry-picked from PR NousResearch#11597 by @MassiveMassimo.
Dropped the run.py group auth bypass (would have skipped user auth
for ALL platforms, not just WhatsApp).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: WhatsApp: Telegram-like group behavior controls (ignore_groups, mention-only replies, and group allowlists)

2 participants