Skip to content

fix(signal): read groupV2.id in envelope, fall back to legacy groupInfo#16260

Closed
teknium1 wants to merge 1 commit into
mainfrom
nanoclaw-port/signal-groupv2
Closed

fix(signal): read groupV2.id in envelope, fall back to legacy groupInfo#16260
teknium1 wants to merge 1 commit into
mainfrom
nanoclaw-port/signal-groupv2

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Port from qwibitai/nanoclaw#1962.

Summary

Modern Signal V2-only groups arrive with their group id on dataMessage.groupV2.id, not dataMessage.groupInfo.groupId. signal-cli versions differ in which field they expose for V2 groups — some forward the underlying libsignal envelope verbatim (groupV2), others normalize everything into groupInfo. Without a groupV2 read, V2-only groups appear as DMs because groupInfo is undefined, and the adapter misroutes them to the sender's DM session.

Changes

  • gateway/platforms/signal.py: read dataMessage.groupV2.id first, fall back to dataMessage.groupInfo.groupId for V1 compatibility. Harden chat_name extraction against non-dict groupInfo payloads (previously crashed with AttributeError under malformed envelopes).
  • tests/gateway/test_signal.py: 6 new tests (TestSignalGroupV2Routing) covering V2 routing, V1 legacy fallback, V2-preferred precedence when both fields are present, no-group DM path, allowlist enforcement on V2 ids, and malformed payload robustness.

Adaptation notes

  • NanoClaw's original fix (TypeScript / signal-cli JSON-RPC adapter): dataMessage.groupV2?.id ?? groupInfo?.groupId
  • Python port keeps the same precedence and adds isinstance(..., dict) guards since signal-cli JSON-RPC envelopes in the wild occasionally deliver unexpected shapes.
  • The allowlist filter (SIGNAL_GROUP_ALLOWED_USERS) already runs on group_id, so it now correctly enforces against V2 ids as well.

Validation

Before After
V2-only group → routing misrouted as DM routes as group:<v2-id>
V1-only group → routing works works
tests/gateway/test_signal.py 67 passed 73 passed

Test plan

  • scripts/run_tests.sh tests/gateway/test_signal.py — 73/73 pass
  • py_compile clean on both files

Source PR: nanocoai/nanoclaw#1962 (V2 Signal adapter improvements — shipped as part of the NanoClaw v2 release).

Port from nanocoai/nanoclaw#1962: modern Signal V2-only groups surface on
dataMessage.groupV2.id, not groupInfo.groupId. signal-cli versions differ
in which field they expose for V2 groups — some forward the underlying
libsignal envelope verbatim (groupV2), others normalize everything into
groupInfo. Without a groupV2 read, V2-only groups appear as DMs because
groupInfo is undefined and the adapter misroutes them to the sender's
DM session.

Reads groupV2.id first, falls back to groupInfo.groupId. Also hardens
chat_name extraction against non-dict groupInfo payloads (crashed with
AttributeError under malformed envelopes).

6 new tests cover V2 routing, V1 legacy compatibility, V2-preferred
precedence, no-group DM path, allowlist enforcement, and malformed
payloads.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/signal Signal CLI adapter labels Apr 27, 2026
@teknium1

Copy link
Copy Markdown
Contributor Author

Closing in favor of #27051, which salvages this PR onto current main. One test-file conflict resolved (both main and the PR appended new test classes at EOF; both kept). 109/109 signal tests pass.

@teknium1 teknium1 closed this May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/signal Signal CLI adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants