Skip to content

feat: add WhatsApp phone-code login#101294

Open
mcaxtr wants to merge 16 commits into
mainfrom
codex/whatsapp-phone-code-login-clean
Open

feat: add WhatsApp phone-code login#101294
mcaxtr wants to merge 16 commits into
mainfrom
codex/whatsapp-phone-code-login-clean

Conversation

@mcaxtr

@mcaxtr mcaxtr commented Jul 7, 2026

Copy link
Copy Markdown
Member

Closes #85867

What Problem This Solves

Fixes an issue where users connecting WhatsApp from a headless, remote, or QR-unavailable environment had no first-class alternative to scanning a QR code.

It also fixes a retry edge case where an interrupted phone-code attempt could leave partial Baileys credentials on disk. Those incomplete credentials could be mistaken for a linked account and prevent a clean QR or phone-code retry.

Why This Change Was Made

WhatsApp now owns an interactive login choice inside its existing channel login callback, following the established plugin-local setup pattern. Running openclaw channels login --channel whatsapp prompts the user to either scan a QR code or link with a phone number; QR remains the default choice.

The WhatsApp plugin owns phone-number validation, Baileys requestPairingCode handling, pairing-code display, socket restart behavior, and stale partial-credential cleanup. The cleanup reuses the existing credential-save queue and logout ownership checks so it cannot race a completed pairing save or delete an unmanaged auth directory.

Baileys 7.0.0-rc13 derives linked-device metadata differently across its QR and phone-code pairing paths. During QR registration, OpenClaw's existing "cli" client name falls back to the Chrome platform type while preserving "openclaw" as the device name, producing the observed Google Chrome (openclaw) label. Phone-code pairing maps the browser name separately and sends its companion platform type and display metadata directly, so the same "cli" tuple would not carry the Chrome identity.

Rather than introduce a phone-code-only browser override, every WhatsApp socket now uses the canonical ["openclaw", "Chrome", VERSION] tuple. This keeps one socket-identity definition across QR, phone-code pairing, startup, and reconnect. Based on the metadata Baileys sends, both pairing methods are expected to appear as Google Chrome (openclaw); physical-device verification remains outstanding.

This normalization does not re-pair or rename existing linked accounts. With saved credentials, Baileys uses its authenticated login path; under OpenClaw's current socket settings, the old "cli" and new "Chrome" tuples produce a byte-identical login payload. Normal startup and reconnect continue using the established session credentials.

This PR adds no production core CLI, channel-login, or Plugin SDK contract.

User Impact

Users can link WhatsApp in either of two ways from the same command:

  • Scan QR code — the existing default flow.
  • Link with phone number — enter a number with country code, then enter the generated pairing code in WhatsApp under Linked Devices → Link with phone number.

Both methods are expected to create the same Google Chrome (openclaw) Linked Devices identity. Existing linked sessions, account selection through --account, and normal send/receive/status behavior remain on the existing WhatsApp session path.

If phone-code pairing is interrupted, OpenClaw no longer reports the partial credentials as linked. A later QR or phone-code login can safely clear managed stale state and retry.

Evidence

Validated on exact head 336aa3f33c0ed427250d43fae60e8d82dbb2cf12:

  • Focused CLI and WhatsApp Testbox proof: 155 tests passed on Blacksmith Testbox tbx_01kx96g5keh29qervsrk57kzq2.
  • Full changed-surface gate passed on Blacksmith Testbox tbx_01kx98stb6n0rpjfffx3x2ccev:
    • pnpm check:changed
  • Full production build passed on the same Testbox:
    • pnpm build
  • Whitespace validation passed:
    • git diff --check
  • GitHub CI completed with no failing or pending relevant checks.
  • A read-only master quality gate reconciled all 23 changed paths, found the implementation scope-fit, and reported no code findings.

Remaining proof gap: this exact head has not been exercised against a physical WhatsApp device. Before merge, live verification should cover phone-number pairing and its native restart, QR login, an existing linked session, and the Google Chrome (openclaw) Linked Devices label.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: whatsapp-web Channel integration: whatsapp-web cli CLI command changes size: L maintainer Maintainer-authored PR labels Jul 7, 2026
@clawsweeper

clawsweeper Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 12, 2026, 12:02 AM ET / 04:02 UTC.

Summary
Adds a plugin-owned interactive WhatsApp QR-or-phone-code login flow, phone-number normalization, partial-credential recovery, socket restart handling, browser identity normalization, tests, documentation, and a phone-number parsing dependency.

PR surface: Source +499, Tests +812, Docs +3, Config +1, Other +8. Total +1323 across 28 files.

Reproducibility: not applicable. as a conventional bug reproduction: this PR adds a new pairing mode, while the headless limitation and partial-credential state are source-clear and the competing PR demonstrates phone-code pairing on a physical device.

Review metrics: 1 noteworthy metric.

  • Dependency surfaces: 1 direct plugin dependency added; 2 resolved graphs changed. The phone parser becomes part of the shipped WhatsApp package and requires explicit dependency authorization before merge.

Stored data model
Persistent data-model change detected: serialized state: extensions/whatsapp/src/auth-store.test.ts, serialized state: extensions/whatsapp/src/session.ts, unknown-data-model-change: extensions/whatsapp/src/session.test.ts, unknown-data-model-change: 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 older open PR are competing candidate fixes for the same canonical headless WhatsApp login issue.

Members:

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

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof is added.

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

Rank-up moves:

  • [P1] Add redacted exact-head physical-device proof for phone-code pairing, QR pairing, interrupted retry, and existing-session reconnect.
  • Obtain dependency-graph authorization for the current head.
  • Confirm the plugin-local login surface as the canonical direction.

Proof guidance:

  • [P1] Needs real behavior proof before merge: This exact head has no after-fix physical-device evidence for phone-code pairing, QR pairing, interrupted retry, existing-session reconnect, or linked-device identity; add redacted logs or a recording, update the PR body, and ask a maintainer for @clawsweeper re-review if a fresh review does not trigger.

Risk before merge

  • [P1] Existing linked users will create future sockets with a different browser identity tuple; source analysis supports compatibility, but only an exact-head physical-device reconnect proves the upgrade path.
  • [P1] Interrupted and completed pairing state is now classified and cleaned differently across status, setup, QR login, and phone-code retry paths; the tests are strong, but real Baileys persistence timing remains unproven on this head.
  • [P1] The new direct runtime dependency changes the shipped WhatsApp package graph and cannot merge without explicit repository authorization.

Maintainer options:

  1. Prove and authorize this head (recommended)
    Keep the plugin-local implementation, add exact-head physical-device and upgrade proof, and obtain dependency-graph authorization.
  2. Choose the competing API surface
    Use [codex] Add WhatsApp phone-code login #85866 only if maintainers intentionally accept its generic CLI and Plugin SDK contract.
  3. Pause both implementations
    Hold both PRs if no permanent WhatsApp login surface is currently sponsored.

Next step before merge

  • [P2] A maintainer must choose the canonical public login surface, review exact-head physical-device evidence, and authorize the dependency graph before merge.

Maintainer decision needed

  • Question: Should WhatsApp phone-code login ship as this PR's plugin-owned interactive choice rather than the generic --phone-number channel-auth surface in [codex] Add WhatsApp phone-code login #85866?
  • Rationale: Both implementations solve the same canonical issue but establish different permanent public interfaces; technical review cannot choose the CLI and Plugin SDK product contract without maintainer intent.
  • Likely owner: steipete — Recent merged history owns the channel login entrypoint, QR runtime routing, Plugin SDK boundary, and overall public-surface decisions adjacent to this choice.
  • Options:
    • Use plugin-local prompt (recommended): Keep QR as the default interactive choice inside the WhatsApp plugin without expanding generic channel-auth APIs.
    • Use generic CLI flag: Adopt the competing PR's explicit --phone-number contract and maintain the broader CLI and SDK compatibility surface.
    • Pause both candidates: Keep the canonical issue open until maintainers sponsor a different permanent login UX.

Security
Cleared: The pinned dependency and lock entries are consistent, and credential cleanup remains bounded by managed-directory, regular-file, and symlink ownership guards.

Review details

Best possible solution:

Ship one canonical plugin-local login flow with QR as the default, retain the serialized managed-auth recovery design, and merge only after redacted exact-head device evidence proves phone-code pairing, QR pairing, interrupted retry, existing-session reconnect, and linked-device identity, with the dependency graph explicitly approved.

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

Not applicable as a conventional bug reproduction: this PR adds a new pairing mode, while the headless limitation and partial-credential state are source-clear and the competing PR demonstrates phone-code pairing on a physical device.

Is this the best way to solve the issue?

Yes for architecture: the plugin-local prompt is narrower and better aligned with channel ownership than a generic CLI flag, but merge still requires product confirmation, exact-head device proof, and dependency authorization.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P2: This is a meaningful but channel-scoped authentication improvement with bounded blast radius.
  • merge-risk: 🚨 compatibility: The PR changes the interactive login UX and browser identity used by every newly created WhatsApp socket.
  • merge-risk: 🚨 session-state: The PR changes persisted credential classification and stale-state deletion across login, status, and setup paths.
  • merge-risk: 🚨 auth-provider: The PR changes WhatsApp pairing, reconnect, and authentication persistence behavior.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: This exact head has no after-fix physical-device evidence for phone-code pairing, QR pairing, interrupted retry, existing-session reconnect, or linked-device identity; add redacted logs or a recording, update the PR body, and ask a maintainer for @clawsweeper re-review if a fresh review does not trigger.
Evidence reviewed

PR surface:

Source +499, Tests +812, Docs +3, Config +1, Other +8. Total +1323 across 28 files.

View PR surface stats
Area Files Added Removed Net
Source 13 650 151 +499
Tests 9 993 181 +812
Docs 4 10 7 +3
Config 1 2 1 +1
Generated 0 0 0 0
Other 1 8 0 +8
Total 28 1663 340 +1323

What I checked:

  • Plugin-local entry point: The public channel login callback delegates method selection to a WhatsApp-owned runtime flow, preserving the core and Plugin SDK boundary. (extensions/whatsapp/src/channel.ts:197, 793617f96c70)
  • Auth lifecycle safety: Login preparation waits for queued credential writes, serializes cleanup through the same keyed queue, preserves completed pairing state, and restricts deletion through existing managed-directory and symlink checks. (extensions/whatsapp/src/auth-store.ts:321, 793617f96c70)
  • Upstream pairing contract: Baileys rc13 sets pairingCode and me for an in-progress phone-code attempt, then emits completed credentials before the pair-success restart; the branch's partial-state predicate and queued re-read match that ordering. (extensions/whatsapp/src/auth-store.ts:120, 793617f96c70)
  • Existing-session compatibility: Under the current socket settings, Baileys authenticated login payload generation does not derive fields from the changed browser tuple; the tuple affects registration platform identity, while physical-device upgrade proof remains required. (extensions/whatsapp/src/session.ts:328, 793617f96c70)
  • Focused regression coverage: Tests cover partial versus completed credentials, queued-save cleanup races, 408 and 515 socket replacement, persistence failures, account-scoped recovery, and durable linked-state confirmation. (extensions/whatsapp/src/login.test.ts:298, 793617f96c70)
  • Prior finding resolved: The current exact-head check-docs check succeeds, so the previous docs-map finding is not re-raised. Public docs: docs/channels/whatsapp.md. (docs/channels/whatsapp.md:49, 793617f96c70)

Likely related people:

  • mcaxtr: Prior merged work owns WhatsApp auth reconciliation, connection lifecycle, startup waits, atomic credential handling, and symlink safety, independently of authoring this PR. (role: recent auth and connection lifecycle contributor; confidence: high; commits: aa76cf43f011, aa023e428306, dd2083c7ec51; files: extensions/whatsapp/src/auth-store.ts, extensions/whatsapp/src/connection-controller.ts, extensions/whatsapp/src/login.ts)
  • vincentkoc: Recent merged work adjusted WhatsApp login outcome reporting, operator messaging, reconnect behavior, and adjacent plugin/channel surfaces. (role: recent WhatsApp login and reconnect contributor; confidence: medium; commits: 841eb81baf37, 071db2ca6940, 21a92ea0f636; files: extensions/whatsapp/src/login.ts, extensions/whatsapp/src/session.ts, src/cli/channel-auth.ts)
  • steipete: Recent merged history routes WhatsApp QR login through the plugin runtime, narrows Plugin SDK boundaries, and maintains the current channel login entrypoint and package surfaces. (role: recent merger and adjacent channel owner; confidence: medium; commits: 9efbae7acda4, 827b0de0ce74, 96f0983a85b5; files: extensions/whatsapp/src/channel.ts, extensions/whatsapp/src/login.ts, extensions/whatsapp/src/session.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 (18 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-11T20:07:04.982Z sha 336aa3f :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T20:35:58.130Z sha 336aa3f :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T20:44:50.083Z sha 336aa3f :: found issues before merge. :: [P1] Preserve the existing WhatsApp socket identity
  • reviewed 2026-07-11T21:21:44.819Z sha 336aa3f :: needs maintainer review before merge. :: none
  • reviewed 2026-07-11T22:47:46.630Z sha 7113a54 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-12T00:23:54.062Z sha db5fef5 :: needs maintainer review before merge. :: none
  • reviewed 2026-07-12T02:36:34.899Z sha ba70427 :: found issues before merge. :: [P3] Regenerate the docs map
  • reviewed 2026-07-12T03:26:21.601Z sha 31ca1b1 :: found issues before merge. :: [P3] Regenerate the docs map

@clawsweeper clawsweeper Bot added 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. P2 Normal backlog priority with limited blast radius. 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. merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. labels Jul 7, 2026
@openclaw-barnacle openclaw-barnacle Bot added the scripts Repository scripts label Jul 7, 2026
@clawsweeper clawsweeper Bot added rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. 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 Jul 8, 2026
@mcaxtr
mcaxtr force-pushed the codex/whatsapp-phone-code-login-clean branch from ccede60 to 68937b2 Compare July 8, 2026 04:26
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 8, 2026
@mcaxtr mcaxtr self-assigned this Jul 11, 2026
@mcaxtr
mcaxtr requested a review from a team as a code owner July 11, 2026 22:30
@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label Jul 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Dependency Guard

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • extensions/whatsapp/npm-shrinkwrap.json
  • extensions/whatsapp/package.json
  • pnpm-lock.yaml

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfile, shrinkwrap, or workspace dependency policy changes are present.
  • Treat package-lock.json and npm-shrinkwrap.json diffs as security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@github-actions

github-actions Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Dependency graph changes are blocked

OpenClaw does not accept dependency graph changes through PRs unless a repository admin or security explicitly authorizes the current head SHA. Dependency updates are generated internally by maintainers so external PRs cannot change the resolved graph.

Detected dependency graph changes:

  • extensions/whatsapp/npm-shrinkwrap.json changed.
  • pnpm-lock.yaml changed.
  • extensions/whatsapp/package.json changed dependencies.

Auto-scrub was not attempted because this PR changes package manifest dependency graph fields:

  • extensions/whatsapp/package.json changed dependencies.

Dependency graph changes must be reviewed by security or handled by maintainers internally. Please remove lockfile changes manually if they are not needed.

To remove lockfile changes, restore them from the target branch:

git fetch origin
git checkout 'origin/main' -- 'extensions/whatsapp/npm-shrinkwrap.json' 'pnpm-lock.yaml'
git commit -m 'chore: remove dependency lockfile change'
git push

If this PR intentionally needs a dependency graph change, ask a repository admin or member of @openclaw/openclaw-secops to comment:

/allow-dependencies-change

The action will approve the current head SHA (793617f96c70d299b8b0973711c8c17af7d94a16) when it reruns. A later push requires a fresh approval.

@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 11, 2026
@mcaxtr
mcaxtr force-pushed the codex/whatsapp-phone-code-login-clean branch from e37fe7c to db5fef5 Compare July 12, 2026 00:11
@clawsweeper clawsweeper Bot removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. 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 Jul 12, 2026
@jamaloff28-coder

Copy link
Copy Markdown

03308363013

@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: feat: add WhatsApp phone-code login This is item 1/1 in the current shard. Shard 9/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

channel: whatsapp-web Channel integration: whatsapp-web dependencies-changed PR changes dependency-related files docs Improvements or additions to documentation maintainer Maintainer-authored PR 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. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants