feat(whatsapp-bridge): add phone-number pairing code support - #17907
feat(whatsapp-bridge): add phone-number pairing code support#17907keiravoss94 wants to merge 2 commits into
Conversation
Adds a new pairing flow using Baileys' requestPairingCode() as an
alternative to QR-scan onboarding. A WhatsApp account can be linked by
passing a phone number and reading an 8-character code on the device,
avoiding QR scanning via camera or screenshare when that is awkward.
Usage:
node bridge.js --pair-with-number "+15551234567"
Output:
Pairing code: ABCD-EFGH
On your phone:
1. Open WhatsApp
2. Settings > Linked Devices > Link a Device > "Link with phone
number instead"
3. Enter: ABCD-EFGH
Waiting for pairing to complete...
The existing --pair-only (QR) flow remains intact and is the fallback
when --pair-with-number isn't provided. If both flags are passed,
phone-number flow takes precedence with a warning.
Argument parsing/validation factored into pairing-args.js with unit
tests; phone numbers are validated as E.164 and stripped to digits-only
before being passed to Baileys per requestPairingCode signature.
c379af0 to
bdb41cb
Compare
There was a problem hiding this comment.
Pull request overview
Adds support for WhatsApp “link with phone number” onboarding in the scripts/whatsapp-bridge Node bridge by introducing a new --pair-with-number <e164> CLI flag and emitting a Baileys pairing code, alongside the existing QR-based --pair-only flow.
Changes:
- Added
--pair-with-numberparsing + phone-number validation utilities (pairing-args.js) with Node test coverage. - Updated
bridge.jsto request/display a pairing code viasock.requestPairingCode()and to avoid duplicate requests across reconnects. - Added an
npm testscript for the bridge package.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| scripts/whatsapp-bridge/bridge.js | Adds phone-number pairing mode, pairing-code request flow, and exit behavior for pairing runs. |
| scripts/whatsapp-bridge/pairing-args.js | Introduces parsing/validation helpers and pairing-code display formatting. |
| scripts/whatsapp-bridge/pairing-args.test.mjs | Adds unit tests for parsing/validation/formatting helpers. |
| scripts/whatsapp-bridge/package.json | Adds a test script for running the bridge’s Node tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** E.164-like phone number for pairing: country code plus 10–15 digits total. */ | ||
| export const E164_PAIRING_REGEX = /^\+?[1-9]\d{9,14}$/; | ||
|
|
||
| /** | ||
| * @param {string} raw - CLI value passed to `--pair-with-number` | ||
| * @returns {{ ok: true, digits: string } | { ok: false, error: string }} | ||
| */ | ||
| export function validateE164ForPairing(raw) { | ||
| const s = String(raw ?? '').trim(); | ||
| if (!E164_PAIRING_REGEX.test(s)) { | ||
| return { | ||
| ok: false, | ||
| error: 'Invalid phone number. Use E.164 (e.g. +15551234567): country code, digits only besides an optional leading +.', | ||
| }; |
There was a problem hiding this comment.
Updated the validation error to state the 10–15 digit requirement explicitly instead of the generic "Use E.164" wording, matching E164_PAIRING_REGEX and the file comment.
| "scripts": { | ||
| "start": "node bridge.js" | ||
| "start": "node bridge.js", | ||
| "test": "node --test ./*.test.mjs" |
There was a problem hiding this comment.
Changed npm test to pass explicit test file paths (pairing-args.test.mjs allowlist.test.mjs) so Node runs them without shell glob expansion.
Clarify the 10–15 digit phone requirement in validation errors and list test files explicitly so npm test works on Windows.
|
Addressed review feedback in 888d8f8: PR body now follows |
|
@austinpickett check again |
…uestPairingCode Adds an opt-in --pair-phone=<E.164> flag to scripts/whatsapp-bridge/bridge.js that switches first-time pairing from QR scan to WhatsApp phone-number pairing code (8 chars). QR mode remains the default — no behaviour change for existing installs. Motivation: pairing a remote EC2-hosted Hermes agent via QR over SSH/journal is awkward; Baileys exposes the native alternative via sock.requestPairingCode(). See PR body for full details. # Status: requires-upstream-merge # Tracks: NousResearch#45585 # Note: collaborator called PR NousResearch#45585 a duplicate of upstream PR NousResearch#17907; # either landing on upstream main causes the auto-drop probe to succeed # and this patch is removed from the series next cycle. # Tests-that-must-pass-without-patch: # tests/scripts/whatsapp-bridge/test_pair_phone.py
…uestPairingCode Adds an opt-in --pair-phone=<E.164> flag to scripts/whatsapp-bridge/bridge.js that switches first-time pairing from QR scan to WhatsApp phone-number pairing code (8 chars). QR mode remains the default — no behaviour change for existing installs. Motivation: pairing a remote EC2-hosted Hermes agent via QR over SSH/journal is awkward; Baileys exposes the native alternative via sock.requestPairingCode(). See PR body for full details. # Status: requires-upstream-merge # Tracks: NousResearch#45585 # Note: collaborator called PR NousResearch#45585 a duplicate of upstream PR NousResearch#17907; # either landing on upstream main causes the auto-drop probe to succeed # and this patch is removed from the series next cycle. # Tests-that-must-pass-without-patch: # tests/scripts/whatsapp-bridge/test_pair_phone.py
|
Thanks for the phone-number pairing implementation and for resolving the prior validation and cross-platform test-script feedback. Problems
Suggested changes
Automated hermes-sweeper review. |
GottZ
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Summary
Three PRs address phone-number pairing through Baileys requestPairingCode(): #17907 provides the most complete bridge-local implementation with argument validation and tests, while #20798 and #45585 implement narrower bridge.js-only variants. None completes the current CLI/dashboard onboarding path or emits the structured pairing-code event required by the dashboard protocol.
Related pull requests
- #17907
related— (+199/-8) — retain as the consolidation base, but not merge-ready: the diff adds validated --pair-with-number parsing, pairing-code formatting, reconnect deduplication, and unit tests, directly implementing the underlying capability. The earlier CHANGES_REQUESTED review was reportedly addressed, but the later contributor keep_open review identifies still-blocking current-main gaps: no CLI/dashboard selection path, no --pair-json code event, and no lifecycle/protocol coverage. - #20798 [closed]
duplicate— (+67/-11) — closed duplicate, still relevant as a reference implementation: it adds requestPairingCode(), health-state exposure, environment/custom-code options, and unrelated outbound JID normalization, but has no dedicated validation or tests and does not integrate phone pairing into current onboarding. Its bridge-only implementation substantially overlaps #17907, and a contributor explicitly identified it as a duplicate of #17907. - #45585
duplicate— (+29/-1) — close as a duplicate after preserving any useful timing evidence: despite the APPROVED non-contributor review and the contributor keep_open review on #45585, the diff's documented --pair-phone=<E.164> form cannot be parsed by getArg(), emits only plain console output rather than the dashboard's structured JSON event, and adds no regression coverage. It implements the same bridge-local requestPairingCode() path as #17907 with less validation and testing.
Duplicates
#17907, #20798, and #45585 substantially duplicate the same phone-number pairing capability; #20798 and #45585 are narrower bridge.js-only alternatives to #17907.
Suggested consolidation
Consolidate on #17907, but do not merge it until the blocking contributor review is addressed by rebasing onto current main, adding explicit CLI/dashboard phone-number selection, emitting a structured --pair-json pairing-code event, and covering the socket lifecycle and JSON protocol. Then close #45585 as a duplicate; keep already-closed #20798 linked as a duplicate/reference implementation rather than reopening it.
Complex graph
flowchart LR
classDef open fill:#dbeafe,stroke:#1d4ed8,color:#1e3a8a
classDef merged fill:#dcfce7,stroke:#15803d,color:#14532d
classDef closed fill:#e5e7eb,stroke:#6b7280,color:#1f2937
classDef unverified fill:#f3f4f6,stroke:#9ca3af,color:#374151
classDef best stroke-width:3px,stroke:#b45309
classDef target stroke-width:3px,stroke:#4338ca
subgraph Dup17907 ["PRs duplicating each other"]
P17907["PR #17907 (open)"]
P20798["PR #20798 (closed)"]
P45585["PR #45585 (open)"]
end
class P17907 open
class P20798 closed
class P45585 open
class P17907 target
click P17907 "https://github.com/NousResearch/hermes-agent/pull/17907"
click P20798 "https://github.com/NousResearch/hermes-agent/pull/20798"
click P45585 "https://github.com/NousResearch/hermes-agent/pull/45585"
Graph: solid arrow = fixes / best fix, dashed arrow = partial or unverified (see edge label); boxed group = PRs duplicating each other; amber border = best fix; indigo border = target; gray node = closed or no verify verdict yet (state tag in the node label).
Cross-PR triage: Reviewed 3 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 21 kB of PR diffs, 8 kB of issue/PR text, 6 kB of discussion (10 comments), 3 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch.
What does this PR do?
Adds
--pair-with-number <e164>to the WhatsApp bridge for BaileysrequestPairingCode()onboarding, alongside the existing--pair-onlyQR flow. Operators who cannot scan a QR code can link the bridge using an 8-character pairing code instead.Related Issue
Fixes #
Type of Change
Changes Made
scripts/whatsapp-bridge/pairing-args.js— parse/validate--pair-with-number, format pairing codes for displayscripts/whatsapp-bridge/pairing-args.test.mjs— unit tests for parsing, validation, and formattingscripts/whatsapp-bridge/bridge.js— request/display pairing code viasock.requestPairingCode(), avoid duplicate requests on reconnectscripts/whatsapp-bridge/package.json— addnpm testwith explicit test file pathsHow to Test
cd scripts/whatsapp-bridge && npm test--pair-with-number +15551234567(use your own E.164 number) and confirm an 8-character hyphenated code is printed with linking steps--pair-onlyQR flow still works unchangedChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AFor New Skills
N/A — delete this section otherwise.
Screenshots / Logs
Pairing output example: