Fix/whatsapp channel bugs#2554
Closed
dvirarad wants to merge 7 commits into
Closed
Conversation
…resh - Install WhatsApp adapter from upstream/channels per /add-whatsapp skill - Baileys 7.0.0-rc.9 + qrcode + pino pinned - Patch 5: strip orphan UTF-16 surrogates from inbound content (Patches 2/3/4/6 already in v2 channels branch) - google-oauth-refresh.ts: refresh ~/.gmail-mcp + ~/.calendar-mcp tokens before container spawn if expiring within 10 min Tests: 323 passed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…P remote Dockerfile: - poppler-utils system dep for pdftotext (PDF reader) - @gongrzhe/server-gmail-autoauth-mcp@1.1.11 + zod-to-json-schema@3.22.5 pinned - mcp-remote@0.1.29 pinned for external MCP server support - pdf-reader CLI installed to /usr/local/bin/pdf-reader container/skills/pdf-reader/: SKILL.md + pdftotext wrapper script (ported from v1) Voice transcription: - New src/transcription.ts: OpenAI Whisper API call, reads audio from disk - Wired into v2 whatsapp.ts after downloadInboundMedia: voice messages get transcribed and prepended to content Gmail-tool: Dockerfile install only (Phase 2). Phase 3 per-agent-group container.json wiring deferred to deployment time. MCP remote: Dockerfile install only. Per-agent-group MCP server registration via container_configs DB at deployment time. NOT ported (obsolete in v2): - Image vision (sharp resize): Claude Code's Read tool handles images natively - Multimodal image content blocks: same — Read tool gives agent vision - Gmail-as-channel: v2 uses gmail-as-tool model; original inbound polling deferred (user can rebuild later if needed) Build: clean. Tests: 323 passed. Typecheck: clean. Eslint: 19 pre-existing warnings (no new errors). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The lockfile was previously generated with pnpm 8.9.2 (local Homebrew install) which produced a v8 format incompatible with the packageManager-declared pnpm@10.33.0. Server pnpm 11.1.0 (via corepack) refused the v8 lockfile during migrate-v2.sh bootstrap, blocking the migration. Build clean, 323 tests pass with the regenerated lockfile. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…at groups)
v2's whatsapp.ts unconditionally dropped fromMe=true messages in non-self-chat
groups, assuming ASSISTANT_HAS_OWN_NUMBER=true. With the v1 shared-number setup
(bot uses the user's own WhatsApp number), every message the user types in any
group is fromMe=true and was being silently filtered before reaching the router.
Symptom: bot ignored user messages in group chats wired to non-self-chat
agent groups (Workshop Andy, Andy LinkedIn, etc.). The Channel metadata
"discovered" event fired but no "Message routed" followed.
Fix: in fromMe filter, only skip non-self-chat fromMe messages when:
- sentMessageCache hits (we just sent them), OR
- ASSISTANT_HAS_OWN_NUMBER=true (dedicated-number mode), OR
- content starts with `${ASSISTANT_NAME}:` (shared-number bot echo prefix)
Otherwise process — it's the user typing on the shared phone.
Deployed live to server first, then back-ported here. Tests still 323/323.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ed groups Previously every new phone number that DMed the bot triggered a "💬 New direct message" approval card sent to the owner's main DM. With ~17 inbound contacts post-migration, this became spam. Change default for `createMessagingGroup` (auto-created on first inbound from unknown sender) from 'request_approval' → 'strict'. Strangers are now silently dropped. The owner can manually wire trusted contacts via ncl messaging-groups update / wirings create when needed. Server-side: ran SQL UPDATE on existing 17 'request_approval' rows to 'strict' as a separate hot fix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…data/attachments/
Symptom: agent receives messages like `[image: photo.jpg — saved to
/workspace/attachments/photo.jpg]` but /workspace/attachments/ doesn't
exist inside the container, so `Read` returns "directory not found."
Affects images, voice notes, PDFs.
Root cause: downloadInboundMedia wrote to `${DATA_DIR}/attachments/`
on the host, but data/attachments/ is not mounted into any agent
container. The path rendered in the agent's prompt referenced a
phantom location.
Fix:
- Resolve the wired agent group's folder from chatJid via
getMessagingGroupByPlatform → getMessagingGroupAgents (priority DESC)
→ getAgentGroup. Skip download for cold-DM / unwired senders.
- Save to ${GROUPS_DIR}/<folder>/attachments/<file> instead. The group
folder is mounted at /workspace/agent/, so files land at
/workspace/agent/attachments/<file> in the container.
- Set localPath: "agent/attachments/<file>" so the formatter renders
/workspace/agent/attachments/<file> (formatter prepends /workspace/).
- Return both localPath (container-relative) and hostPath (absolute,
for host-side consumers like transcription). Strip hostPath before
serializing attachments into messages_in.
- transcribeAudioFile now called with audio.hostPath (absolute path)
instead of audio.localPath, since localPath is no longer resolvable
against DATA_DIR after this change.
Multi-agent caveat: when one messaging group is wired to several agent
groups (priority list), the file lands only in the highest-priority
group's folder. Documented in a code comment; not relevant to the
current 1:1 wiring setup.
Tests: 323/323 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The WhatsApp adapter hardcoded `isMention: !isGroup ? true : undefined`, so a mention of the assistant inside a group was never flagged as a mention. The router then dropped the message at the unknown-group gate (router.ts auto-creates a messaging_group only when isMention is true), so new groups never produced an approval card and the agent silently ignored them. Run the configured TRIGGER_PATTERN against the message content for group messages too. DMs keep their always-true behavior since they are addressed to the bot by definition. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Collaborator
|
Closing as there is no description and it contains many unrelated code changes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of Change
.claude/skills/<name>/, no source changes)Description
For Skills