Skip to content

[codex] Add WhatsApp phone-code login#85866

Open
VishalJ99 wants to merge 5 commits into
openclaw:mainfrom
VishalJ99:codex/whatsapp-phone-code-login
Open

[codex] Add WhatsApp phone-code login#85866
VishalJ99 wants to merge 5 commits into
openclaw:mainfrom
VishalJ99:codex/whatsapp-phone-code-login

Conversation

@VishalJ99

@VishalJ99 VishalJ99 commented May 23, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add openclaw channels login --phone-number <number> to the generic channel auth adapter and CLI
  • implement WhatsApp phone-code pairing through Baileys as a headless/QR-free login fallback, including cleanup for stale partial phone-code credentials
  • document the headless phone-code flow, the QR-unavailable use case, and the optional trunk-prefix caveat for international numbers

Why

QR-based WhatsApp linking can be awkward or impossible in headless setups, and it can fail when the phone scanner does not pick up the terminal/dashboard QR. The phone-number pairing flow creates the same saved WhatsApp Web credentials after a one-time code entry on the phone, so the CLI can continue normally afterward.

Closes #85867.
Refs #15614, #85868.

Real behavior proof

Behavior addressed: WhatsApp linking when QR scanning is unavailable or unreliable from a headless gateway host.

Real environment tested: local OpenClaw source checkout running against a physical Android WhatsApp device and a named WhatsApp account, with private identifiers redacted.

Exact steps or command run after this patch: ran openclaw channels login --channel whatsapp --account <account> --phone-number <country-code-and-number>, entered the printed pairing code on the phone under WhatsApp > Linked Devices > Link with phone number using an ADB-controlled phone UI, restarted the gateway during the native Logging in... / 515 phase, then ran openclaw channels status --channel whatsapp --account <account> --probe.

Evidence after fix: OpenClaw printed a pairing code, the phone accepted it in the linked-device code flow, OpenClaw then logged WhatsApp asked for a restart after pairing (code 515); waiting for creds to save…, WhatsApp Web connected., and Linked after restart; web session ready.

Observed result after fix: final channel status was linked, healthy, running, and connected with no last error; the phone's Linked Devices screen showed an active web session.

What was not tested: a completely unattended flow with no reachable phone UI was not tested. The gateway/operator side can be headless when the phone UI is remotely controllable, such as Android over ADB or an iPhone via a simulator/remote-control path; this PR does not change broader 515 restart recovery behavior beyond documenting the observed sequence.

Verification

  • pnpm test extensions/whatsapp/src/login.test.ts extensions/whatsapp/src/login.coverage.test.ts extensions/whatsapp/src/login-qr.test.ts extensions/whatsapp/src/auth-store.test.ts extensions/whatsapp/src/accounts.whatsapp-auth.test.ts src/cli/channel-auth.test.ts
  • pnpm check:changed
  • pnpm build
  • subagent self-review returned no findings after the readiness timer fix

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: whatsapp-web Channel integration: whatsapp-web app: macos App: macos cli CLI command changes size: L triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 23, 2026
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

Codex review: found issues before merge. Reviewed July 11, 2026, 12:53 AM ET / 04:53 UTC.

Summary
This PR adds a generic phone-number channel login input, a WhatsApp Baileys phone-code pairing flow, stale partial-credential cleanup, and related CLI, docs, and tests, alongside unrelated policy, changelog, and test edits.

PR surface: Source +343, Tests +229, Docs +26. Total +598 across 22 files.

Reproducibility: yes. for the introduced retry defect from source: trigger the existing 408 timeout recovery after the initial phone code, and the replacement socket is installed without another requestPairingCode call. This read-only review did not run a live timeout scenario.

Review metrics: 3 noteworthy metrics.

  • Public login surface: 1 CLI option and 1 shared auth input added. The patch expands both the documented CLI contract and the plugin-facing channel authentication contract.
  • Persisted auth classification: 1 partial-credential state added. The patch changes whether an existing WhatsApp credential file is accepted as linked or removed before retry.
  • Unrelated surfaces: 3 files outside feature ownership. Root policy, release-owned changelog, and a document-extractor test increase merge and review scope without implementing phone-code login.

Stored data model
Persistent data-model change detected: serialized state: extensions/whatsapp/src/auth-store.test.ts, serialized state: extensions/whatsapp/src/auth-store.ts, serialized state: extensions/whatsapp/src/creds-files.ts, serialized state: extensions/whatsapp/src/session.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #85867
Summary: This PR and the maintainer replacement are competing candidate fixes for the canonical phone-code login issue; the adjacent 515 report remains separate session-finalization work.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Consolidate on one typed API branch and fix both blocking findings.
  • Repeat the redacted physical-device pairing proof on the exact final canonical head, including a timeout/replacement retry.

Risk before merge

  • [P2] A timeout-triggered replacement socket can wait without presenting a fresh phone code, leaving the new login flow unusable after its built-in 408 recovery.
  • [P1] When partial credentials require cleanup but deletion is refused for ownership or path-safety reasons, this branch cannot distinguish that failure from no cleanup being necessary and continues with unresolved auth state.
  • [P1] The branch adds a raw phoneNumber field to the shared plugin auth adapter while the maintainer replacement defines a typed, extensible login-method contract.
  • [P1] Root policy, release-owned changelog, and an unrelated document-extractor test are mixed into the auth/session feature branch.

Maintainer options:

  1. Consolidate and prove the replacement (recommended)
    Transfer the useful live evidence and unique coverage to the typed maintainer branch, then verify physical-device pairing on its exact final head.
  2. Repair this branch in place
    Add per-replacement code issuance, fail-closed cleanup, and the typed API while removing unrelated branch changes before another review.
  3. Pause both branches
    Keep both open only if maintainers need more API design evidence before selecting the permanent channel login contract.

Next step before merge

  • [P2] A maintainer must select the canonical shared API and branch; after that choice, the two concrete runtime defects have narrow repairs.

Maintainer decision needed

  • Question: Should the typed channel login-method contract in feat: add WhatsApp phone-code login #101294 become canonical, with this PR's live proof and unique coverage transferred before this branch closes?
  • Rationale: Both open PRs implement the same capability, but the replacement has the stronger API and retry design while this PR has the stronger real-device proof; automation cannot safely choose the permanent plugin contract or discard either evidence set.
  • Likely owner: mcaxtr — They own the open maintainer replacement and its proposed permanent shared login-method contract.
  • Options:
    • Consolidate on typed replacement (recommended): Use the maintainer replacement as the canonical branch, transfer or repeat this PR's physical-device proof, then close this branch once the replacement is proof-positive.
    • Repair this branch: Retain this branch only if it adopts the typed API and replacement-socket hardening while dropping unrelated policy, changelog, and test changes.

Security
Cleared: The diff adds no dependency, workflow, permission, secret-access, or downloaded-code surface; credential path protections remain intact, with cleanup handling reported as a functional state defect.

Review findings

  • [P1] Request a fresh code on timeout replacement sockets — extensions/whatsapp/src/login.ts:234-236
  • [P2] Surface refused stale-credential cleanup — extensions/whatsapp/src/login.ts:197-201
Review details

Best possible solution:

Consolidate on the typed login-method implementation, prepare every replacement socket for a fresh code, fail closed when detected partial auth cannot be safely cleared, and carry the contributor's physical-device proof onto the final canonical head.

Do we have a high-confidence way to reproduce the issue?

Yes for the introduced retry defect from source: trigger the existing 408 timeout recovery after the initial phone code, and the replacement socket is installed without another requestPairingCode call. This read-only review did not run a live timeout scenario.

Is this the best way to solve the issue?

No. The happy path is real-device proven, but the best solution uses the typed shared login-method contract, prepares every replacement socket, and stops rather than continuing when detected partial auth cannot be cleared safely.

Full review comments:

  • [P1] Request a fresh code on timeout replacement sockets — extensions/whatsapp/src/login.ts:234-236
    The code requests a pairing code only on the initial socket. waitForWhatsAppLoginResult can replace that socket after a 408 timeout, but this callback only updates the reference, so the replacement waits without ever presenting a new code. Prepare each replacement socket and call requestPairingCode again before waiting.
    Confidence: 0.98
  • [P2] Surface refused stale-credential cleanup — extensions/whatsapp/src/login.ts:197-201
    The cleanup helper returns the same false value when no cleanup is needed and when detected partial state cannot be removed safely. The caller therefore continues in the latter case with the stale state it intended to remove; return a closed result that distinguishes these cases and fail with an actionable error when cleanup is refused.
    Confidence: 0.92

Overall correctness: patch is incorrect
Overall confidence: 0.94

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 6595d1756b1a.

Label changes

Label changes:

  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR body provides after-fix physical Android pairing evidence, observed pairing and restart logs, and final linked healthy status with private identifiers redacted.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦐 gold shrimp, so this older rating label is no longer current.
  • remove status: 👀 ready for maintainer look: Current PR status label is status: ⏳ waiting on author.

Label justifications:

  • P2: This is a valuable but bounded WhatsApp onboarding feature whose retry defects block merge without creating an urgent current-main regression.
  • merge-risk: 🚨 compatibility: The PR changes a public CLI contract and shared plugin auth API while a different typed permanent contract is under maintainer review.
  • merge-risk: 🚨 auth-provider: The timeout recovery path can replace the login socket without generating a usable new authentication code.
  • merge-risk: 🚨 session-state: The patch reclassifies and conditionally deletes persisted WhatsApp pairing credentials but cannot reliably surface refused cleanup.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (live_output): The PR body provides after-fix physical Android pairing evidence, observed pairing and restart logs, and final linked healthy status with private identifiers redacted.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body provides after-fix physical Android pairing evidence, observed pairing and restart logs, and final linked healthy status with private identifiers redacted.
Evidence reviewed

PR surface:

Source +343, Tests +229, Docs +26. Total +598 across 22 files.

View PR surface stats
Area Files Added Removed Net
Source 11 379 36 +343
Tests 6 237 8 +229
Docs 5 34 8 +26
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 22 650 52 +598

What I checked:

  • Real-device proof: The PR body documents a physical Android phone accepting the generated code, observed 515 recovery logs, and a final linked, healthy, connected channel state. (24f18c05bee1)
  • Timeout replacement gap: The initial socket receives requestPairingCode, but the timeout recovery callback only assigns the replacement socket and never prepares it or requests another code. (extensions/whatsapp/src/login.ts:234, 24f18c05bee1)
  • Upstream socket contract: Baileys 7.0.0-rc13 emits connecting for each created socket, while requestPairingCode writes pairing identity and code into that socket's auth state; a replacement therefore needs its own request. (extensions/whatsapp/package.json:12, 24f18c05bee1)
  • Competing canonical implementation: The maintainer-authored replacement adds a typed channel login method, per-replacement socket preparation, cleanup failure handling, and focused retry tests, but explicitly reports no live physical-device pairing proof. (src/channels/plugins/channel-login-method.types.ts:1, 7d80bcfbf96c)
  • Feature history: Current WhatsApp login and auth behavior was shaped by lifecycle, 515 recovery, auth detection, credential security, and plugin-boundary changes, indicating shared historical ownership. (extensions/whatsapp/src/login.ts:1, aa023e428306)

Likely related people:

  • mcaxtr: Authored the maintainer-labeled replacement for the same canonical issue and added the typed API, timeout replacement, and credential-safety hardening relevant here. (role: replacement implementation owner; confidence: high; commits: d9b765828b60, 312acae88161, aa7a6ea82c62; files: src/channels/plugins/channel-login-method.types.ts, src/plugin-sdk/channel-contract.ts, extensions/whatsapp/src/login.ts)
  • steipete: Authored major merged WhatsApp auth detection, identity handling, plugin SDK boundary, and channel architecture changes around the affected paths. (role: feature-history owner; confidence: high; commits: 6320f739d4e7, 3b6d980c52c3, 9ebe38b6e36b; files: extensions/whatsapp/src/auth-store.ts, src/channels/plugins/types.adapters.ts)
  • Jason: Implemented the merged WhatsApp 515 pairing recovery behavior that the new phone-code flow reuses and must preserve. (role: adjacent behavior contributor; confidence: medium; commits: 9d3e653ec9d2; files: extensions/whatsapp/src/login.ts, extensions/whatsapp/src/connection-controller.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (1 earlier review cycle)
  • reviewed 2026-06-24T16:18:29.063Z sha c217d0e :: needs maintainer review before merge. :: none

@VishalJ99
VishalJ99 force-pushed the codex/whatsapp-phone-code-login branch from 1d69ab0 to 1ffc9a0 Compare May 23, 2026 23:30
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 23, 2026
@VishalJ99
VishalJ99 marked this pull request as ready for review May 23, 2026 23:37
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels May 23, 2026
@clawsweeper

clawsweeper Bot commented May 23, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Clockwork Branchling

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: keeps receipts.
Image traits: location flaky test forest; accessory rollback rope; palette violet, aqua, and starlight; mood curious; pose nestled inside a glowing shell; shell frosted glass shell; lighting soft studio lighting; background soft code-shaped tiles.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Clockwork Branchling in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@VishalJ99
VishalJ99 force-pushed the codex/whatsapp-phone-code-login branch from 0546421 to 20670fe Compare May 23, 2026 23:48
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels May 24, 2026
@VishalJ99
VishalJ99 force-pushed the codex/whatsapp-phone-code-login branch from 20670fe to 518b110 Compare May 24, 2026 06:59
@openclaw-barnacle openclaw-barnacle Bot removed the gateway Gateway runtime label May 24, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels May 24, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label May 24, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels May 24, 2026
@BingqingLyu

This comment was marked as spam.

@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jun 15, 2026
@vincentkoc
vincentkoc force-pushed the codex/whatsapp-phone-code-login branch from c217d0e to 24f18c0 Compare July 11, 2026 04:31
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 11, 2026
@jamaloff28-coder

Copy link
Copy Markdown

Whatsapp login

@clawsweeper

clawsweeper Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: [codex] Add WhatsApp phone-code login This is item 1/1 in the current shard. Shard 10/22.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos channel: whatsapp-web Channel integration: whatsapp-web cli CLI command changes docs Improvements or additions to documentation merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: L status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WhatsApp QR-unavailable/headless login needs phone-code fallback

3 participants