@nerxa/socketon 0.0.0-stage → 1.21.0
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/EXPERIMENTAL.md +350 -0
- package/LICENSE +24 -0
- package/README.md +6317 -2
- package/WAProto/index.d.ts +17301 -0
- package/WAProto/index.js +125088 -0
- package/engine-requirements.js +14 -0
- package/package.json +100 -4
- package/src/Defaults/index.d.ts +152 -0
- package/src/Defaults/index.js +164 -0
- package/src/MessageBuilder/bot-signature.d.ts +22 -0
- package/src/MessageBuilder/bot-signature.js +122 -0
- package/src/MessageBuilder/extras.d.ts +449 -0
- package/src/MessageBuilder/extras.js +1356 -0
- package/src/MessageBuilder/index.d.ts +210 -0
- package/src/MessageBuilder/index.js +3594 -0
- package/src/MessageBuilder/metaai.d.ts +438 -0
- package/src/MessageBuilder/metaai.js +890 -0
- package/src/Signal/Group/ciphertext-message.d.ts +9 -0
- package/src/Signal/Group/ciphertext-message.js +11 -0
- package/src/Signal/Group/group-session-builder.d.ts +7 -0
- package/src/Signal/Group/group-session-builder.js +27 -0
- package/src/Signal/Group/group_cipher.d.ts +11 -0
- package/src/Signal/Group/group_cipher.js +78 -0
- package/src/Signal/Group/index.d.ts +11 -0
- package/src/Signal/Group/index.js +11 -0
- package/src/Signal/Group/keyhelper.d.ts +6 -0
- package/src/Signal/Group/keyhelper.js +17 -0
- package/src/Signal/Group/sender-chain-key.d.ts +13 -0
- package/src/Signal/Group/sender-chain-key.js +25 -0
- package/src/Signal/Group/sender-key-distribution-message.d.ts +16 -0
- package/src/Signal/Group/sender-key-distribution-message.js +62 -0
- package/src/Signal/Group/sender-key-message.d.ts +18 -0
- package/src/Signal/Group/sender-key-message.js +65 -0
- package/src/Signal/Group/sender-key-name.d.ts +11 -0
- package/src/Signal/Group/sender-key-name.js +47 -0
- package/src/Signal/Group/sender-key-record.d.ts +12 -0
- package/src/Signal/Group/sender-key-record.js +40 -0
- package/src/Signal/Group/sender-key-state.d.ts +16 -0
- package/src/Signal/Group/sender-key-state.js +83 -0
- package/src/Signal/Group/sender-message-key.d.ts +11 -0
- package/src/Signal/Group/sender-message-key.js +25 -0
- package/src/Signal/libsignal.d.ts +54 -0
- package/src/Signal/libsignal.js +427 -0
- package/src/Signal/lid-mapping.d.ts +20 -0
- package/src/Signal/lid-mapping.js +274 -0
- package/src/Socket/Client/index.d.ts +2 -0
- package/src/Socket/Client/index.js +3 -0
- package/src/Socket/Client/tcp.js +177 -0
- package/src/Socket/Client/types.d.ts +5 -0
- package/src/Socket/Client/types.js +9 -0
- package/src/Socket/Client/websocket.d.ts +12 -0
- package/src/Socket/Client/websocket.js +53 -0
- package/src/Socket/business.d.ts +431 -0
- package/src/Socket/business.js +379 -0
- package/src/Socket/chats.d.ts +247 -0
- package/src/Socket/chats.js +1484 -0
- package/src/Socket/communities.d.ts +598 -0
- package/src/Socket/communities.js +421 -0
- package/src/Socket/email.js +145 -0
- package/src/Socket/groups.d.ts +298 -0
- package/src/Socket/groups.js +339 -0
- package/src/Socket/index.d.ts +581 -0
- package/src/Socket/index.js +37 -0
- package/src/Socket/messages-recv.d.ts +370 -0
- package/src/Socket/messages-recv.js +1864 -0
- package/src/Socket/messages-send.d.ts +390 -0
- package/src/Socket/messages-send.js +1574 -0
- package/src/Socket/mex.d.ts +1 -0
- package/src/Socket/mex.js +44 -0
- package/src/Socket/mobile-builders.js +72 -0
- package/src/Socket/mobile.js +424 -0
- package/src/Socket/newsletter.d.ts +468 -0
- package/src/Socket/newsletter.js +671 -0
- package/src/Socket/socket.d.ts +77 -0
- package/src/Socket/socket.js +1106 -0
- package/src/Store/index.d.ts +3 -0
- package/src/Store/index.js +3 -0
- package/src/Store/make-in-memory-store.d.ts +62 -0
- package/src/Store/make-in-memory-store.js +396 -0
- package/src/Store/make-ordered-dictionary.d.ts +12 -0
- package/src/Store/make-ordered-dictionary.js +78 -0
- package/src/Store/object-repository.d.ts +10 -0
- package/src/Store/object-repository.js +23 -0
- package/src/Types/Auth.d.ts +1 -0
- package/src/Types/Auth.js +1 -0
- package/src/Types/Bussines.d.ts +1 -0
- package/src/Types/Bussines.js +1 -0
- package/src/Types/Call.d.ts +1 -0
- package/src/Types/Call.js +1 -0
- package/src/Types/Chat.d.ts +2 -0
- package/src/Types/Chat.js +24 -0
- package/src/Types/Contact.d.ts +1 -0
- package/src/Types/Contact.js +1 -0
- package/src/Types/Events.d.ts +1 -0
- package/src/Types/Events.js +0 -0
- package/src/Types/GroupMetadata.d.ts +5 -0
- package/src/Types/GroupMetadata.js +6 -0
- package/src/Types/Label.d.ts +2 -0
- package/src/Types/Label.js +24 -0
- package/src/Types/LabelAssociation.d.ts +2 -0
- package/src/Types/LabelAssociation.js +6 -0
- package/src/Types/Message.d.ts +13 -0
- package/src/Types/Message.js +23 -0
- package/src/Types/Mex.d.ts +2 -0
- package/src/Types/Mex.js +95 -0
- package/src/Types/Product.d.ts +1 -0
- package/src/Types/Product.js +1 -0
- package/src/Types/Signal.d.ts +1 -0
- package/src/Types/Signal.js +0 -0
- package/src/Types/Socket.d.ts +1 -0
- package/src/Types/Socket.js +0 -0
- package/src/Types/State.d.ts +5 -0
- package/src/Types/State.js +54 -0
- package/src/Types/USync.d.ts +1 -0
- package/src/Types/USync.js +0 -0
- package/src/Types/index.d.ts +13 -0
- package/src/Types/index.js +25 -0
- package/src/Utils/auth-store.d.ts +29 -0
- package/src/Utils/auth-store.js +76 -0
- package/src/Utils/auth-utils.d.ts +58 -0
- package/src/Utils/auth-utils.js +273 -0
- package/src/Utils/browser-utils.d.ts +9 -0
- package/src/Utils/browser-utils.js +28 -0
- package/src/Utils/business.d.ts +49 -0
- package/src/Utils/business.js +226 -0
- package/src/Utils/chat-utils.d.ts +408 -0
- package/src/Utils/chat-utils.js +846 -0
- package/src/Utils/companion-reg-client-utils.d.ts +4 -0
- package/src/Utils/companion-reg-client-utils.js +39 -0
- package/src/Utils/crypto.d.ts +39 -0
- package/src/Utils/crypto.js +110 -0
- package/src/Utils/decode-wa-message.d.ts +99 -0
- package/src/Utils/decode-wa-message.js +373 -0
- package/src/Utils/event-buffer.d.ts +22 -0
- package/src/Utils/event-buffer.js +624 -0
- package/src/Utils/generics.d.ts +63 -0
- package/src/Utils/generics.js +375 -0
- package/src/Utils/group-metadata-cache.d.ts +4 -0
- package/src/Utils/group-metadata-cache.js +25 -0
- package/src/Utils/history.d.ts +75 -0
- package/src/Utils/history.js +131 -0
- package/src/Utils/html-app.d.ts +19 -0
- package/src/Utils/html-app.js +96 -0
- package/src/Utils/html-multiplayer.d.ts +10 -0
- package/src/Utils/html-multiplayer.js +94 -0
- package/src/Utils/identity-change-handler.d.ts +13 -0
- package/src/Utils/identity-change-handler.js +48 -0
- package/src/Utils/index.d.ts +44 -0
- package/src/Utils/index.js +44 -0
- package/src/Utils/link-preview-metadata.d.ts +47 -0
- package/src/Utils/link-preview-metadata.js +88 -0
- package/src/Utils/link-preview.d.ts +12 -0
- package/src/Utils/link-preview.js +79 -0
- package/src/Utils/logger.d.ts +2 -0
- package/src/Utils/logger.js +2 -0
- package/src/Utils/lt-hash.d.ts +6 -0
- package/src/Utils/lt-hash.js +3 -0
- package/src/Utils/make-mutex.d.ts +6 -0
- package/src/Utils/make-mutex.js +32 -0
- package/src/Utils/message-retry-manager.d.ts +79 -0
- package/src/Utils/message-retry-manager.js +255 -0
- package/src/Utils/messages-media.d.ts +136 -0
- package/src/Utils/messages-media.js +814 -0
- package/src/Utils/messages.d.ts +62 -0
- package/src/Utils/messages.js +2223 -0
- package/src/Utils/mobile-companion-crypto.js +191 -0
- package/src/Utils/modern-messages.d.ts +150 -0
- package/src/Utils/modern-messages.js +496 -0
- package/src/Utils/native-flow.d.ts +11 -0
- package/src/Utils/native-flow.js +115 -0
- package/src/Utils/newsletter-status.d.ts +158 -0
- package/src/Utils/newsletter-status.js +651 -0
- package/src/Utils/noise-handler.d.ts +20 -0
- package/src/Utils/noise-handler.js +200 -0
- package/src/Utils/offline-node-processor.d.ts +9 -0
- package/src/Utils/offline-node-processor.js +33 -0
- package/src/Utils/optional-media.d.ts +3 -0
- package/src/Utils/optional-media.js +45 -0
- package/src/Utils/payment-messages.d.ts +66 -0
- package/src/Utils/payment-messages.js +160 -0
- package/src/Utils/pre-key-manager.d.ts +25 -0
- package/src/Utils/pre-key-manager.js +95 -0
- package/src/Utils/process-message.d.ts +60 -0
- package/src/Utils/process-message.js +688 -0
- package/src/Utils/reporting-utils.d.ts +12 -0
- package/src/Utils/reporting-utils.js +256 -0
- package/src/Utils/scheduled-message.d.ts +51 -0
- package/src/Utils/scheduled-message.js +112 -0
- package/src/Utils/sender-key-memory.d.ts +19 -0
- package/src/Utils/sender-key-memory.js +51 -0
- package/src/Utils/signal.d.ts +82 -0
- package/src/Utils/signal.js +193 -0
- package/src/Utils/stanza-ack.d.ts +16 -0
- package/src/Utils/stanza-ack.js +30 -0
- package/src/Utils/status-stickers.d.ts +127 -0
- package/src/Utils/status-stickers.js +260 -0
- package/src/Utils/sync-action-utils.d.ts +2 -0
- package/src/Utils/sync-action-utils.js +44 -0
- package/src/Utils/tc-token-utils.d.ts +29 -0
- package/src/Utils/tc-token-utils.js +155 -0
- package/src/Utils/ttl-cache.d.ts +28 -0
- package/src/Utils/ttl-cache.js +120 -0
- package/src/Utils/use-mongo-auth-state.d.ts +21 -0
- package/src/Utils/use-mongo-auth-state.js +67 -0
- package/src/Utils/use-multi-file-auth-state.d.ts +11 -0
- package/src/Utils/use-multi-file-auth-state.js +106 -0
- package/src/Utils/use-mysql-auth-state.d.ts +19 -0
- package/src/Utils/use-mysql-auth-state.js +79 -0
- package/src/Utils/use-postgres-auth-state.d.ts +19 -0
- package/src/Utils/use-postgres-auth-state.js +79 -0
- package/src/Utils/use-redis-auth-state.d.ts +19 -0
- package/src/Utils/use-redis-auth-state.js +89 -0
- package/src/Utils/use-single-file-auth-state.d.ts +10 -0
- package/src/Utils/use-single-file-auth-state.js +108 -0
- package/src/Utils/use-sqlite-auth-state.d.ts +12 -0
- package/src/Utils/use-sqlite-auth-state.js +120 -0
- package/src/Utils/useNekoDBAuth.d.ts +19 -0
- package/src/Utils/useNekoDBAuth.js +111 -0
- package/src/Utils/username.d.ts +12 -0
- package/src/Utils/username.js +58 -0
- package/src/Utils/validate-connection.d.ts +43 -0
- package/src/Utils/validate-connection.js +277 -0
- package/src/Utils/voice-recognition.d.ts +53 -0
- package/src/Utils/voice-recognition.js +219 -0
- package/src/Voip/audio-feeder.d.ts +24 -0
- package/src/Voip/audio-feeder.js +268 -0
- package/src/Voip/index.d.ts +88 -0
- package/src/Voip/index.js +936 -0
- package/src/Voip/relay-transport.d.ts +5 -0
- package/src/Voip/relay-transport.js +824 -0
- package/src/Voip/signaling.d.ts +11 -0
- package/src/Voip/signaling.js +1099 -0
- package/src/Voip/types.d.ts +2 -0
- package/src/Voip/types.js +12 -0
- package/src/Voip/video-feeder.d.ts +24 -0
- package/src/Voip/video-feeder.js +268 -0
- package/src/Voip/wasm-engine.d.ts +26 -0
- package/src/Voip/wasm-engine.js +1307 -0
- package/src/Voip/worker-bootstrap.js +1023 -0
- package/src/WABinary/constants.d.ts +22 -0
- package/src/WABinary/constants.js +1300 -0
- package/src/WABinary/decode.d.ts +9 -0
- package/src/WABinary/decode.js +261 -0
- package/src/WABinary/encode.d.ts +2 -0
- package/src/WABinary/encode.js +219 -0
- package/src/WABinary/generic-utils.d.ts +76 -0
- package/src/WABinary/generic-utils.js +214 -0
- package/src/WABinary/index.d.ts +5 -0
- package/src/WABinary/index.js +5 -0
- package/src/WABinary/jid-utils.d.ts +30 -0
- package/src/WABinary/jid-utils.js +97 -0
- package/src/WABinary/types.d.ts +1 -0
- package/src/WABinary/types.js +0 -0
- package/src/WAM/BinaryInfo.d.ts +7 -0
- package/src/WAM/BinaryInfo.js +9 -0
- package/src/WAM/constants.d.ts +34926 -0
- package/src/WAM/constants.js +22852 -0
- package/src/WAM/encode.d.ts +1 -0
- package/src/WAM/encode.js +148 -0
- package/src/WAM/index.d.ts +3 -0
- package/src/WAM/index.js +3 -0
- package/src/WAUSync/Protocols/USyncContactProtocol.d.ts +36 -0
- package/src/WAUSync/Protocols/USyncContactProtocol.js +50 -0
- package/src/WAUSync/Protocols/USyncDeviceProtocol.d.ts +22 -0
- package/src/WAUSync/Protocols/USyncDeviceProtocol.js +51 -0
- package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +12 -0
- package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +26 -0
- package/src/WAUSync/Protocols/USyncStatusProtocol.d.ts +12 -0
- package/src/WAUSync/Protocols/USyncStatusProtocol.js +37 -0
- package/src/WAUSync/Protocols/USyncUsernameProtocol.d.ts +9 -0
- package/src/WAUSync/Protocols/USyncUsernameProtocol.js +23 -0
- package/src/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +38 -0
- package/src/WAUSync/Protocols/UsyncBotProfileProtocol.js +49 -0
- package/src/WAUSync/Protocols/UsyncLIDProtocol.d.ts +14 -0
- package/src/WAUSync/Protocols/UsyncLIDProtocol.js +28 -0
- package/src/WAUSync/Protocols/index.d.ts +5 -0
- package/src/WAUSync/Protocols/index.js +5 -0
- package/src/WAUSync/USyncQuery.d.ts +20 -0
- package/src/WAUSync/USyncQuery.js +93 -0
- package/src/WAUSync/USyncUser.d.ts +16 -0
- package/src/WAUSync/USyncUser.js +30 -0
- package/src/WAUSync/index.d.ts +3 -0
- package/src/WAUSync/index.js +3 -0
- package/src/assets/wasm/README.md +76 -0
- package/src/assets/wasm/loader.js +5 -0
- package/src/assets/wasm/whatsapp.wasm +0 -0
- package/src/assets/wasm/worker-modules.js +273 -0
- package/src/index.d.ts +43 -0
- package/src/index.js +48 -0
package/EXPERIMENTAL.md
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# Experimental
|
|
2
|
+
|
|
3
|
+
Features reconstructed from the WhatsApp Web bundle rather than from an existing
|
|
4
|
+
library. Each one lists where its wire format came from and how far it has been
|
|
5
|
+
verified, so you know what to trust before shipping it.
|
|
6
|
+
|
|
7
|
+
Verification levels used below:
|
|
8
|
+
|
|
9
|
+
| Level | Meaning |
|
|
10
|
+
|---|---|
|
|
11
|
+
| **Live** | executed against WhatsApp's servers and answered as expected |
|
|
12
|
+
| **Offline** | stanza, proto or parser verified locally, never sent to a server |
|
|
13
|
+
| **Derived** | shape taken from the bundle, no execution at all |
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Newsletter status
|
|
18
|
+
|
|
19
|
+
`sendNewsletterStatus`, `sendNewsletterStatusReaction`, `revokeNewsletterStatus`,
|
|
20
|
+
`getNewsletterStatuses`.
|
|
21
|
+
|
|
22
|
+
Source: the Web status-publish RPC — `WASmaxOutStatusPublishPostNewsletterStatusRequest`
|
|
23
|
+
and its mixins, plus `WASmaxInStatusPublishStatusAckMixin` for the ack.
|
|
24
|
+
|
|
25
|
+
The stanza is a single flat element; every mixin merges onto the same `<status>`:
|
|
26
|
+
|
|
27
|
+
```xml
|
|
28
|
+
<status to="123@newsletter" id="MSGID" type="text">
|
|
29
|
+
<plaintext>PROTO_MESSAGE</plaintext>
|
|
30
|
+
</status>
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Media adds `type="media" media_id="UPLOAD_HANDLE"` and `<plaintext mediatype="image">`.
|
|
34
|
+
`media_id` is the `handle` field of the newsletter upload response, which the upload
|
|
35
|
+
result now keeps. Questions ride on media with `<meta interaction_type="question"/>`,
|
|
36
|
+
question responses are text statuses carrying the parent `server_id`, reaction revoke
|
|
37
|
+
is `edit="7"` and status revoke is `edit="8"`.
|
|
38
|
+
|
|
39
|
+
The payload is the plain message proto. WhatsApp Web never wraps an outgoing status in
|
|
40
|
+
`newsletterAdminProfileStatusMessage`; that field is only a future-proof container on
|
|
41
|
+
the receiving side. Every status carries
|
|
42
|
+
`contextInfo.statusAttributions = [{ type: NEWSLETTER_STATUS }]` and
|
|
43
|
+
`featureEligibilities.canBeReshared`, matching the Web client. Pass
|
|
44
|
+
`statusAttribution: false` to omit them.
|
|
45
|
+
|
|
46
|
+
The ack is `<ack from class="status" id t [server_id] [edit]>`; a negative ack adds
|
|
47
|
+
`error` plus optional `application_error` and `backoff`.
|
|
48
|
+
|
|
49
|
+
**Verification: Live (partly).** The server accepts the stanza and answers a positive
|
|
50
|
+
ack with `class="status"`. It did **not** return `server_id`, and the published status
|
|
51
|
+
did not appear in `getNewsletterStatuses` — consistent with the account lacking the
|
|
52
|
+
`CHANNEL_STATUS_PRODUCER` capability, which gates posting. The transport is correct;
|
|
53
|
+
whether the status is stored depends on that capability.
|
|
54
|
+
|
|
55
|
+
> [!IMPORTANT]
|
|
56
|
+
> Posting a channel status needs the `channel_status_creation` feature, admin or owner
|
|
57
|
+
> rights, and `CHANNEL_STATUS_PRODUCER` in the channel capabilities. Check with
|
|
58
|
+
> `newsletterAdminCapabilities` first — without it the server acks and discards.
|
|
59
|
+
|
|
60
|
+
`server_id` is optional on the ack. When it is missing, read it back with
|
|
61
|
+
`getNewsletterStatuses`; reactions and question responses need it as `parentServerId`.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Newsletter questions and polls
|
|
66
|
+
|
|
67
|
+
Newsletter questions never worked because the `<meta>` node they are keyed by was never
|
|
68
|
+
sent. The Web client publishes them as:
|
|
69
|
+
|
|
70
|
+
```xml
|
|
71
|
+
<message to="123@newsletter" id="MSGID" type="text">
|
|
72
|
+
<meta questiontype="question"/>
|
|
73
|
+
<plaintext>PROTO</plaintext>
|
|
74
|
+
</message>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`questiontype` is `question` when the channel asks, `response` when a follower answers,
|
|
78
|
+
and `reply` when the channel answers back. The `questionReply` content shortcut was added
|
|
79
|
+
for the third case; it wraps `questionReplyMessage` and carries
|
|
80
|
+
`contextInfo.questionReplyQuotedMessage` with the question server id.
|
|
81
|
+
|
|
82
|
+
Poll result snapshots were also mis-keyed: they now send `type="poll"` with
|
|
83
|
+
`<meta polltype="result_snapshot">`. Valid `polltype` values are `creation`,
|
|
84
|
+
`quiz_creation`, `vote` and `result_snapshot`.
|
|
85
|
+
|
|
86
|
+
**Verification: Offline.** Message generation checked for all three question types;
|
|
87
|
+
the meta node is derived from the message wrapper, never guessed.
|
|
88
|
+
|
|
89
|
+
### Photo polls
|
|
90
|
+
|
|
91
|
+
Give a poll option an `image` and the poll becomes a photo poll:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
await sock.sendMessage(jid, {
|
|
95
|
+
poll: {
|
|
96
|
+
name: 'Which cover?',
|
|
97
|
+
values: [
|
|
98
|
+
{ name: 'Jakarta', image: { url: './jakarta.jpg' } },
|
|
99
|
+
{ name: 'Bandung', image: { url: './bandung.jpg' } }
|
|
100
|
+
],
|
|
101
|
+
selectableCount: 1
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Each image is uploaded once, `pollContentType` becomes `IMAGE`, and each option carries
|
|
107
|
+
the hash the Web client derives. The option images follow the poll as
|
|
108
|
+
`pollCreationOptionImageMessage` children associated by `MEDIA_POLL` with
|
|
109
|
+
`<meta message_association_type="media_poll">`, while the poll is keyed
|
|
110
|
+
`<meta polltype="creation" contenttype="image">`. String options still send a plain
|
|
111
|
+
text poll and may be mixed with image options.
|
|
112
|
+
|
|
113
|
+
**Verification: Offline.** The proto is verified — `pollContentType: IMAGE` with per
|
|
114
|
+
option hashes. One detail is inferred rather than read: the option hash is
|
|
115
|
+
`sha256(sha256hex(name) + base64(fileSha256))`, and the base64 representation of the
|
|
116
|
+
file hash is the part that was not directly observable in the bundle.
|
|
117
|
+
|
|
118
|
+
### Channel poll votes
|
|
119
|
+
|
|
120
|
+
`newsletterSendPollVote(jid, pollServerId, ['Jakarta'])` sends the votes node newsletters
|
|
121
|
+
use, where each `<vote>` is the raw sha256 of the option name rather than the encrypted
|
|
122
|
+
vote used in chats.
|
|
123
|
+
|
|
124
|
+
**Verification: Derived.**
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Newsletter queries
|
|
129
|
+
|
|
130
|
+
All taken id-by-id from the persisted queries in the bundle.
|
|
131
|
+
|
|
132
|
+
| Method | What it answers |
|
|
133
|
+
|---|---|
|
|
134
|
+
| `newsletterAdminCapabilities` | which channel features the server enabled for you |
|
|
135
|
+
| `newsletterAdminInfo` | the channel admin profile |
|
|
136
|
+
| `newsletterInsights` | admin analytics, per metric values with timestamps |
|
|
137
|
+
| `newsletterFollowers` | the follower list |
|
|
138
|
+
| `newsletterPendingAdminInvites` | admin invites still awaiting an answer |
|
|
139
|
+
| `newsletterPinMessages` / `newsletterUnpinMessages` | pin by message server id |
|
|
140
|
+
| `newsletterPollVoters` | voters grouped per vote hash |
|
|
141
|
+
| `newsletterReactionSenders` | who reacted to a message |
|
|
142
|
+
| `newsletterLabelAiContent` / `newsletterLabelPaidPartnership` | content labels |
|
|
143
|
+
| `newsletterCreateAdminInvite` / `Revoke` / `Accept` | the admin invite mutations |
|
|
144
|
+
| `newsletterQuestionResponseState` | hide or show a follower's answer |
|
|
145
|
+
| `newsletterRecommended` / `newsletterSimilar` | discovery |
|
|
146
|
+
| `newsletterDirectoryList` / `Search` / `Categories` | the channel directory |
|
|
147
|
+
|
|
148
|
+
Directory views are `RECOMMENDED`, `NEW`, `POPULAR`, `FEATURED` and `TRENDING`.
|
|
149
|
+
Categories are `BUSINESS`, `ENTERTAINMENT`, `LIFESTYLE`, `NEWS`, `ORGANIZATIONS`,
|
|
150
|
+
`PEOPLE`, `SPORTS` and `SPECIAL_EVENTS` through `SPECIAL_EVENTS_5`.
|
|
151
|
+
|
|
152
|
+
**Verification: `newsletterAdminCapabilities` is Live** — it answered with the capability
|
|
153
|
+
list for a channel and `Not Authorized` for a channel the account does not administer.
|
|
154
|
+
Everything else is **Derived**.
|
|
155
|
+
|
|
156
|
+
For insights, only `NET_FOLLOWS` and `UNFOLLOWS` appear as string literals in the bundle
|
|
157
|
+
and are the defaults; the metric list is a parameter so other names can be tried.
|
|
158
|
+
`metrics_status: MISSING` means the server has no data for the window yet, not an error.
|
|
159
|
+
|
|
160
|
+
> [!NOTE]
|
|
161
|
+
> `newsletterSubscribers` uses query id `9783111038412085`, which in the current bundle
|
|
162
|
+
> is the pending-admin-invites query, and its `xwa2_newsletter_subscribers` path does not
|
|
163
|
+
> exist in that response. `newsletterFollowers` is what the Web client uses instead. The
|
|
164
|
+
> old binding was left in place rather than silently repointed.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Username, About and link preview
|
|
169
|
+
|
|
170
|
+
| Method | Query |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `getUsername` | `xwa2_username_get` |
|
|
173
|
+
| `setUsername` / `removeUsername` | `xwa2_username_set` |
|
|
174
|
+
| `setUsernamePin` | `xwa2_username_pin_set` |
|
|
175
|
+
| `checkUsernameAvailability` | `xwa2_username_check`, with server suggestions |
|
|
176
|
+
| `updateTextStatus` / `fetchTextStatus` | `xwa2_update_text_status`, `xwa2_text_status_list` |
|
|
177
|
+
| `fetchAbout` | `xwa2_users_updates_since` |
|
|
178
|
+
| `fetchServerLinkPreview` | `xwa2_newsletter_link_preview` |
|
|
179
|
+
|
|
180
|
+
WhatsApp Web moved About to MEX, where it is `{ text, emoji: { content }, ephemeral_duration_sec }`
|
|
181
|
+
— an About can now carry an emoji and expire on its own, which the classic `status` IQ
|
|
182
|
+
cannot express. That IQ (`updateProfileStatus`) is untouched.
|
|
183
|
+
|
|
184
|
+
`fetchServerLinkPreview` lets the server build the preview instead of scraping the page.
|
|
185
|
+
|
|
186
|
+
**Verification: Derived.**
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Terms of service, opt-out and push
|
|
191
|
+
|
|
192
|
+
| Method | Namespace |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `fetchUserNotices` / `updateUserNoticeStage` | `tos` |
|
|
195
|
+
| `fetchOptOutList` / `updateOptOut` | `optoutlist` |
|
|
196
|
+
| `fetchPushSettings` | `urn:xmpp:whatsapp:push` |
|
|
197
|
+
|
|
198
|
+
WhatsApp gates features behind notices — the channel terms notice among them — so a
|
|
199
|
+
client that never answers them stays gated. `stage` is the server's own counter for a
|
|
200
|
+
notice: read the current value from `fetchUserNotices` before advancing it.
|
|
201
|
+
|
|
202
|
+
**Verification: Derived.**
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## WAProto additions
|
|
207
|
+
|
|
208
|
+
Four Message types the Web bundle declares and `WAProto` did not:
|
|
209
|
+
|
|
210
|
+
| Field | Type |
|
|
211
|
+
|---|---|
|
|
212
|
+
| 128 | `splitPaymentUpdateMessage` — `splitId`, `participantJid` |
|
|
213
|
+
| 129 | `musicMessage` — `embeddedMusic`, `songUri`, `artworkUri`, `style`, `contextInfo` |
|
|
214
|
+
| 130 | `statusLinkPreviewMetadata` — `style` |
|
|
215
|
+
| 131 | `botPlatformRegistrationSuccessMessage` — a `FutureProofMessage` |
|
|
216
|
+
|
|
217
|
+
Without these, messages of those types decode incompletely on arrival; `musicMessage` is
|
|
218
|
+
the one likely to be seen in practice.
|
|
219
|
+
|
|
220
|
+
`statusLinkPreviewMetadata.style` is declared `int32` rather than an enum: the field is an
|
|
221
|
+
enum in the bundle, but its value names were not resolvable there, and an int32 is wire
|
|
222
|
+
compatible with an enum. `MusicMessage.style` is `int32` in the bundle itself.
|
|
223
|
+
|
|
224
|
+
**Verification: Offline.** Each field was encoded and decoded again, and the field number
|
|
225
|
+
on the wire was read back from the raw bytes to confirm 128 through 131.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Proto gaps beyond Message
|
|
230
|
+
|
|
231
|
+
Catching `Message` up to field 131 closed the top-level oneof, but the bundle also declares
|
|
232
|
+
fields on other types. Those are now applied too — **34 fields across 21 types, plus the 24
|
|
233
|
+
supporting types they reference**:
|
|
234
|
+
|
|
235
|
+
| Type | Fields added |
|
|
236
|
+
|---|---|
|
|
237
|
+
| `PreKeySignalMessage`, `SessionStructure.PendingPreKey` | `kyberCiphertext`, `kyberPreKeyId` — post-quantum prekeys |
|
|
238
|
+
| `ContextInfo` | `aiProvenance`, `instagramThreadLink` |
|
|
239
|
+
| `MessageContextInfo` | `accountEncryptionAttestation`, `associatedPrimaryIdentityKey` |
|
|
240
|
+
| `Message.ProtocolMessage` | `coexStateSync`, `markAsVerifiedAction` |
|
|
241
|
+
| `SyncActionValue` | `bubbleLockMessageAction`, `businessFolderActivationAction`, `contactManagerMetadataAction`, `ctwaMessageReceivedAction`, `deviceCapabilitiesV2`, `labelSublistAction`, `sharedDeviceAllowlistAction` |
|
|
242
|
+
| `DeviceCapabilities` | `aiFbidMigration`, `bizAiSettingsSync`, `contactRefresh` |
|
|
243
|
+
| `Conversation` | `identityVerification` |
|
|
244
|
+
| `Message.Call` | `callReason` |
|
|
245
|
+
| `DeviceProps.HistorySyncConfig` | `supportNewsletter` |
|
|
246
|
+
| `ReportingTokenInfo` | `reportingTagTimestamp` |
|
|
247
|
+
|
|
248
|
+
The rest sit on `BotMetadata`, `BotAgentDeepLinkMetadata`,
|
|
249
|
+
`BotSignatureVerificationUseCaseProof`, `Message.MessageHistoryNotice`,
|
|
250
|
+
`Message.PaymentExtendedMetadata`, `PeerDataOperationResult`,
|
|
251
|
+
`ContextInfo.BusinessInteractionPills`, `SyncActionValue.BusinessBroadcastListAction`,
|
|
252
|
+
`SyncActionValue.SettingsSyncAction` and `RootSecretEntry`.
|
|
253
|
+
|
|
254
|
+
Enum-typed fields are declared `int32`. The bundle carries enum member names in a form the
|
|
255
|
+
extractor cannot resolve, and int32 is wire compatible with an enum, so the value arrives
|
|
256
|
+
intact even though the name does not.
|
|
257
|
+
|
|
258
|
+
`ExtendedTextMessage.faviconMmsMetadata` is **not** in that list: `WAProto` already had it
|
|
259
|
+
as `faviconMMSMetadata`. The comparison is case-insensitive now so an acronym spelled
|
|
260
|
+
differently on each side does not read as a missing field.
|
|
261
|
+
|
|
262
|
+
167 types in the bundle have no `WAProto` counterpart at all. Almost all of them are the
|
|
263
|
+
`ConsumerApplication` / Armadillo message family, which this library does not speak; they
|
|
264
|
+
are counted in the report but never patched.
|
|
265
|
+
|
|
266
|
+
Unknown proto fields are skipped on decode rather than fatal, so a gap shows up as data
|
|
267
|
+
quietly missing from received messages, not as an error.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Unmodelled MEX notifications
|
|
272
|
+
|
|
273
|
+
WhatsApp Web routes 35 operations through its `w:mex` notification handler. This fork
|
|
274
|
+
named 16 and shared 14 of them with the Web list; the remaining 21 fell into a `default`
|
|
275
|
+
branch that logged and returned, so nothing downstream could ever see them:
|
|
276
|
+
|
|
277
|
+
| Area | Operations |
|
|
278
|
+
|---|---|
|
|
279
|
+
| Events | `NotificationEventDelete`, `Invite`, `InviteRemove`, `Reminder`, `Rsvp`, `Update` |
|
|
280
|
+
| Group properties | `NotificationGroupPropertyUpdate`, `GroupHiddenPropertyUpdate`, `GroupLimitSharingPropertyUpdate`, `GroupMemberLinkPropertyUpdate`, `GroupMemberShareGroupHistoryModePropertyUpdate`, `GroupSafetyCheckPropertyUpdate`, `GroupAppealStatusUpdate` |
|
|
281
|
+
| Communities | `NotificationCommunityOwnerUpdate` |
|
|
282
|
+
| Newsletters | `NotificationNewsletterAIContentUpdate`, `NotificationNewsletterAdminProfileUpdate`, `NotificationNewsletterPaidPartnershipUpdate` |
|
|
283
|
+
| Scheduled messages | `NotificationScheduledMessagePost`, `NotificationScheduledMessageReveal` |
|
|
284
|
+
| Integrity | `NotificationIntegrityChallengeRequest`, `NotificationUserBrigadingUpdate` |
|
|
285
|
+
|
|
286
|
+
One of those is a plain name mismatch rather than a missing feature: the fork listened for
|
|
287
|
+
`NotificationNewsletterPaidPartnership`, while the Web bundle sends
|
|
288
|
+
`NotificationNewsletterPaidPartnershipUpdate`. Both names now route to the newsletter
|
|
289
|
+
handler, so paid-partnership notifications reach it for the first time.
|
|
290
|
+
|
|
291
|
+
The default branch now re-emits the rest instead:
|
|
292
|
+
|
|
293
|
+
```js
|
|
294
|
+
sock.ev.on('mex.notification', ({ operation, updates, data }) => {
|
|
295
|
+
console.log(operation, updates)
|
|
296
|
+
})
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Modelling each one properly means knowing its payload shape, which the bundle only gives
|
|
300
|
+
for the operations WhatsApp Web itself renders. The passthrough is the honest middle
|
|
301
|
+
ground: the data reaches you unchanged, typed as whatever the server sent, and anything
|
|
302
|
+
worth modelling can be promoted to a real event later without breaking it.
|
|
303
|
+
|
|
304
|
+
**Verification: Offline.** The operation list is read from the Web bundle's notification
|
|
305
|
+
router; the payloads have not been observed on the wire.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Keeping up with WhatsApp Web
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
npm run check:proto
|
|
313
|
+
npm run sync:proto
|
|
314
|
+
node ./script/verifyproto.js
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
`check:proto` downloads the current bundle, extracts every proto spec in it, and compares
|
|
318
|
+
the `Message` oneof and every other type against `WAProto`. It prints the live and pinned
|
|
319
|
+
client revisions and exits non-zero when WhatsApp declares fields this proto does not.
|
|
320
|
+
|
|
321
|
+
`sync:proto` applies them — it patches the generated `WAProto/index.js` and `index.d.ts` in
|
|
322
|
+
place, adding whatever supporting types the new fields reference. It is additive and
|
|
323
|
+
idempotent: running it twice changes nothing the second time. It refuses to touch a gap in
|
|
324
|
+
the `Message` oneof, because a new top-level message type warrants regenerating the proto
|
|
325
|
+
by hand.
|
|
326
|
+
|
|
327
|
+
`verifyproto.js` is the safety net. It encodes every field the bundle declares, reads the
|
|
328
|
+
field number back off the wire, decodes it again and runs `toObject` — roughly 2,900 fields
|
|
329
|
+
on the current bundle. A patch that writes the wrong tag or loses a value fails here.
|
|
330
|
+
|
|
331
|
+
All three take `PROTO_BUNDLE_DIR` to read chunks off disk instead of the network;
|
|
332
|
+
`script/fetchbundle.js` downloads them once.
|
|
333
|
+
|
|
334
|
+
The `Proto Watch` workflow runs daily and chains them: fetch the bundle, compare, bump the
|
|
335
|
+
client revision if it drifted, apply new fields, verify, and commit. If verification fails
|
|
336
|
+
the proto patch is rolled back and an issue labelled `proto-watch` is opened instead, so a
|
|
337
|
+
broken proto is never pushed.
|
|
338
|
+
|
|
339
|
+
Commits are made as the repository owner. Push uses `GH_PAT` when that secret exists and
|
|
340
|
+
falls back to `GITHUB_TOKEN` otherwise; with the fallback the commit is still authored by
|
|
341
|
+
the owner, it is simply pushed by Actions. Run it by hand from the Actions tab with
|
|
342
|
+
`apply: false` to get the report without any changes.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## Testing what is only Derived
|
|
347
|
+
|
|
348
|
+
Most of the surface above has never been executed against a server. When something
|
|
349
|
+
answers with a GraphQL error or an unexpected stanza, the error text usually names the
|
|
350
|
+
field that is wrong, and the fix is normally a variable name rather than a redesign.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Rajeh Taher/WhiskeySockets
|
|
4
|
+
Copyright (c) 2026 noxXza/luna-baileys
|
|
5
|
+
Copyright (c) 2026 RexxHayanasi
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|