openclaw - ✅(Solved) Fix working signal chat app channel [1 pull requests, 2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#75870Fetched 2026-05-02 05:28:41
View on GitHub
Comments
2
Participants
2
Timeline
9
Reactions
2
Author
Timeline (top)
referenced ×3commented ×2cross-referenced ×1mentioned ×1

Fix Action

Fix / Workaround

hi, currently the signal functionality is basically unusable. outbound messages to openclaw through signal aren't received. i implemented a patch (or a variant, just asked claude to implement this patch) and it made signal functional / useable. signal seems like potentially a major channel, maybe worth implementing? its a small fix

PR fix notes

PR #75890: fix(signal): support Note-to-Self in linked-device mode

Description (problem / solution / changelog)

Summary

  • Problem: When signal-cli runs as a linked device on the operator's personal Signal account, the existing loop-protection in event-handler.ts blanket-drops all messages from the bot's own account AND all syncMessages. Note-to-Self chat is therefore impossible.
  • Why it matters: Note-to-Self is the natural chat surface for users running OpenClaw as a personal agent on their existing Signal account. Without this, users must acquire a dedicated bot number to chat with their own agent — significant friction for personal-use deployments.
  • What changed: Added a Note-to-Self carve-out: syncMessages where destination === source are promoted to dataMessage so downstream allowFrom/dmPolicy/agent processing treats them as normal inbound. Both phone-number and UUID identification paths are handled.
  • What did NOT change (scope boundary): Loop protection is preserved. Other syncMessages (sentTranscripts to third parties, read receipts, etc.) and direct own-account messages are still dropped.

Change Type

  • Bug fix

Scope

  • Integrations

Linked Issue/PR

  • Closes #75870
  • Related: #5722 (original feature request with equivalent patch, closed via maintainer triage without review)
  • This PR fixes a bug or regression

Root Cause

  • Root cause: Loop-protection was implemented as "drop anything from own account; drop anything that's a syncMessage" — correct for preventing outbound replies from re-triggering the agent, but blanket-blocks legitimate Note-to-Self conversations on a linked-device personal-account setup.
  • Missing detection / guardrail: Implementation didn't distinguish syncMessages-to-self (legitimate inbound) from syncMessages-to-others (true outbound replays). Treating them the same is the bug.
  • Contributing context: This carve-out is the canonical pattern other Signal-cli bots use (signal-ai-chat-bot, signalbot, Hermes Agent). Requested by multiple users since Feb 2026.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
  • Target test or file: extensions/signal/src/monitor/event-handler.test.ts (or equivalent)
  • Scenario the test should lock in: syncMessage with destination === source (Note-to-Self) is promoted to dataMessage; destination !== source (third-party transcript) is still dropped; direct own-account non-sync messages still dropped.
  • If no new test is added, why not: Author doesn't have local pnpm/CI set up for this repo. Happy to add a unit test in a follow-up or per maintainer guidance.

User-visible / Behavior Changes

  • Linked-device deployments where signal-cli is paired to the operator's personal Signal account can now chat with the agent via Note-to-Self.
  • No new config flag; behavior is automatic when destination === source.
  • No change for dedicated-bot-number deployments (the typical pattern).

Diagram

Before:
phone -> Note-to-Self -> Signal server -> linked signal-cli -> envelope
   -> "syncMessage" in envelope -> RETURN (dropped)
   -> agent never sees it

After:
phone -> Note-to-Self -> Signal server -> linked signal-cli -> envelope
   -> envelope.syncMessage.sentMessage exists
   -> destination === source ? YES
   -> envelope.dataMessage = sentMessage; fall through
   -> agent processes as normal inbound (subject to allowFrom/dmPolicy)

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No (existing dmPolicy/allowFrom gates still apply)
  • Data access scope changed? No — only routing decision changes.

The patch only changes which messages get routed inbound. Existing access-control machinery still gates whether the agent processes them.

Repro + Verification

Environment

  • OS: macOS 15 (Apple Silicon M2 Max)
  • Runtime: [email protected] globally installed; daemon as launchd LaunchAgent
  • Model/provider: anthropic/claude-opus-4-7 (direct API)
  • Channel: Signal (signal-cli 0.14.3 linked as device)
  • Config: channels.signal.dmPolicy=allowlist, allowFrom=["+1xxxxx"] (operator's own number), groupPolicy=disabled

Steps

  1. Pair signal-cli as a linked device of operator's personal Signal account (signal-cli link -n "OpenClaw" + scan QR)
  2. Configure OpenClaw signal channel for the linked account
  3. From operator's phone, send a message to the "Note to Self" thread

Expected

  • Agent receives the message and responds in the same thread.

Actual (before patch)

  • Message silently dropped; no agent response in Note-to-Self.

Actual (after patch)

  • Agent processes Note-to-Self message and replies in the same thread.

Evidence

  • Trace/log snippets

Manually verified end-to-end against a working OpenClaw 2026.4.29 install with the equivalent patch applied to the bundled dist/monitor-D141zc1R.js (same logic). Note-to-Self bidirectional chat works; non-Note-to-Self syncMessages and direct own-account outbound are still correctly dropped (no spurious replies, no infinite loops over a multi-hour test session).

Human Verification

  • Verified scenarios:
    • Note-to-Self message from primary device (phone) → agent responds correctly ✅
    • Outbound message from agent to Note-to-Self → not re-processed (no loop) ✅
    • sentTranscript syncMessages to third parties → dropped (destination !== source) ✅
    • Other inbound (third-party DMs to operator) → unaffected by this change ✅
  • Edge cases checked:
    • UUID identification path (destinationUuid === sourceUuid)
    • Phone-number identification path (destinationNumber === sourceNumber)
    • Envelope with only one of phone/UUID populated — falsy guards handle gracefully
  • What I did not verify:
    • Did NOT run pnpm build && pnpm check && pnpm test locally (no local pnpm setup for this monorepo)
    • Did NOT add a new unit test
    • Did NOT run codex review --base origin/main locally

Compatibility / Migration

  • Backward compatible? Yes — behavior only changes for syncMessages with destination === source, which were previously dropped. No config or migration required.
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: Future Signal/signal-cli protocol changes could rename destinationNumber/destinationUuid fields.
    • Mitigation: Falsy-guarded checks (!!destNum && !!srcNum); missing fields cause the syncMessage to fall through to the existing "syncMessage" in envelope → return branch (preserves loop protection).

AI-assisted PR

  • Marked as AI-assisted (this section)
  • Degree of testing: lightly tested — manual end-to-end against a running daemon; no pnpm test suite run.
  • Confirm I understand what the code does: Yes. The patch promotes self-addressed syncMessage.sentMessage envelopes to dataMessage to allow Note-to-Self routing through the existing inbound pipeline.
  • Codex review: Did NOT run codex review --base origin/main locally (no local codex CLI setup); flagging for first-push CI review.
  • Bot review conversations: Will resolve any addressed bot conversations after first push.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • docs/channels/signal.md (modified, +6/-2)
  • extensions/signal/src/monitor/event-handler.ts (modified, +64/-11)

Code Example

> // Extract dataMessage from syncMessage if present
> if (envelope.syncMessage?.sentMessage && envelope.sourceDevice >= 1) {
>     // Only process if destination matches source (Note to Self)
>     const sentMessage = envelope.syncMessage.sentMessage;
>     const destination = sentMessage.destinationNumber || sentMessage.destination;
>     const source = envelope.sourceNumber || envelope.source;
>     
>     if (destination === source) {
>         // This is a Note to Self message
>         envelope.dataMessage = envelope.syncMessage.sentMessage;
>     } else {
>         // Ignore syncMessages to other recipients
>         return;
>     }
> }
>

---

> {"destination":"+4915144614539", "source":"+4915144614539"} // ✓ Processed
>

---

> {"destination":"+491746688612", "source":"+4915144614539"} // ✓ Ignored
>
RAW_BUFFERClick to expand / collapse

Update: Improved Solution

After further testing, I discovered an important issue with the initial implementation that required refinement:

Bug Found and Fixed

Problem: The initial code checked if destination was empty/undefined, assuming "Note to Self" messages would have no destination. However, in reality, "Note to Self" messages have the destination set to the user's own number.

This caused two issues:

  1. The bot would process ALL syncMessages (messages to everyone), not just "Note to Self"
  2. The bot would respond in "Note to Self" when the user messaged other people

Example of unwanted behavior: User writes to a friend: "Let's meet at 7pm" Bot responds in "Note to Self": "Hey, I think this message wasn't meant for me! 😅"

Corrected Code

The solution is to check if destination === source (user's own number):

// Extract dataMessage from syncMessage if present
if (envelope.syncMessage?.sentMessage && envelope.sourceDevice >= 1) {
    // Only process if destination matches source (Note to Self)
    const sentMessage = envelope.syncMessage.sentMessage;
    const destination = sentMessage.destinationNumber || sentMessage.destination;
    const source = envelope.sourceNumber || envelope.source;
    
    if (destination === source) {
        // This is a Note to Self message
        envelope.dataMessage = envelope.syncMessage.sentMessage;
    } else {
        // Ignore syncMessages to other recipients
        return;
    }
}

Verification

Tested with the following scenarios:

Sending message to "Note to Self" → Bot responds correctly
Sending message to another person → Bot ignores it (no unwanted responses)
Receiving messages from others → Bot processes normally

Log Example

Note to Self message:

{"destination":"+4915144614539", "source":"+4915144614539"} // ✓ Processed

Message to friend:

{"destination":"+491746688612", "source":"+4915144614539"} // ✓ Ignored

This refined solution ensures the bot only responds to actual "Note to Self" messages and doesn't interfere with private conversations.

Originally posted by @ipecxx in #5722

hi, currently the signal functionality is basically unusable. outbound messages to openclaw through signal aren't received. i implemented a patch (or a variant, just asked claude to implement this patch) and it made signal functional / useable. signal seems like potentially a major channel, maybe worth implementing? its a small fix

extent analysis

TL;DR

The issue with Signal functionality can be resolved by implementing a patch that fixes the outbound message reception.

Guidance

  • Review the patch implemented by the user to understand the specific changes made to fix the Signal functionality.
  • Verify that the patch correctly handles outbound messages to OpenClaw through Signal.
  • Test the patch with various scenarios to ensure it doesn't introduce any new issues.
  • Consider implementing the patch as a permanent fix to support Signal as a major channel.

Example

No code snippet is provided as the issue doesn't contain specific code changes made by the patch.

Notes

The issue lacks detailed information about the patch and its implementation, so it's essential to review and test the changes carefully before applying them.

Recommendation

Apply the workaround by implementing the patch, as it has been reported to make Signal functional and usable, and it's a small fix.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING