whalibmob 5.12.14 → 5.12.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example CHANGED
@@ -52,11 +52,13 @@
52
52
 
53
53
  # ─── WhatsApp version ────────────────────────────────────────────────────────
54
54
  # Pin the WhatsApp client version. When set, the live version lookup is skipped
55
- # entirely. Leave unset to fetch the current version automatically (recommended).
55
+ # entirely, and this is what is announced on connect in place of the version
56
+ # stored in the session. Leave unset to fetch the current version automatically.
56
57
  #
57
- # On Android this is normally not needed either way: the version is taken from
58
- # the APK the token material came from, since the token is signed over that
59
- # build. Setting this still overrides it.
58
+ # On Android this is normally not needed: the version comes from the APK the
59
+ # token material was read from. On iOS it is looked up on the App Store, and a
60
+ # lookup that fails leaves a built-in fallback version in the session — which
61
+ # the server refuses at connect with a 405. That is what this is for.
60
62
  # WA_VERSION=2.24.10.75
61
63
 
62
64
  # Override the static registration token. iOS only — Android has no static token
package/README.md CHANGED
@@ -254,6 +254,7 @@ npm install -g whalibmob
254
254
  - [Android Profiles](#android-profiles)
255
255
  - [Custom Device Fields](#custom-device-fields)
256
256
  - [Version & Token Overrides](#version--token-overrides)
257
+ - [When the server answers 405 on connect](#when-the-server-answers-405-on-connect)
257
258
 
258
259
  ---
259
260
 
@@ -291,14 +292,40 @@ wa registration --request-code 919634847671 --method wa_old
291
292
  ```
292
293
 
293
294
  **Registering as Android** is the same command with the platform named. Nothing
294
- else to prepare — see [what it does behind that one command](#registering-as-android):
295
+ else to prepare — see [what it does behind that one command](#registering-as-android).
296
+
297
+ Linux, macOS, Termux:
295
298
 
296
299
  ```sh
297
300
  WA_OS=android WA_DEVICE=samsung-s24-ultra wa registration --request-code 919634847671 --debug
298
301
  ```
299
302
 
300
- Set `WA_OS=android` in a `.env` file instead and the plain command is enough.
301
- `--debug` prints every request and reply, which is worth having the first time.
303
+ Windows, Command Prompt — `set` on its own line, because `VAR=value` in front of
304
+ a command is Unix syntax and Windows refuses it:
305
+
306
+ ```bat
307
+ set WA_OS=android
308
+ set WA_DEVICE=samsung-s24-ultra
309
+ wa registration --request-code 919634847671 --debug
310
+ ```
311
+
312
+ Windows, PowerShell:
313
+
314
+ ```powershell
315
+ $env:WA_OS = "android"
316
+ $env:WA_DEVICE = "samsung-s24-ultra"
317
+ wa registration --request-code 919634847671 --debug
318
+ ```
319
+
320
+ A `.env` file in the directory you run from works the same everywhere and saves
321
+ repeating it — see [Device Quick Start](#device-quick-start). `--debug` prints
322
+ every request and reply, which is worth having the first time: its first line
323
+ names the platform that actually went out, so you can see whether the variables
324
+ arrived.
325
+
326
+ The variables only matter for the command that *creates* the session. What a
327
+ session registered as is written into it, so the confirmation step and every
328
+ later connect follow the session, not whatever the shell carries at the time.
302
329
 
303
330
  The CLI sends the code request, prints the result, and then **stays open** in the interactive shell. You will see:
304
331
 
@@ -1342,6 +1369,28 @@ registered session saved to /home/user/.waSession/919634847671.json
1342
1369
  now run: /connect 919634847671
1343
1370
  ```
1344
1371
 
1372
+ **Registering as Android from the shell** works the same way, but `WA_OS` has to
1373
+ be set when the shell *starts* — the `wa>` prompt is already inside a running
1374
+ process, and nothing typed at it can change the environment that process was
1375
+ launched with:
1376
+
1377
+ ```sh
1378
+ WA_OS=android WA_DEVICE=samsung-s24-ultra wa
1379
+ ```
1380
+ ```sh
1381
+ wa> /reg code 919634847671
1382
+ no Android token material yet — fetching the WhatsApp APK from Google Play
1383
+ ...
1384
+ status sent
1385
+ wa> /reg confirm 919634847671 123456
1386
+ ```
1387
+
1388
+ A `.env` file with `WA_OS=android` in the directory you start from does the same
1389
+ and saves the typing. Either way it only matters for the command that *creates*
1390
+ the session: what a session registered as is written into it, and every later
1391
+ step — the confirmation, a reconnect from a different shell tomorrow — follows
1392
+ the session rather than the environment.
1393
+
1345
1394
  ---
1346
1395
 
1347
1396
  ### Connection Commands (in-shell)
@@ -4282,12 +4331,56 @@ Copy `.env.example` to `.env` in your project root and set the variables you nee
4282
4331
 
4283
4332
  ### Device Quick Start
4284
4333
 
4285
- Emulate an Android Pixel 8 Pro:
4334
+ Emulate an Android Pixel 8 Pro. **The syntax for setting a variable differs per
4335
+ shell**, and getting it wrong is the most common reason a device profile appears
4336
+ to be ignored:
4337
+
4338
+ **Linux, macOS, Termux** — set them for the one command:
4286
4339
 
4287
4340
  ```sh
4288
4341
  WA_OS=android WA_DEVICE=pixel_8_pro node your-app.js
4342
+ WA_OS=android WA_DEVICE=pixel_8_pro wa registration --request-code 919634847671
4343
+ ```
4344
+
4345
+ **Windows, Command Prompt** — `set` first, one per line. `VAR=value` in front of
4346
+ a command is Unix syntax and Windows answers it with
4347
+ `'WA_OS' is not recognized as an internal or external command`:
4348
+
4349
+ ```bat
4350
+ set WA_OS=android
4351
+ set WA_DEVICE=pixel_8_pro
4352
+ wa registration --request-code 919634847671
4353
+ ```
4354
+
4355
+ Keep them on separate lines. Chaining with `&&` puts the space before the `&&`
4356
+ inside the value.
4357
+
4358
+ **Windows, PowerShell**:
4359
+
4360
+ ```powershell
4361
+ $env:WA_OS = "android"
4362
+ $env:WA_DEVICE = "pixel_8_pro"
4363
+ wa registration --request-code 919634847671
4289
4364
  ```
4290
4365
 
4366
+ **Anywhere, and the one worth preferring** — a `.env` file in the directory you
4367
+ run from, which behaves identically on every platform:
4368
+
4369
+ ```dotenv
4370
+ WA_OS=android
4371
+ WA_DEVICE=pixel_8_pro
4372
+ ```
4373
+
4374
+ ```sh
4375
+ wa registration --request-code 919634847671
4376
+ ```
4377
+
4378
+ The CLI reads `.env` from the **current directory**, not from where whalibmob is
4379
+ installed, so `cd` to the directory holding it before running. Whichever way you
4380
+ choose, the first line of `--debug` output tells you whether it took:
4381
+ `User-Agent: WhatsApp/… Android/14 Device/Google-Pixel 8 Pro`. An `iOS/…` there
4382
+ means the variables never arrived.
4383
+
4291
4384
  Or put the variables in a `.env` file. When using the **CLI** (`wa` command) the file is loaded automatically. When using the **library directly**, load it before `require('whalibmob')`:
4292
4385
 
4293
4386
  ```js
@@ -4374,8 +4467,46 @@ These variables override individual fields on top of the selected profile:
4374
4467
 
4375
4468
  | Variable | Description |
4376
4469
  |---|---|
4377
- | `WA_VERSION` | Pin the WhatsApp version (e.g. `2.24.13.80`). Skips the live store fetch. |
4378
- | `WA_STATIC_TOKEN` | Override the static token used in registration token computation. |
4470
+ | `WA_VERSION` | Pin the WhatsApp version (e.g. `2.24.13.80`). Skips the live store fetch, and is announced on connect in place of the version stored in the session. |
4471
+ | `WA_STATIC_TOKEN` | Override the static token used in registration token computation. iOS only — Android has no static token. |
4472
+
4473
+ ### When the server answers 405 on connect
4474
+
4475
+ ```
4476
+ WhatsApp auth failure 405 — client outdated — the version this session
4477
+ announces is not one the server accepts.
4478
+ ```
4479
+
4480
+ **The session is fine and the number is still registered.** 405 is the server
4481
+ declining the *client*, not the account: the version being announced is one it no
4482
+ longer accepts. Registering the number again is the one move that cannot help —
4483
+ the same version would go out and be refused identically, at the cost of a real
4484
+ phone number and a code request.
4485
+
4486
+ Announce a current version instead:
4487
+
4488
+ ```sh
4489
+ WA_VERSION=2.26.30.3 wa connect 919634847671
4490
+ ```
4491
+
4492
+ Or put `WA_VERSION` in the `.env` file, where it applies to every command.
4493
+
4494
+ **Where the stale version comes from.** Each platform learns its version
4495
+ differently:
4496
+
4497
+ | | how the version is found | what happens when that fails |
4498
+ |---|---|---|
4499
+ | iOS | looked up on the App Store | falls back to a version compiled into the library, which goes stale |
4500
+ | Android | read from the APK the token material came from | `wa apk-material --download` fetches the current one |
4501
+
4502
+ So this is mostly an iOS story: a lookup that times out or is rate limited leaves
4503
+ a months-old fallback version in the session, and nothing says so until the
4504
+ handshake is refused. On Android the version travels with the APK, and refreshing
4505
+ the material refreshes the version with it:
4506
+
4507
+ ```sh
4508
+ wa apk-material --download
4509
+ ```
4379
4510
 
4380
4511
  ## License
4381
4512
 
@@ -575,6 +575,39 @@ function tryLoadAndroidMaterial() {
575
575
  try { return loadAndroidMaterial(); } catch (_) { return null; }
576
576
  }
577
577
 
578
+ /**
579
+ * Which platform a registration speaks.
580
+ *
581
+ * Once a session has an account behind it, or has a code outstanding, its
582
+ * platform is settled: the account was created as that, the token and the
583
+ * User-Agent have to keep saying so, and re-reading WA_OS could only break it.
584
+ * A confirmation run from a shell without the variables must not flip to iOS
585
+ * halfway through.
586
+ *
587
+ * Before that, a session holds nothing but keys. Re-running the code request is
588
+ * how you start it over, and the environment is how you say what to start it
589
+ * over as — so the environment decides, and this stops being consulted the
590
+ * moment a code goes out.
591
+ *
592
+ * When the two disagree on a session that is settled, that is said out loud.
593
+ * Silently ignoring WA_OS is how you end up watching an Android registration go
594
+ * out under an iOS User-Agent and not knowing why.
595
+ */
596
+ function deviceForRegistration(store, opts) {
597
+ const env = getDeviceConfig();
598
+ const stored = store && store.device;
599
+ const settled = !!(store && (store.registered || store.codePending));
600
+ if (!settled || !stored) return env;
601
+
602
+ if (stored.os !== env.os) {
603
+ const say = (opts && opts.onProgress) || (m => _whaDbg('[DBG] REG ' + m));
604
+ say('note: this session was started as ' + stored.os + ', so it stays ' + stored.os +
605
+ ' — WA_OS=' + env.os + ' does not apply to a number that is already part-way ' +
606
+ 'through registering. Delete the session file to start it over as ' + env.os + '.');
607
+ }
608
+ return stored;
609
+ }
610
+
578
611
  /**
579
612
  * Have the Android token material ready, fetching the APK if it is not.
580
613
  *
@@ -1333,11 +1366,7 @@ async function requestSmsCode(store, method, opts) {
1333
1366
  opts = opts || {};
1334
1367
  // Before the version is read, since on Android the version comes out of the
1335
1368
  // APK this fetches.
1336
- // What a session registered as is settled when it is created, so it is the
1337
- // store that decides — not whatever WA_OS the shell happens to carry now. A
1338
- // confirmation run from a shell without the variables would otherwise sign an
1339
- // Android registration with an iOS token.
1340
- const _device = store.device || getDeviceConfig();
1369
+ const _device = deviceForRegistration(store, opts);
1341
1370
  await ensureAndroidMaterial(opts, _device);
1342
1371
  const waVersion = await fetchWaVersion(_device);
1343
1372
  store.version = waVersion;
@@ -1459,11 +1488,7 @@ async function verifyCode(store, code, opts) {
1459
1488
  opts = opts || {};
1460
1489
  // Normally already there from the code request, but a confirmation can be run
1461
1490
  // from a fresh shell that never made one.
1462
- // What a session registered as is settled when it is created, so it is the
1463
- // store that decides — not whatever WA_OS the shell happens to carry now. A
1464
- // confirmation run from a shell without the variables would otherwise sign an
1465
- // Android registration with an iOS token.
1466
- const _device = store.device || getDeviceConfig();
1491
+ const _device = deviceForRegistration(store, opts);
1467
1492
  await ensureAndroidMaterial(opts, _device);
1468
1493
  const waVersion = await fetchWaVersion(_device);
1469
1494
  store.version = waVersion;
@@ -1559,7 +1584,7 @@ module.exports = { checkIfRegistered, checkNumberStatus, requestSmsCode, verifyC
1559
1584
  module.exports._http = { readHttpResponse, parseHttpResponse, decodeChunkedBody };
1560
1585
 
1561
1586
  // Token computation, exposed for tests. Not part of the public API.
1562
- module.exports._token = { computeToken, androidMaterialPath, registrationHeaders, ensureAndroidMaterial };
1587
+ module.exports._token = { computeToken, androidMaterialPath, registrationHeaders, ensureAndroidMaterial, deviceForRegistration };
1563
1588
 
1564
1589
  // Challenge / two-factor internals, exposed for tests. Not part of the public API.
1565
1590
  module.exports._verify = {
package/lib/noise.js CHANGED
@@ -375,7 +375,12 @@ class NoiseSocket extends EventEmitter {
375
375
  oc: false,
376
376
  userAgent: {
377
377
  platform: (this.store.device && this.store.device.platform) || 1,
378
- version: this.store.version,
378
+ // The version the session was registered with, unless WA_VERSION says
379
+ // otherwise. Without that override there is no way out of a 405: the
380
+ // version lives in the session file, the server refuses it, and the
381
+ // only remaining move is to register the number again — which is the
382
+ // one thing that should never be the answer to a client-side problem.
383
+ version: process.env.WA_VERSION || this.store.version,
379
384
  mcc: _phoneMeta.mcc,
380
385
  mnc: _phoneMeta.mnc,
381
386
  osVersion: this.store.device.osVersion,
@@ -463,8 +468,20 @@ class NoiseSocket extends EventEmitter {
463
468
  '402': { wipe: false, text: 'temporarily banned.' },
464
469
  '403': { wipe: true, text: "the account's primary device is gone " +
465
470
  '— it is no longer a multi-device account.' },
466
- '405': { wipe: true, text: 'client outdated — the announced ' +
467
- 'version is not one the server accepts.' },
471
+ // Not a spent session, however much it looks like one. The server
472
+ // declined the *client*: the version we announced is not one it
473
+ // accepts. The registration behind the session is untouched, and
474
+ // telling people to register again over this costs them a real
475
+ // phone number for nothing — the same version would be announced
476
+ // and refused identically. _handleFailure already reads it this way
477
+ // once a session is up; this is the same code arriving during the
478
+ // handshake, and it was the one path still calling it revoked.
479
+ '405': { wipe: false, text: 'client outdated — the version this ' +
480
+ 'session announces is not one the server accepts. The ' +
481
+ 'session itself is fine: set WA_VERSION to a current ' +
482
+ 'WhatsApp version and connect again. On Android, ' +
483
+ '`wa apk-material --download` picks the current one up on ' +
484
+ 'its own.' },
468
485
  '406': { wipe: true, text: 'banned.' },
469
486
  '409': { wipe: true, text: 'bad user agent — the client identified ' +
470
487
  'itself in a way the server rejects.' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whalibmob",
3
- "version": "5.12.14",
3
+ "version": "5.12.16",
4
4
  "description": "WhatsApp library for interaction with WhatsApp Mobile API and web ",
5
5
  "author": "Kunboruto20",
6
6
  "main": "index.js",