whalibmob 5.23.5 → 5.24.1
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/README.md +128 -2
- package/index.d.ts +1332 -0
- package/index.js +232 -26
- package/lib/messages/MediaRetry.js +8 -2
- package/lib/proto/MessageProto.js +102 -11
- package/package.json +13 -2
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ code, and bring the account into being. Both transports, one API.
|
|
|
11
11
|
[](https://www.npmjs.com/package/whalibmob)
|
|
12
12
|
[](https://nodejs.org)
|
|
13
13
|
[](LICENSE)
|
|
14
|
+
[](index.d.ts)
|
|
14
15
|
|
|
15
16
|
[](https://github.com/Kunboruto20/whalibmob/blob/main/Brasil.md)
|
|
16
17
|
|
|
@@ -49,8 +50,8 @@ If you want to talk with me contact me on Telegram my username îs @brtyu545
|
|
|
49
50
|
> [!CAUTION]
|
|
50
51
|
> Use a dedicated phone number with this library. Connecting with a number that is already active on a real device will cause WhatsApp to log that device out.
|
|
51
52
|
|
|
52
|
-
> [!
|
|
53
|
-
>
|
|
53
|
+
> [!NOTE]
|
|
54
|
+
> **Actively developed.** WhatsApp changed the mobile protocol recently, and whalibmob is being kept in step with it release by release. Contributions are welcome — pull requests are accepted.
|
|
54
55
|
|
|
55
56
|
> [!IMPORTANT]
|
|
56
57
|
> This project is not affiliated, associated, authorized, endorsed by, or in any way officially connected with WhatsApp or any of its subsidiaries or affiliates. "WhatsApp" and related names are registered trademarks of their respective owners. Use at your own discretion.
|
|
@@ -1663,6 +1664,82 @@ Everything the CLI does is available as a Node.js library. The sections below
|
|
|
1663
1664
|
cover connecting an account, sending and receiving every message type, groups,
|
|
1664
1665
|
communities, channels, presence, privacy, history sync, and device emulation.
|
|
1665
1666
|
|
|
1667
|
+
### What the package exports
|
|
1668
|
+
|
|
1669
|
+
Two layers. The first is the flat one the rest of this document uses — the
|
|
1670
|
+
eighty-two names the common paths are built from:
|
|
1671
|
+
|
|
1672
|
+
```js
|
|
1673
|
+
const { WhalibmobClient, createNewStore, requestSmsCode } = require('whalibmob')
|
|
1674
|
+
```
|
|
1675
|
+
|
|
1676
|
+
The second is everything else. The library is ninety-five modules and close to
|
|
1677
|
+
five hundred exported names, and the flat layer picks out under a fifth of
|
|
1678
|
+
them. The rest are reachable as **namespaces**, each one a module of `lib/`
|
|
1679
|
+
under a name of its own:
|
|
1680
|
+
|
|
1681
|
+
```js
|
|
1682
|
+
const wa = require('whalibmob')
|
|
1683
|
+
|
|
1684
|
+
wa.MediaService.getMediaKeyName('ptt') // → 'WhatsApp Audio Keys'
|
|
1685
|
+
wa.MessageProto.decodeMessageContainer(buf) // raw bytes → a decoded message
|
|
1686
|
+
wa.Messages.MediaRetry.mediaRetryKey(key) // the retry-receipt key
|
|
1687
|
+
wa.Signal.libsignal.SessionCipher // the vendored libsignal
|
|
1688
|
+
wa.AppState.SyncdProto // app-state mutation records
|
|
1689
|
+
wa.Image.Jpeg // the JPEG header reader
|
|
1690
|
+
```
|
|
1691
|
+
|
|
1692
|
+
A namespace is named after the module it comes from, and a directory in `lib/`
|
|
1693
|
+
becomes one namespace rather than several — so `Signal` is all of
|
|
1694
|
+
`lib/signal/`, `AppState` all of `lib/appstate/`, `Messages` all of
|
|
1695
|
+
`lib/messages/`. Two names could not be had: **`Devices`** is
|
|
1696
|
+
`lib/DeviceManager.js`, because the flat `DeviceManager` is the class rather
|
|
1697
|
+
than the module, and **`Proto`** is `lib/proto.js` while the message protobufs
|
|
1698
|
+
in `lib/proto/` are **`MessageProto`**.
|
|
1699
|
+
|
|
1700
|
+
Deep requires work as well, and always have — the package declares no `exports`
|
|
1701
|
+
map, so nothing is sealed off:
|
|
1702
|
+
|
|
1703
|
+
```js
|
|
1704
|
+
const MediaService = require('whalibmob/lib/MediaService')
|
|
1705
|
+
// the same object, by a longer name
|
|
1706
|
+
require('whalibmob').MediaService === MediaService // true
|
|
1707
|
+
```
|
|
1708
|
+
|
|
1709
|
+
Adding the namespaces renamed and removed nothing: every name the library
|
|
1710
|
+
exported before is still exported, still holding what it held.
|
|
1711
|
+
|
|
1712
|
+
> [!NOTE]
|
|
1713
|
+
> The namespaces are typed as far as the rest of this document goes — media,
|
|
1714
|
+
> the message protobufs, media retry. Past that they are `any`, which is what
|
|
1715
|
+
> the internals have always been in `index.d.ts`. They are reachable, not
|
|
1716
|
+
> described.
|
|
1717
|
+
|
|
1718
|
+
### ES modules
|
|
1719
|
+
|
|
1720
|
+
The package is CommonJS, and every one of its names can be imported from an ES
|
|
1721
|
+
module — a bot written with `"type": "module"` needs no interop dance:
|
|
1722
|
+
|
|
1723
|
+
```js
|
|
1724
|
+
import { WhalibmobClient, createNewStore, requestSmsCode } from 'whalibmob'
|
|
1725
|
+
import { MediaService, MessageProto } from 'whalibmob'
|
|
1726
|
+
|
|
1727
|
+
// the default import is the whole export object, if you prefer it
|
|
1728
|
+
import wa from 'whalibmob'
|
|
1729
|
+
|
|
1730
|
+
// deep imports work too — ESM wants the extension, CommonJS does not
|
|
1731
|
+
import { downloadMedia } from 'whalibmob/lib/MediaService.js'
|
|
1732
|
+
```
|
|
1733
|
+
|
|
1734
|
+
> [!NOTE]
|
|
1735
|
+
> `import { … }` used to fail for all but five names. Node reads a CommonJS
|
|
1736
|
+
> module's names statically, and the reader gives up at the first property of
|
|
1737
|
+
> `module.exports` whose value is not a plain identifier — an inline arrow
|
|
1738
|
+
> function five entries in cost the other 116. `require()` and the default
|
|
1739
|
+
> import were unaffected, which is why it went unnoticed. Everything is now
|
|
1740
|
+
> bound to a name before it is exported, and a test fails if that stops being
|
|
1741
|
+
> true.
|
|
1742
|
+
|
|
1666
1743
|
## Connecting Account
|
|
1667
1744
|
|
|
1668
1745
|
### Register a New Number
|
|
@@ -3699,6 +3776,55 @@ const bytes = await client.downloadMedia(d, { verify: true })
|
|
|
3699
3776
|
with no media, no CDN location, an unsupported type, or a file that does not
|
|
3700
3777
|
match the message all say so.
|
|
3701
3778
|
|
|
3779
|
+
### View-once and disappearing messages
|
|
3780
|
+
|
|
3781
|
+
Some messages arrive inside an envelope. A photo sent as **view-once** is an
|
|
3782
|
+
ordinary `ImageMessage` wrapped in a `ViewOnceMessage`; the same photo in a
|
|
3783
|
+
chat with **disappearing messages** turned on is one wrapped in an
|
|
3784
|
+
`EphemeralMessage`. Nothing about the photo changes — the envelope only records
|
|
3785
|
+
how it was sent.
|
|
3786
|
+
|
|
3787
|
+
The decoder opens them, so nothing special is needed on your side. `msg.decoded`
|
|
3788
|
+
is the photo, and `downloadMedia()` works on it exactly as it does on any other:
|
|
3789
|
+
|
|
3790
|
+
```js
|
|
3791
|
+
client.on('message', async (msg) => {
|
|
3792
|
+
const d = msg.decoded
|
|
3793
|
+
if (!d || !d.mediaKey) return
|
|
3794
|
+
|
|
3795
|
+
if (d.viewOnce) console.log('sent as view-once')
|
|
3796
|
+
if (d.ephemeral) console.log('from a disappearing chat')
|
|
3797
|
+
|
|
3798
|
+
const bytes = await client.downloadMedia(d) // same call, wrapped or not
|
|
3799
|
+
})
|
|
3800
|
+
```
|
|
3801
|
+
|
|
3802
|
+
Three flags say how the message was sent, and are absent otherwise:
|
|
3803
|
+
|
|
3804
|
+
| flag | meaning |
|
|
3805
|
+
|---|---|
|
|
3806
|
+
| `d.viewOnce` | sent as view-once — `ViewOnceMessage`, `ViewOnceMessageV2` or the V2 extension a voice note uses |
|
|
3807
|
+
| `d.ephemeral` | from a chat with disappearing messages on |
|
|
3808
|
+
| `d.edited` | the new text of an edited message — the payload is the `protocol` message carrying it |
|
|
3809
|
+
|
|
3810
|
+
They stack. A view-once photo in a disappearing chat carries both:
|
|
3811
|
+
|
|
3812
|
+
```js
|
|
3813
|
+
if (d.viewOnce && d.ephemeral) { /* … */ }
|
|
3814
|
+
```
|
|
3815
|
+
|
|
3816
|
+
Documents sent with a caption (`DocumentWithCaptionMessage`) are unwrapped the
|
|
3817
|
+
same way and decode as a plain `document`, with no flag of their own.
|
|
3818
|
+
|
|
3819
|
+
> [!NOTE]
|
|
3820
|
+
> Opening the envelope is what makes this media reachable at all. Before it, a
|
|
3821
|
+
> view-once photo decoded as `{ type: 'unknown' }` — no `mediaKey`, no
|
|
3822
|
+
> `directPath` — and there was nothing for `downloadMedia()` to fetch.
|
|
3823
|
+
|
|
3824
|
+
Nothing here changes when the message came through history sync, or when it is
|
|
3825
|
+
one of your own echoed back to this device from another: those envelopes nest,
|
|
3826
|
+
and are unwrapped down to the message inside.
|
|
3827
|
+
|
|
3702
3828
|
### When the file is gone from the CDN
|
|
3703
3829
|
|
|
3704
3830
|
Media is not carried inside the message — the message carries a URL, a hash and
|