Skip to content

fix(whatsapp): populate senderE164 for direct chats to enable owner commands#247

Merged
steipete merged 2 commits into
openclaw:mainfrom
imfing:fix/whatsapp-direct-chat-sender
Jan 5, 2026
Merged

fix(whatsapp): populate senderE164 for direct chats to enable owner commands#247
steipete merged 2 commits into
openclaw:mainfrom
imfing:fix/whatsapp-direct-chat-sender

Conversation

@imfing

@imfing imfing commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes owner commands (/status, /help) not working in WhatsApp direct chats by correctly populating senderE164 from the conversation's from number.

Root Cause

  • /status and /help are gated in src/auto-reply/reply/commands.ts, returning early unless command.isAuthorizedSender is true
  • isAuthorizedSender is built from senderE164 + whatsapp.allowFrom configuration
  • The original code only populated senderE164 from participantJid (which only exists in group messages to identify the group member who sent it)
  • In direct chats, participantJid is undefined, leaving senderE164 as null and causing the global owner check to fail

Fix

Set senderE164 appropriately for both contexts:

  • Group chats: use participantJid (the group member who sent the message)
  • Direct chats: use from (the person you're chatting with)

Note: Group-only logic in src/web/auto-reply.ts controls mention requirements for /activation and /status, but doesn't remove the owner check. The authorization gate is global; groups just have additional mention gating on top.

@imfing

imfing commented Jan 5, 2026

Copy link
Copy Markdown
Contributor Author

manually verified in whatsapp:

@steipete

steipete commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Xin, thanks for your contribution!

@steipete steipete merged commit a6a45f4 into openclaw:main Jan 5, 2026
13 checks passed
@steipete

steipete commented Jan 5, 2026

Copy link
Copy Markdown
Contributor

Thanks for the fix! Merged; I added a regression test + changelog entry in main (commit 291c6f3).

@imfing imfing deleted the fix/whatsapp-direct-chat-sender branch January 6, 2026 00:30
@imfing

imfing commented Jan 6, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the great work! 🙌

dgarson added a commit to dgarson/clawdbot that referenced this pull request Feb 9, 2026
* feat: tool journal/diagnostics

* feat: journal fixes
dgarson added a commit to dgarson/clawdbot that referenced this pull request Feb 22, 2026
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
matin added a commit to matin/openclaw that referenced this pull request Jun 9, 2026
…aw#247) (#17)

* feat(speech): native audio output via Vertex ADC route (tulgey openclaw#247)

The Google speech provider already emits native generateContent AUDIO
(gemini-3.1-flash-tts-preview, responseModalities:['AUDIO'] + speechConfig)
and already transcodes to opus-in-ogg for voice-note delivery. The only
gap was auth: it knew the AI-Studio key route only and threw "Google API
key missing" on a keyless Vertex deployment (tulgey #10). This adds the
Vertex ADC route so native output is the primary path on the deployment.

- Add a Vertex ADC synthesis route (synthesizeGoogleVertexTtsPcm) that
  rides resolveGoogleVertexAuthorizedUserHeaders (the same ADC bearer the
  Google chat/Veo paths use), POSTing to
  aiplatform.googleapis.com/v1/projects/{P}/locations/{global}/publishers/
  google/models/{model}:generateContent. Body, PCM extraction, WAV-wrap,
  and opus transcode are shared verbatim with the AI-Studio route.
- Route selection (resolveGoogleTtsPcm): AI-Studio key route stays primary;
  fall to the Vertex ADC route when no key but ADC is present; throw with
  neither so the speech provider-order fallback (Cloud TTS -> text) trips
  on a detected failure, never a silent degrade (ADR 0024 clause 2).
- isConfigured is now ADC-aware so the provider is selected keyless.
- Extract buildGoogleSpeechGenerateContentBody (shared by both routes).
- Test: Vertex generateContent URL shape (global + regional).

Implements the membrane row of tulgey#247 / ADR 0024. Existing AI-Studio
tests unaffected (real keys take the unchanged route).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(google): clear pre-existing oxlint errors in the Veo provider

lint:extensions:bundled lints the whole extensions/google package, so
these errors (introduced with the Veo REST fallback in #5, never linted
since no later PR touched the package) block any PR that touches the
extension. Surfaced by the native-audio-output change.

- resolveVertexOAuthToken: brace the metadata-token if, type res.json()
  as { access_token?: string } (drops the unnecessary `as any`), and
  omit the unused catch binding.
- brace the "Force rest fallback for Vertex" guard.

No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(speech): route Vertex TTS through guarded postJsonRequest

The new Vertex ADC route used a raw fetch(), which trips the
no-raw-channel-fetch boundary guard. Route it through postJsonRequest
(the same guarded helper the AI-Studio route uses) so SSRF/dispatcher
policy and timeout handling apply uniformly; drop the manual
AbortController.

Also allowlist the pre-existing Veo metadata-server fetch
(video-generation-provider.ts:44, http://metadata.google.internal —
link-local, must be raw; the SSRF guard intentionally blocks it). It
predates this work and was surfaced when the PR first touched the
package.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
matin added a commit to matin/openclaw that referenced this pull request Jun 9, 2026
…o-accented (tulgey openclaw#251) (#18)

Without speechConfig.languageCode, Gemini TTS infers the spoken language
from the text's script: Arabic -> Persian (Farsi correct), but Latin
defaults to English, so Latin-script Spanish was read with an English
accent. Add an optional, omit-when-absent languageCode to the shared
generateContent body and resolve it per turn by precedence:
directive/talk override > operator config > Spanish auto-detection > omit.

Omit-when-absent preserves Gemini's script-based auto-selection (the
Arabic-script -> Persian path Farsi relies on). The auto-detector abstains
unless it is confident the text is Spanish (stopword scorer + inverted
punctuation; never touches non-Latin scripts and strips the audio-profile
wrapper before scoring), so Farsi keeps its Persian voice and English stays
English. Default detected locale es-MX; operators can pin a locale via
config/`[[tts:language=...]]` or disable detection with detectLanguage:false.

Refs tulgey openclaw#247 / ADR 0024.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.

2 participants