zapo-js 1.6.1 → 1.7.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/dist/abprops-spec.d.ts +10 -0
- package/dist/abprops-spec.js +25 -0
- package/dist/client/WaClient.d.ts +11 -0
- package/dist/client/WaClient.js +60 -0
- package/dist/client/WaClientFactory.d.ts +2 -2
- package/dist/client/WaClientFactory.js +50 -12
- package/dist/client/coordinators/WaAbPropsCoordinator.d.ts +2 -2
- package/dist/client/coordinators/WaAbPropsCoordinator.js +16 -4
- package/dist/client/coordinators/WaIncomingNodeCoordinator.d.ts +2 -1
- package/dist/client/coordinators/WaIncomingNodeCoordinator.js +4 -0
- package/dist/client/coordinators/WaMessageCoordinator.d.ts +96 -0
- package/dist/client/coordinators/WaMessageCoordinator.js +163 -8
- package/dist/client/coordinators/WaMessageDispatchCoordinator.d.ts +64 -0
- package/dist/client/coordinators/WaMessageDispatchCoordinator.js +217 -30
- package/dist/client/coordinators/WaPrivacyCoordinator.d.ts +97 -19
- package/dist/client/coordinators/WaPrivacyCoordinator.js +152 -101
- package/dist/client/coordinators/WaRetryCoordinator.d.ts +22 -0
- package/dist/client/coordinators/WaRetryCoordinator.js +74 -11
- package/dist/client/events/dirty.d.ts +3 -0
- package/dist/client/events/dirty.js +12 -7
- package/dist/client/events/offline.d.ts +9 -0
- package/dist/client/events/offline.js +95 -0
- package/dist/client/events/privacy.d.ts +45 -0
- package/dist/client/events/privacy.js +130 -0
- package/dist/client/messaging/group-metadata.d.ts +12 -0
- package/dist/client/messaging/group-metadata.js +24 -8
- package/dist/client/messaging/link-preview.d.ts +7 -0
- package/dist/client/messaging/link-preview.js +27 -0
- package/dist/client/newsletter/content.d.ts +4 -1
- package/dist/client/newsletter/content.js +43 -18
- package/dist/client/newsletter/messaging.d.ts +2 -0
- package/dist/client/newsletter/messaging.js +2 -1
- package/dist/client/newsletter/mex.d.ts +2 -2
- package/dist/client/persistence/WriteBehindPersistence.js +2 -1
- package/dist/client/persistence/ephemeral-setting.d.ts +42 -0
- package/dist/client/persistence/ephemeral-setting.js +120 -0
- package/dist/client/persistence/group-history.d.ts +29 -0
- package/dist/client/persistence/group-history.js +149 -0
- package/dist/client/persistence/history-blob.d.ts +25 -0
- package/dist/client/persistence/history-blob.js +38 -0
- package/dist/client/persistence/history-sync.d.ts +2 -0
- package/dist/client/persistence/history-sync.js +31 -29
- package/dist/client/types.d.ts +150 -16
- package/dist/crypto/core/xeddsa.js +16 -0
- package/dist/crypto/curves/X25519.js +13 -0
- package/dist/crypto/nativeBackend.d.ts +20 -0
- package/dist/crypto/nativeBackend.js +95 -0
- package/dist/esm/abprops-spec.js +15 -0
- package/dist/esm/client/WaClient.js +60 -0
- package/dist/esm/client/WaClientFactory.js +51 -13
- package/dist/esm/client/coordinators/WaAbPropsCoordinator.js +17 -5
- package/dist/esm/client/coordinators/WaIncomingNodeCoordinator.js +4 -0
- package/dist/esm/client/coordinators/WaMessageCoordinator.js +166 -11
- package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +218 -32
- package/dist/esm/client/coordinators/WaPrivacyCoordinator.js +145 -94
- package/dist/esm/client/coordinators/WaRetryCoordinator.js +74 -11
- package/dist/esm/client/events/dirty.js +12 -7
- package/dist/esm/client/events/offline.js +92 -0
- package/dist/esm/client/events/privacy.js +123 -0
- package/dist/esm/client/messaging/group-metadata.js +25 -9
- package/dist/esm/client/messaging/link-preview.js +29 -2
- package/dist/esm/client/newsletter/content.js +44 -19
- package/dist/esm/client/newsletter/messaging.js +2 -1
- package/dist/esm/client/persistence/WriteBehindPersistence.js +2 -1
- package/dist/esm/client/persistence/ephemeral-setting.js +116 -0
- package/dist/esm/client/persistence/group-history.js +145 -0
- package/dist/esm/client/persistence/history-blob.js +34 -0
- package/dist/esm/client/persistence/history-sync.js +24 -22
- package/dist/esm/crypto/core/xeddsa.js +17 -1
- package/dist/esm/crypto/curves/X25519.js +13 -0
- package/dist/esm/crypto/nativeBackend.js +93 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/message/context-info.js +39 -0
- package/dist/esm/message/encode/content.js +20 -4
- package/dist/esm/message/encode/media-payload.js +3 -1
- package/dist/esm/message/kinds/group-history.js +36 -0
- package/dist/esm/message/primitives/incoming.js +18 -6
- package/dist/esm/protocol/abprops.js +18 -162
- package/dist/esm/protocol/constants.js +4 -3
- package/dist/esm/protocol/defaults.js +6 -0
- package/dist/esm/protocol/media.js +1 -0
- package/dist/esm/protocol/message.js +8 -0
- package/dist/esm/protocol/notification.js +1 -0
- package/dist/esm/protocol/privacy.js +70 -4
- package/dist/esm/store/contracts/chat-metadata.store.js +1 -0
- package/dist/esm/store/createStore.js +138 -59
- package/dist/esm/store/index.js +1 -0
- package/dist/esm/store/memory/chat-metadata.store.js +66 -0
- package/dist/esm/store/noop.store.js +8 -0
- package/dist/esm/transport/node/builders/privacy.js +63 -4
- package/dist/esm/util/coercion.js +12 -4
- package/dist/esm/util/index.js +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.js +15 -2
- package/dist/media/types.d.ts +1 -1
- package/dist/message/context-info.d.ts +10 -0
- package/dist/message/context-info.js +40 -0
- package/dist/message/encode/content.d.ts +7 -3
- package/dist/message/encode/content.js +20 -4
- package/dist/message/encode/media-payload.d.ts +5 -2
- package/dist/message/encode/media-payload.js +3 -1
- package/dist/message/kinds/group-history.d.ts +30 -0
- package/dist/message/kinds/group-history.js +40 -0
- package/dist/message/primitives/incoming.d.ts +5 -0
- package/dist/message/primitives/incoming.js +18 -6
- package/dist/protocol/abprops.d.ts +27 -140
- package/dist/protocol/abprops.js +18 -163
- package/dist/protocol/constants.d.ts +4 -3
- package/dist/protocol/constants.js +10 -3
- package/dist/protocol/defaults.d.ts +6 -0
- package/dist/protocol/defaults.js +6 -0
- package/dist/protocol/media.d.ts +1 -0
- package/dist/protocol/media.js +1 -0
- package/dist/protocol/message.d.ts +6 -0
- package/dist/protocol/message.js +9 -0
- package/dist/protocol/notification.d.ts +1 -0
- package/dist/protocol/notification.js +1 -0
- package/dist/protocol/privacy.d.ts +52 -0
- package/dist/protocol/privacy.js +71 -5
- package/dist/store/contracts/chat-metadata.store.d.ts +34 -0
- package/dist/store/contracts/chat-metadata.store.js +2 -0
- package/dist/store/contracts/group-metadata.store.d.ts +7 -0
- package/dist/store/contracts/thread.store.d.ts +6 -0
- package/dist/store/createStore.d.ts +10 -2
- package/dist/store/createStore.js +137 -58
- package/dist/store/index.d.ts +3 -1
- package/dist/store/index.js +3 -1
- package/dist/store/memory/chat-metadata.store.d.ts +26 -0
- package/dist/store/memory/chat-metadata.store.js +70 -0
- package/dist/store/noop.store.d.ts +2 -0
- package/dist/store/noop.store.js +9 -1
- package/dist/store/types.d.ts +221 -39
- package/dist/transport/node/builders/privacy.d.ts +26 -2
- package/dist/transport/node/builders/privacy.js +63 -3
- package/dist/util/coercion.d.ts +6 -0
- package/dist/util/coercion.js +13 -4
- package/dist/util/index.d.ts +1 -1
- package/dist/util/index.js +2 -1
- package/package.json +3 -1
- package/spec/abprops/index.d.ts +4402 -0
- package/spec/abprops/index.js +4372 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type WaAbPropName } from '../spec/abprops';
|
|
2
|
+
export { WA_ABPROPS, WA_ABPROPS_BY_CODE, WA_ABPROPS_SPECIAL_EARLY, WA_ABPROPS_USED_BEFORE_INIT, WA_GROUP_ABPROPS, WA_GROUP_ABPROPS_BY_CODE } from '../spec/abprops';
|
|
3
|
+
export type { WaAbProp, WaAbPropName, WaAbPropType, WaAbPropValue, WaAbPropValueByName, WaAbPropValueOf, WaGroupAbPropName, WaGroupAbPropValueByName } from '../spec/abprops';
|
|
4
|
+
/**
|
|
5
|
+
* Resolves the client-side prop name for a wire config code.
|
|
6
|
+
*
|
|
7
|
+
* Returns `undefined` for codes this build does not know about - the server
|
|
8
|
+
* advertises props from newer bundles, and WA Web drops those rows too.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveAbPropNameByCode(configCode: number): WaAbPropName | undefined;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WA_GROUP_ABPROPS_BY_CODE = exports.WA_GROUP_ABPROPS = exports.WA_ABPROPS_USED_BEFORE_INIT = exports.WA_ABPROPS_SPECIAL_EARLY = exports.WA_ABPROPS_BY_CODE = exports.WA_ABPROPS = void 0;
|
|
4
|
+
exports.resolveAbPropNameByCode = resolveAbPropNameByCode;
|
|
5
|
+
const abprops_1 = require("../spec/abprops");
|
|
6
|
+
var abprops_2 = require("../spec/abprops");
|
|
7
|
+
Object.defineProperty(exports, "WA_ABPROPS", { enumerable: true, get: function () { return abprops_2.WA_ABPROPS; } });
|
|
8
|
+
Object.defineProperty(exports, "WA_ABPROPS_BY_CODE", { enumerable: true, get: function () { return abprops_2.WA_ABPROPS_BY_CODE; } });
|
|
9
|
+
Object.defineProperty(exports, "WA_ABPROPS_SPECIAL_EARLY", { enumerable: true, get: function () { return abprops_2.WA_ABPROPS_SPECIAL_EARLY; } });
|
|
10
|
+
Object.defineProperty(exports, "WA_ABPROPS_USED_BEFORE_INIT", { enumerable: true, get: function () { return abprops_2.WA_ABPROPS_USED_BEFORE_INIT; } });
|
|
11
|
+
Object.defineProperty(exports, "WA_GROUP_ABPROPS", { enumerable: true, get: function () { return abprops_2.WA_GROUP_ABPROPS; } });
|
|
12
|
+
Object.defineProperty(exports, "WA_GROUP_ABPROPS_BY_CODE", { enumerable: true, get: function () { return abprops_2.WA_GROUP_ABPROPS_BY_CODE; } });
|
|
13
|
+
// The reverse map is emitted with numeric literal keys, so it cannot be indexed
|
|
14
|
+
// with a plain `number`. Widening it keeps the lookup a single property read and
|
|
15
|
+
// avoids allocating a parallel Map with 2000+ entries at module init.
|
|
16
|
+
const AB_PROP_NAME_BY_CODE = abprops_1.WA_ABPROPS_BY_CODE;
|
|
17
|
+
/**
|
|
18
|
+
* Resolves the client-side prop name for a wire config code.
|
|
19
|
+
*
|
|
20
|
+
* Returns `undefined` for codes this build does not know about - the server
|
|
21
|
+
* advertises props from newer bundles, and WA Web drops those rows too.
|
|
22
|
+
*/
|
|
23
|
+
function resolveAbPropNameByCode(configCode) {
|
|
24
|
+
return AB_PROP_NAME_BY_CODE[configCode];
|
|
25
|
+
}
|
|
@@ -27,6 +27,7 @@ declare class WaClientImpl extends EventEmitter {
|
|
|
27
27
|
private readonly appStateSync;
|
|
28
28
|
private readonly mediaTransfer;
|
|
29
29
|
private readonly writeBehind;
|
|
30
|
+
private readonly observeEphemeralSetting;
|
|
30
31
|
private connectPromise;
|
|
31
32
|
private acceptingIncomingEvents;
|
|
32
33
|
private activeIncomingHandlers;
|
|
@@ -74,6 +75,16 @@ declare class WaClientImpl extends EventEmitter {
|
|
|
74
75
|
getClockSkewMs(): number | null;
|
|
75
76
|
private bindNodeTransportEvents;
|
|
76
77
|
private handleIncomingMessageEvent;
|
|
78
|
+
/**
|
|
79
|
+
* Kicks off the group-history bundle download when the incoming message
|
|
80
|
+
* carries one. Fire-and-forget: the blob can be large, and the incoming
|
|
81
|
+
* handler must not stall behind a CDN fetch.
|
|
82
|
+
*
|
|
83
|
+
* The download outlives the handler that started it, so it takes a slot of
|
|
84
|
+
* its own in the drain accounting - `disconnect()` and `clearStoredState()`
|
|
85
|
+
* must not flush or wipe the stores while a bundle is still writing.
|
|
86
|
+
*/
|
|
87
|
+
private tryProcessGroupHistoryBundle;
|
|
77
88
|
private queryWithContext;
|
|
78
89
|
private handleIncomingFrame;
|
|
79
90
|
/**
|
package/dist/client/WaClient.js
CHANGED
|
@@ -3,12 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WaClient = void 0;
|
|
4
4
|
const node_events_1 = require("node:events");
|
|
5
5
|
const ignore_key_1 = require("./messaging/ignore-key");
|
|
6
|
+
const ephemeral_setting_1 = require("./persistence/ephemeral-setting");
|
|
7
|
+
const group_history_1 = require("./persistence/group-history");
|
|
6
8
|
const history_sync_1 = require("./persistence/history-sync");
|
|
7
9
|
const mailbox_1 = require("./persistence/mailbox");
|
|
8
10
|
const WriteBehindPersistence_1 = require("./persistence/WriteBehindPersistence");
|
|
9
11
|
const install_1 = require("./plugins/install");
|
|
10
12
|
const WaClientFactory_1 = require("./WaClientFactory");
|
|
11
13
|
const ConsoleLogger_1 = require("../infra/log/ConsoleLogger");
|
|
14
|
+
const content_1 = require("../message/encode/content");
|
|
12
15
|
const _proto_1 = require("../proto");
|
|
13
16
|
const constants_1 = require("../protocol/constants");
|
|
14
17
|
const jid_1 = require("../protocol/jid");
|
|
@@ -45,6 +48,10 @@ class WaClientImpl extends node_events_1.EventEmitter {
|
|
|
45
48
|
threadStore: this.stores.threads,
|
|
46
49
|
contactStore: this.stores.contacts
|
|
47
50
|
}, this.logger, this.options.writeBehind);
|
|
51
|
+
this.observeEphemeralSetting = (0, ephemeral_setting_1.createEphemeralObserver)({
|
|
52
|
+
logger: this.logger,
|
|
53
|
+
chatMetadataStore: this.stores.chatMetadata
|
|
54
|
+
});
|
|
48
55
|
const dependencies = (0, WaClientFactory_1.buildWaClientDependencies)({
|
|
49
56
|
base,
|
|
50
57
|
runtime: {
|
|
@@ -185,6 +192,7 @@ class WaClientImpl extends node_events_1.EventEmitter {
|
|
|
185
192
|
}
|
|
186
193
|
try {
|
|
187
194
|
this.emit('message', event);
|
|
195
|
+
this.observeEphemeralSetting(event);
|
|
188
196
|
void (0, mailbox_1.persistIncomingMailboxEntities)({
|
|
189
197
|
logger: this.logger,
|
|
190
198
|
writeBehind: this.writeBehind,
|
|
@@ -210,6 +218,9 @@ class WaClientImpl extends node_events_1.EventEmitter {
|
|
|
210
218
|
});
|
|
211
219
|
});
|
|
212
220
|
}
|
|
221
|
+
if (this.options.history?.groupBundles === true && event.message && !event.key.fromMe) {
|
|
222
|
+
this.tryProcessGroupHistoryBundle(event);
|
|
223
|
+
}
|
|
213
224
|
const protocolMessage = event.message?.protocolMessage;
|
|
214
225
|
if (!protocolMessage) {
|
|
215
226
|
return;
|
|
@@ -261,6 +272,7 @@ class WaClientImpl extends node_events_1.EventEmitter {
|
|
|
261
272
|
await (0, history_sync_1.runHistorySyncNotification)({
|
|
262
273
|
logger: this.logger,
|
|
263
274
|
mediaTransfer: this.mediaTransfer,
|
|
275
|
+
chatMetadataStore: this.stores.chatMetadata,
|
|
264
276
|
writeBehind: this.writeBehind,
|
|
265
277
|
emitEvent: this.emit.bind(this),
|
|
266
278
|
onPrivacyTokens: (conversations) => this.deps.trustedContactToken.hydrateFromHistorySync(conversations),
|
|
@@ -273,6 +285,16 @@ class WaClientImpl extends node_events_1.EventEmitter {
|
|
|
273
285
|
}
|
|
274
286
|
return;
|
|
275
287
|
}
|
|
288
|
+
if (protocolType === _proto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING) {
|
|
289
|
+
(0, ephemeral_setting_1.persistIncomingEphemeralSetting)({
|
|
290
|
+
logger: this.logger,
|
|
291
|
+
writeBehind: this.writeBehind,
|
|
292
|
+
chatMetadataStore: this.stores.chatMetadata,
|
|
293
|
+
event,
|
|
294
|
+
protocolMessage
|
|
295
|
+
});
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
276
298
|
if (SYNC_RELATED_PROTOCOL_TYPES.has(protocolType)) {
|
|
277
299
|
this.logger.info('incoming sync-related protocol message', {
|
|
278
300
|
id: event.key.id,
|
|
@@ -291,6 +313,43 @@ class WaClientImpl extends node_events_1.EventEmitter {
|
|
|
291
313
|
this.leaveIncomingHandler();
|
|
292
314
|
}
|
|
293
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* Kicks off the group-history bundle download when the incoming message
|
|
318
|
+
* carries one. Fire-and-forget: the blob can be large, and the incoming
|
|
319
|
+
* handler must not stall behind a CDN fetch.
|
|
320
|
+
*
|
|
321
|
+
* The download outlives the handler that started it, so it takes a slot of
|
|
322
|
+
* its own in the drain accounting - `disconnect()` and `clearStoredState()`
|
|
323
|
+
* must not flush or wipe the stores while a bundle is still writing.
|
|
324
|
+
*/
|
|
325
|
+
tryProcessGroupHistoryBundle(event) {
|
|
326
|
+
const bundle = (0, content_1.unwrapMessage)(event.message ?? {}).messageHistoryBundle;
|
|
327
|
+
const groupJid = event.key.remoteJid;
|
|
328
|
+
if (!bundle || !groupJid) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (!this.tryEnterIncomingHandler()) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const credentials = this.deps.authClient.getCurrentCredentials();
|
|
335
|
+
void (0, group_history_1.runGroupHistoryBundle)({
|
|
336
|
+
logger: this.logger,
|
|
337
|
+
mediaTransfer: this.mediaTransfer,
|
|
338
|
+
writeBehind: this.writeBehind,
|
|
339
|
+
emitEvent: this.emit.bind(this),
|
|
340
|
+
meJid: credentials?.meJid,
|
|
341
|
+
meLid: credentials?.meLid,
|
|
342
|
+
getAbPropNumber: (name) => this.deps.abPropsCoordinator.getConfigValue(name)
|
|
343
|
+
}, {
|
|
344
|
+
bundle,
|
|
345
|
+
groupJid,
|
|
346
|
+
senderJid: event.key.participant ?? undefined,
|
|
347
|
+
bundleMessageId: event.key.id,
|
|
348
|
+
sentAtSeconds: event.timestampSeconds
|
|
349
|
+
}).finally(() => {
|
|
350
|
+
this.leaveIncomingHandler();
|
|
351
|
+
});
|
|
352
|
+
}
|
|
294
353
|
async queryWithContext(context, node, timeoutMs = this.options.iqTimeoutMs ?? constants_1.WA_DEFAULTS.IQ_TIMEOUT_MS, contextData = {}, options = {}) {
|
|
295
354
|
return (0, query_1.queryWithContext)(async (queryNode, queryTimeoutMs) => this.deps.lowLevelCoordinator.query(queryNode, queryTimeoutMs, options), this.logger, context, node, timeoutMs, contextData);
|
|
296
355
|
}
|
|
@@ -365,6 +424,7 @@ class WaClientImpl extends node_events_1.EventEmitter {
|
|
|
365
424
|
* your own backoff.
|
|
366
425
|
*/
|
|
367
426
|
async disconnect() {
|
|
427
|
+
this.deps.privacyCoordinator.stopAccountSyncRefresh();
|
|
368
428
|
await this.pauseIncomingEventsAndWaitDrain();
|
|
369
429
|
const writeBehindFlush = await this.writeBehind.flush(this.options.writeBehind?.flushTimeoutMs);
|
|
370
430
|
if (writeBehindFlush.remaining > 0) {
|
|
@@ -18,7 +18,7 @@ import { WaMobileCoordinator } from './coordinators/WaMobileCoordinator';
|
|
|
18
18
|
import { type WaNewsletterCoordinator } from './coordinators/WaNewsletterCoordinator';
|
|
19
19
|
import { WaPassiveTasksCoordinator } from './coordinators/WaPassiveTasksCoordinator';
|
|
20
20
|
import { type WaPresenceCoordinator } from './coordinators/WaPresenceCoordinator';
|
|
21
|
-
import { type
|
|
21
|
+
import { type WaPrivacyCoordinatorRuntime } from './coordinators/WaPrivacyCoordinator';
|
|
22
22
|
import { type WaProfileCoordinator } from './coordinators/WaProfileCoordinator';
|
|
23
23
|
import { WaRetryCoordinator } from './coordinators/WaRetryCoordinator';
|
|
24
24
|
import { type WaStatusCoordinator } from './coordinators/WaStatusCoordinator';
|
|
@@ -110,7 +110,7 @@ export interface WaClientDependencies {
|
|
|
110
110
|
readonly statusCoordinator: WaStatusCoordinator;
|
|
111
111
|
readonly broadcastListCoordinator: WaBroadcastListCoordinator;
|
|
112
112
|
readonly newsletterCoordinator: WaNewsletterCoordinator;
|
|
113
|
-
readonly privacyCoordinator:
|
|
113
|
+
readonly privacyCoordinator: WaPrivacyCoordinatorRuntime;
|
|
114
114
|
readonly profileCoordinator: WaProfileCoordinator;
|
|
115
115
|
readonly businessCoordinator: WaBusinessCoordinator;
|
|
116
116
|
readonly botCoordinator: WaBotCoordinator;
|
|
@@ -149,6 +149,7 @@ function createIncomingNodeRuntime(input) {
|
|
|
149
149
|
emitIncomingFailure: (event) => emitEvent('stream_failure', event),
|
|
150
150
|
emitIncomingErrorStanza: (event) => emitEvent('stanza_error', event),
|
|
151
151
|
emitIncomingNotification: (event) => emitEvent('debug_notification', event),
|
|
152
|
+
emitOfflineThreadMetadata: (event) => emitEvent('offline_thread_metadata', event),
|
|
152
153
|
emitMexNotification: (event) => emitEvent('mex_notification', event),
|
|
153
154
|
emitRegistrationCode: (event) => emitEvent('mobile_registration_code', event),
|
|
154
155
|
emitAccountTakeoverNotice: (event) => emitEvent('mobile_account_takeover_notice', event),
|
|
@@ -244,6 +245,15 @@ function buildWaClientDependencies(input) {
|
|
|
244
245
|
allowPrivateHosts: linkPreviewOptions.allowPrivateHosts,
|
|
245
246
|
proxy: linkPreviewOptions.proxy ?? options.proxy?.linkPreview
|
|
246
247
|
});
|
|
248
|
+
const createLinkPreviewResolver = (surface) => (content) => (0, link_preview_1.resolveLinkPreview)(content.text, content.linkPreview, {
|
|
249
|
+
logger,
|
|
250
|
+
mediaTransfer,
|
|
251
|
+
getMediaConn: () => (0, messages_1.getMediaConn)(mediaMessageBuildOptions),
|
|
252
|
+
fetcher: linkPreviewFetcher,
|
|
253
|
+
options: linkPreviewOptions,
|
|
254
|
+
serverClock,
|
|
255
|
+
surface
|
|
256
|
+
});
|
|
247
257
|
const mediaMessageBuildOptions = {
|
|
248
258
|
logger,
|
|
249
259
|
mediaTransfer,
|
|
@@ -261,14 +271,7 @@ function buildWaClientDependencies(input) {
|
|
|
261
271
|
},
|
|
262
272
|
serverClock,
|
|
263
273
|
media: options.media,
|
|
264
|
-
linkPreviewResolver: (
|
|
265
|
-
logger,
|
|
266
|
-
mediaTransfer,
|
|
267
|
-
getMediaConn: () => (0, messages_1.getMediaConn)(mediaMessageBuildOptions),
|
|
268
|
-
fetcher: linkPreviewFetcher,
|
|
269
|
-
options: linkPreviewOptions,
|
|
270
|
-
serverClock
|
|
271
|
-
})
|
|
274
|
+
linkPreviewResolver: createLinkPreviewResolver()
|
|
272
275
|
};
|
|
273
276
|
const messageClient = new WaMessageClient_1.WaMessageClient({
|
|
274
277
|
logger,
|
|
@@ -371,12 +374,16 @@ function buildWaClientDependencies(input) {
|
|
|
371
374
|
generateStanzaId: () => messageDispatch.generateOutgoingMessageId(),
|
|
372
375
|
mediaTransfer,
|
|
373
376
|
getMediaConn: () => (0, messages_1.getMediaConn)(mediaMessageBuildOptions),
|
|
377
|
+
linkPreviewResolver: createLinkPreviewResolver('newsletter'),
|
|
374
378
|
getAbPropString: (name) => abPropsCoordinator.getConfigValue(name),
|
|
375
379
|
logger
|
|
376
380
|
});
|
|
377
381
|
const privacyCoordinator = (0, WaPrivacyCoordinator_1.createPrivacyCoordinator)({
|
|
382
|
+
logger,
|
|
378
383
|
queryWithContext: runtime.queryWithContext,
|
|
379
|
-
resolveUserJidPair: (userJid) => signalDeviceSync.resolveUserJidPair(userJid)
|
|
384
|
+
resolveUserJidPair: (userJid) => signalDeviceSync.resolveUserJidPair(userJid),
|
|
385
|
+
getSelfLid: () => getCurrentCredentials()?.meLid ?? null,
|
|
386
|
+
emitPrivacy: (event) => runtime.emitEvent('privacy', event)
|
|
380
387
|
});
|
|
381
388
|
const businessCoordinator = (0, WaBusinessCoordinator_1.createBusinessCoordinator)({
|
|
382
389
|
queryWithContext: runtime.queryWithContext,
|
|
@@ -415,7 +422,8 @@ function buildWaClientDependencies(input) {
|
|
|
415
422
|
}
|
|
416
423
|
return {
|
|
417
424
|
participants: participantJids,
|
|
418
|
-
ephemeral: metadata.ephemeral
|
|
425
|
+
ephemeral: metadata.ephemeral,
|
|
426
|
+
ephemeralTrigger: metadata.ephemeralTrigger
|
|
419
427
|
};
|
|
420
428
|
},
|
|
421
429
|
logger
|
|
@@ -470,6 +478,8 @@ function buildWaClientDependencies(input) {
|
|
|
470
478
|
sessionStore: sessionStore.session,
|
|
471
479
|
identityStore: sessionStore.identity,
|
|
472
480
|
deviceListStore: sessionStore.deviceList,
|
|
481
|
+
threadStore: sessionStore.threads,
|
|
482
|
+
chatMetadataStore: sessionStore.chatMetadata,
|
|
473
483
|
signalDeviceSync,
|
|
474
484
|
messageSecretStore: sessionStore.messageSecret,
|
|
475
485
|
persistAllMessageSecrets: options.addons?.persistAllSecrets === true,
|
|
@@ -512,7 +522,9 @@ function buildWaClientDependencies(input) {
|
|
|
512
522
|
trustedContactToken,
|
|
513
523
|
emitAddon: (event) => runtime.emitEvent('message_addon', event),
|
|
514
524
|
mexSocket: { query: runtime.query },
|
|
515
|
-
peerDataOperation
|
|
525
|
+
peerDataOperation,
|
|
526
|
+
isGroupHistorySendEnabled: () => abPropsCoordinator.getConfigValue('group_history_send'),
|
|
527
|
+
getAbPropNumber: (name) => abPropsCoordinator.getConfigValue(name)
|
|
516
528
|
});
|
|
517
529
|
const retryCoordinator = new WaRetryCoordinator_1.WaRetryCoordinator({
|
|
518
530
|
logger,
|
|
@@ -537,7 +549,8 @@ function buildWaClientDependencies(input) {
|
|
|
537
549
|
.handleIncomingMessageEvent(event)
|
|
538
550
|
.catch((err) => runtime.handleError((0, primitives_1.toError)(err)));
|
|
539
551
|
},
|
|
540
|
-
isMobilePrimary
|
|
552
|
+
isMobilePrimary,
|
|
553
|
+
getAbPropNumber: (name) => abPropsCoordinator.getConfigValue(name)
|
|
541
554
|
});
|
|
542
555
|
const botCoordinator = (0, WaBotCoordinator_1.createBotCoordinator)({
|
|
543
556
|
logger,
|
|
@@ -649,6 +662,7 @@ function buildWaClientDependencies(input) {
|
|
|
649
662
|
const disconnectWithClientSideEffects = async (reason, isLogout, code) => {
|
|
650
663
|
abPropsCoordinator.reset();
|
|
651
664
|
offlineResume.reset();
|
|
665
|
+
privacyCoordinator.stopAccountSyncRefresh();
|
|
652
666
|
await connectionManager?.disconnect();
|
|
653
667
|
runtime.emitEvent('connection', {
|
|
654
668
|
status: 'close',
|
|
@@ -695,6 +709,7 @@ function buildWaClientDependencies(input) {
|
|
|
695
709
|
signalProtocol,
|
|
696
710
|
senderKeyManager,
|
|
697
711
|
onDecryptFailure: (context, error) => retryCoordinator.onDecryptFailure(context, error),
|
|
712
|
+
requestPlaceholderResend: (context) => retryCoordinator.onUnavailableMessage(context),
|
|
698
713
|
emitIncomingMessage: (event) => {
|
|
699
714
|
void runtime
|
|
700
715
|
.handleIncomingMessageEvent(event)
|
|
@@ -710,6 +725,10 @@ function buildWaClientDependencies(input) {
|
|
|
710
725
|
getCurrentCredentials,
|
|
711
726
|
syncAppState: runtime.syncAppState,
|
|
712
727
|
generateUsyncSid,
|
|
728
|
+
syncAccountPrivacy: async () => {
|
|
729
|
+
await privacyCoordinator.refreshFromAccountSync();
|
|
730
|
+
},
|
|
731
|
+
emitBlocklist: (blocklist) => runtime.emitEvent('blocklist', blocklist),
|
|
713
732
|
newsletterListSubscribed: () => newsletterCoordinator.listSubscribed()
|
|
714
733
|
}, dirtyBits);
|
|
715
734
|
const offlineResume = new WaOfflineResumeCoordinator_1.WaOfflineResumeCoordinator({
|
|
@@ -891,6 +910,25 @@ function buildWaClientDependencies(input) {
|
|
|
891
910
|
return false;
|
|
892
911
|
}
|
|
893
912
|
});
|
|
913
|
+
incomingNode.registerIncomingHandler({
|
|
914
|
+
tag: constants_1.WA_NODE_TAGS.NOTIFICATION,
|
|
915
|
+
subtype: constants_1.WA_NOTIFICATION_TYPES.ACCOUNT_SYNC,
|
|
916
|
+
prepend: true,
|
|
917
|
+
/**
|
|
918
|
+
* The stanza carries the changed `<category>` inline, but it is a
|
|
919
|
+
* trigger only: the payload is a partial view, so the whole set is
|
|
920
|
+
* refetched instead. Observer only - returning false keeps the
|
|
921
|
+
* generic notification handler responsible for the ack and the
|
|
922
|
+
* `debug_notification` emit, leaving wire behavior unchanged.
|
|
923
|
+
*/
|
|
924
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
925
|
+
handler: async (node) => {
|
|
926
|
+
if ((0, helpers_1.findNodeChild)(node, constants_1.WA_NODE_TAGS.PRIVACY)) {
|
|
927
|
+
privacyCoordinator.scheduleAccountSyncRefresh();
|
|
928
|
+
}
|
|
929
|
+
return false;
|
|
930
|
+
}
|
|
931
|
+
});
|
|
894
932
|
incomingNode.registerIncomingHandler({
|
|
895
933
|
tag: constants_1.WA_NODE_TAGS.NOTIFICATION,
|
|
896
934
|
subtype: constants_1.WA_NOTIFICATION_TYPES.DEVICES,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { type WaAbPropName, type WaAbPropValue } from '../../abprops-spec';
|
|
1
2
|
import type { Logger } from '../../infra/log/types';
|
|
2
|
-
import { type AbPropName, type AbPropValue } from '../../protocol/abprops';
|
|
3
3
|
import type { BinaryNode } from '../../transport/types';
|
|
4
4
|
type WaAbPropsRuntime = {
|
|
5
5
|
readonly queryWithContext: (context: string, node: BinaryNode, timeoutMs?: number, contextData?: Readonly<Record<string, unknown>>) => Promise<BinaryNode>;
|
|
@@ -16,7 +16,7 @@ export declare class WaAbPropsCoordinator {
|
|
|
16
16
|
readonly logger: Logger;
|
|
17
17
|
readonly runtime: WaAbPropsRuntime;
|
|
18
18
|
});
|
|
19
|
-
getConfigValue<T extends
|
|
19
|
+
getConfigValue<T extends WaAbPropValue>(name: WaAbPropName): T;
|
|
20
20
|
sync(): void;
|
|
21
21
|
reset(): void;
|
|
22
22
|
private startSync;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.WaAbPropsCoordinator = void 0;
|
|
4
|
+
const _abprops_spec_1 = require("../../abprops-spec");
|
|
4
5
|
const abprops_1 = require("../events/abprops");
|
|
5
6
|
const abprops_2 = require("../../protocol/abprops");
|
|
6
7
|
const constants_1 = require("../../protocol/constants");
|
|
7
8
|
const abprops_3 = require("../../transport/node/builders/abprops");
|
|
8
9
|
const primitives_1 = require("../../util/primitives");
|
|
10
|
+
// The generated table types every entry with literal `code` / `defaultValue`
|
|
11
|
+
// types. Reading through a widened view keeps a lookup by a non-literal name
|
|
12
|
+
// from expanding into a 2000-member union at every call site.
|
|
13
|
+
const AB_PROPS = _abprops_spec_1.WA_ABPROPS;
|
|
9
14
|
class WaAbPropsCoordinator {
|
|
10
15
|
constructor(options) {
|
|
11
16
|
this.logger = options.logger;
|
|
@@ -21,7 +26,7 @@ class WaAbPropsCoordinator {
|
|
|
21
26
|
if (cached !== undefined) {
|
|
22
27
|
return cached;
|
|
23
28
|
}
|
|
24
|
-
return
|
|
29
|
+
return AB_PROPS[name].defaultValue;
|
|
25
30
|
}
|
|
26
31
|
sync() {
|
|
27
32
|
if (this.syncPromise) {
|
|
@@ -104,11 +109,11 @@ class WaAbPropsCoordinator {
|
|
|
104
109
|
let applied = 0;
|
|
105
110
|
for (let i = 0; i < result.props.length; i += 1) {
|
|
106
111
|
const entry = result.props[i];
|
|
107
|
-
const name = (0,
|
|
112
|
+
const name = (0, _abprops_spec_1.resolveAbPropNameByCode)(entry.configCode);
|
|
108
113
|
if (!name) {
|
|
109
114
|
continue;
|
|
110
115
|
}
|
|
111
|
-
const config =
|
|
116
|
+
const config = AB_PROPS[name];
|
|
112
117
|
const parsed = parseConfigValue(entry.configValue, config.type, config.defaultValue);
|
|
113
118
|
this.cache.set(name, parsed);
|
|
114
119
|
applied += 1;
|
|
@@ -123,6 +128,8 @@ class WaAbPropsCoordinator {
|
|
|
123
128
|
}
|
|
124
129
|
}
|
|
125
130
|
exports.WaAbPropsCoordinator = WaAbPropsCoordinator;
|
|
131
|
+
// parseInt, not a digits-only parse: negative values are in band, several props
|
|
132
|
+
// ship -1 as their default. Divergence: WA Web caches NaN, we keep the default.
|
|
126
133
|
function parseConfigValue(value, type, defaultValue) {
|
|
127
134
|
if (value === null) {
|
|
128
135
|
return defaultValue;
|
|
@@ -131,7 +138,12 @@ function parseConfigValue(value, type, defaultValue) {
|
|
|
131
138
|
return value === '1' || value === 'true' || value === 'True';
|
|
132
139
|
}
|
|
133
140
|
if (type === 'int') {
|
|
134
|
-
|
|
141
|
+
const parsed = Number.parseInt(value, 10);
|
|
142
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
143
|
+
}
|
|
144
|
+
if (type === 'float') {
|
|
145
|
+
const parsed = Number.parseFloat(value);
|
|
146
|
+
return Number.isNaN(parsed) ? defaultValue : parsed;
|
|
135
147
|
}
|
|
136
148
|
return value;
|
|
137
149
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { WaAuthCredentials, WaSuccessPersistAttributes } from '../../auth/types';
|
|
2
2
|
import type { WaOfflineResumeCoordinator } from '../coordinators/WaOfflineResumeCoordinator';
|
|
3
3
|
import type { WaDirtyBit } from '../events/dirty';
|
|
4
|
-
import type { WaAccountTakeoverNoticeEvent, WaBusinessEvent, WaGroupEvent, WaIncomingCallEvent, WaIncomingChatstateEvent, WaIncomingErrorStanzaEvent, WaIncomingFailureEvent, WaIncomingNodeHandlerRegistration, WaIncomingNotificationEvent, WaIncomingPresenceEvent, WaIncomingReceiptEvent, WaIncomingStanzaFilter, WaIncomingUnhandledStanzaEvent, WaMexNotificationEvent, WaPictureEvent, WaRegistrationCodeEvent } from '../types';
|
|
4
|
+
import type { WaAccountTakeoverNoticeEvent, WaBusinessEvent, WaGroupEvent, WaIncomingCallEvent, WaIncomingChatstateEvent, WaIncomingErrorStanzaEvent, WaIncomingFailureEvent, WaIncomingNodeHandlerRegistration, WaIncomingNotificationEvent, WaIncomingPresenceEvent, WaIncomingReceiptEvent, WaIncomingStanzaFilter, WaIncomingUnhandledStanzaEvent, WaMexNotificationEvent, WaOfflineThreadMetadataEvent, WaPictureEvent, WaRegistrationCodeEvent } from '../types';
|
|
5
5
|
import type { Logger } from '../../infra/log/types';
|
|
6
6
|
import type { WaConnectionCode, WaDisconnectReason } from '../../protocol/stream';
|
|
7
7
|
import { type WaStreamControlNodeResult } from '../../transport/stream/parse';
|
|
@@ -31,6 +31,7 @@ interface WaIncomingNodeRuntime {
|
|
|
31
31
|
readonly emitIncomingFailure: (event: WaIncomingFailureEvent) => void;
|
|
32
32
|
readonly emitIncomingErrorStanza: (event: WaIncomingErrorStanzaEvent) => void;
|
|
33
33
|
readonly emitIncomingNotification: (event: WaIncomingNotificationEvent) => void;
|
|
34
|
+
readonly emitOfflineThreadMetadata: (event: WaOfflineThreadMetadataEvent) => void;
|
|
34
35
|
readonly emitMexNotification: (event: WaMexNotificationEvent) => void;
|
|
35
36
|
readonly emitRegistrationCode: (event: WaRegistrationCodeEvent) => void;
|
|
36
37
|
readonly emitAccountTakeoverNotice: (event: WaAccountTakeoverNoticeEvent) => void;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.WaIncomingNodeCoordinator = void 0;
|
|
4
4
|
const chatstate_1 = require("../events/chatstate");
|
|
5
5
|
const incoming_1 = require("../events/incoming");
|
|
6
|
+
const offline_1 = require("../events/offline");
|
|
6
7
|
const presence_1 = require("../events/presence");
|
|
7
8
|
const constants_1 = require("../../protocol/constants");
|
|
8
9
|
const helpers_1 = require("../../transport/node/helpers");
|
|
@@ -381,6 +382,9 @@ class WaIncomingNodeCoordinator {
|
|
|
381
382
|
if (child.tag === 'offline') {
|
|
382
383
|
this.offlineResume.handleOfflineComplete((0, primitives_1.parseOptionalInt)(child.attrs.count) ?? 0);
|
|
383
384
|
}
|
|
385
|
+
if (child.tag === 'thread_metadata') {
|
|
386
|
+
this.runtime.emitOfflineThreadMetadata((0, offline_1.parseOfflineThreadMetadata)(child));
|
|
387
|
+
}
|
|
384
388
|
handled = true;
|
|
385
389
|
}
|
|
386
390
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Readable } from 'node:stream';
|
|
2
|
+
import type { WaAbPropName } from '../../abprops-spec';
|
|
2
3
|
import type { WaMessageDispatchCoordinator } from '../coordinators/WaMessageDispatchCoordinator';
|
|
3
4
|
import type { WaTrustedContactTokenCoordinator } from '../coordinators/WaTrustedContactTokenCoordinator';
|
|
4
5
|
import { type WaUploadMediaSource } from '../media';
|
|
@@ -25,6 +26,65 @@ export interface WaMessageCoordinatorDeps {
|
|
|
25
26
|
readonly emitAddon: (event: WaIncomingAddonEvent) => void;
|
|
26
27
|
readonly mexSocket: WaMexQuerySocket;
|
|
27
28
|
readonly peerDataOperation: PeerDataOperationRequester;
|
|
29
|
+
/**
|
|
30
|
+
* Server-synced `group_history_send` AB-prop. WhatsApp gates the sender
|
|
31
|
+
* side per account, and rejects the stanza with SMAX_INVALID when it is
|
|
32
|
+
* off, so {@link WaMessageCoordinator.shareGroupHistory} checks it before
|
|
33
|
+
* spending an upload.
|
|
34
|
+
*/
|
|
35
|
+
readonly isGroupHistorySendEnabled: () => boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Reads a server-synced numeric AB-prop, falling back to its shipped
|
|
38
|
+
* default. Sole source for the group-history message-count limit, so a
|
|
39
|
+
* server-side change takes effect without a release.
|
|
40
|
+
*/
|
|
41
|
+
readonly getAbPropNumber: (name: WaAbPropName) => number;
|
|
42
|
+
}
|
|
43
|
+
export interface WaShareGroupHistoryInput {
|
|
44
|
+
/**
|
|
45
|
+
* Members to share the history with. Must be current members of the group,
|
|
46
|
+
* written in the group's own addressing mode - a LID-addressed group only
|
|
47
|
+
* matches `@lid` entries, and a PN one only matches `@s.whatsapp.net`.
|
|
48
|
+
* Anything else throws, naming the mode the group uses. Read the mode off
|
|
49
|
+
* `client.group.queryGroupMetadata()`, whose participants carry both forms.
|
|
50
|
+
*/
|
|
51
|
+
readonly toJids: readonly string[];
|
|
52
|
+
/**
|
|
53
|
+
* How many of the most recent messages to read from the mailbox store.
|
|
54
|
+
* Defaults to WhatsApp's `group_history_message_count_limit` (100).
|
|
55
|
+
* Ignored when {@link messages} is supplied - that list is bundled as-is.
|
|
56
|
+
*/
|
|
57
|
+
readonly count?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Only read messages at or after this timestamp (ms) from the mailbox
|
|
60
|
+
* store. Ignored when {@link messages} is supplied.
|
|
61
|
+
*/
|
|
62
|
+
readonly sinceMs?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Messages to bundle, bypassing the mailbox store entirely - {@link count}
|
|
65
|
+
* and {@link sinceMs} do not apply, so the caller owns the windowing.
|
|
66
|
+
* Required when the `messages` store domain is `'none'` (the default),
|
|
67
|
+
* since there is nothing to read back in that case.
|
|
68
|
+
*/
|
|
69
|
+
readonly messages?: readonly Proto.IWebMessageInfo[];
|
|
70
|
+
/**
|
|
71
|
+
* Pinned messages older than the shared window. The receiver injects these
|
|
72
|
+
* regardless of the age cutoff it applies to `messages`.
|
|
73
|
+
*/
|
|
74
|
+
readonly outOfWindowPinnedMessages?: readonly Proto.IWebMessageInfo[];
|
|
75
|
+
}
|
|
76
|
+
export interface WaShareGroupHistoryResult {
|
|
77
|
+
/** Stanza id of the bundle message, fanned out only to `historyReceivers`. */
|
|
78
|
+
readonly bundleMessageId: string;
|
|
79
|
+
/**
|
|
80
|
+
* Stanza id of the notice message, sent to the whole group. Absent when the
|
|
81
|
+
* notice failed to send: the bundle still reached its receivers, so do not
|
|
82
|
+
* retry the share - it would upload and deliver the history a second time.
|
|
83
|
+
*/
|
|
84
|
+
readonly noticeMessageId?: string;
|
|
85
|
+
readonly messagesCount: number;
|
|
86
|
+
readonly historyReceivers: readonly string[];
|
|
87
|
+
readonly nonHistoryReceivers: readonly string[];
|
|
28
88
|
}
|
|
29
89
|
export interface WaRequestHistorySyncInput {
|
|
30
90
|
/** Chat the older messages should be fetched from. */
|
|
@@ -111,6 +171,8 @@ export declare class WaMessageCoordinator {
|
|
|
111
171
|
private readonly emitAddon;
|
|
112
172
|
private readonly mexSocket;
|
|
113
173
|
private readonly peerDataOperation;
|
|
174
|
+
private readonly isGroupHistorySendEnabled;
|
|
175
|
+
private readonly getAbPropNumber;
|
|
114
176
|
constructor(deps: WaMessageCoordinatorDeps);
|
|
115
177
|
/**
|
|
116
178
|
* Asks the server to backfill older messages for `chatJid` beyond what
|
|
@@ -128,6 +190,40 @@ export declare class WaMessageCoordinator {
|
|
|
128
190
|
requestHistorySync(input: WaRequestHistorySyncInput): Promise<{
|
|
129
191
|
readonly messageId: string;
|
|
130
192
|
}>;
|
|
193
|
+
/**
|
|
194
|
+
* Shares recent group history with members who joined after the fact - the
|
|
195
|
+
* counterpart of the `group_history_bundle` event on the receiving side.
|
|
196
|
+
*
|
|
197
|
+
* Sends two messages: the bundle itself, encrypted per device and fanned
|
|
198
|
+
* out **only** to `toJids` (never to the whole group), followed by a hidden
|
|
199
|
+
* notice addressed to everyone so other clients can render the "history was
|
|
200
|
+
* shared" marker.
|
|
201
|
+
*
|
|
202
|
+
* WhatsApp gates the sender side per account through the `group_history_send`
|
|
203
|
+
* AB-prop and rejects the stanza with SMAX_INVALID when it is off, so this
|
|
204
|
+
* throws up front rather than spending an upload. Admin-only groups
|
|
205
|
+
* (`memberShareGroupHistoryMode: 'admin_share'`) reject a share from a
|
|
206
|
+
* regular member server-side - read `client.group.queryGroupMetadata()`
|
|
207
|
+
* first if you want to check that too.
|
|
208
|
+
*
|
|
209
|
+
* @throws when the account is not allowed to share group history, when
|
|
210
|
+
* `groupJid` is not a group, when any of `toJids` is not a current member
|
|
211
|
+
* (or is this account), or when there is nothing to bundle.
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* await client.message.shareGroupHistory('12036@g.us', {
|
|
215
|
+
* toJids: ['5511999999999@s.whatsapp.net'],
|
|
216
|
+
* count: 50
|
|
217
|
+
* })
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
shareGroupHistory(groupJid: string, input: WaShareGroupHistoryInput): Promise<WaShareGroupHistoryResult>;
|
|
221
|
+
/**
|
|
222
|
+
* Reads the most recent messages of a group back out of the mailbox store
|
|
223
|
+
* and rebuilds the `WebMessageInfo` shape a bundle carries. Yields nothing
|
|
224
|
+
* when the `messages` store domain is `'none'`.
|
|
225
|
+
*/
|
|
226
|
+
private loadGroupHistoryMessages;
|
|
131
227
|
/**
|
|
132
228
|
* Fetches the server-side "reachout" timelock that throttles cold outreach
|
|
133
229
|
* to non-contacts, returning the active window when enforcement is on.
|