@d0v3riz/baileys 6.7.5 → 6.7.7
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 +1 -1
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.js +3 -1
- package/lib/Socket/business.d.ts +14 -5
- package/lib/Socket/chats.d.ts +2 -5
- package/lib/Socket/chats.js +9 -0
- package/lib/Socket/groups.d.ts +8 -1
- package/lib/Socket/groups.js +10 -0
- package/lib/Socket/index.d.ts +14 -5
- package/lib/Socket/messages-recv.d.ts +14 -6
- package/lib/Socket/messages-recv.js +95 -8
- package/lib/Socket/messages-send.d.ts +10 -4
- package/lib/Socket/messages-send.js +77 -68
- package/lib/Socket/registration.d.ts +14 -5
- package/lib/Store/make-in-memory-store.js +5 -1
- package/lib/Types/Chat.d.ts +1 -0
- package/lib/Types/Events.d.ts +5 -1
- package/lib/Types/Message.d.ts +27 -24
- package/lib/Types/Socket.d.ts +5 -0
- package/lib/Utils/decode-wa-message.d.ts +1 -0
- package/lib/Utils/decode-wa-message.js +16 -7
- package/lib/Utils/history.d.ts +4 -0
- package/lib/Utils/history.js +3 -0
- package/lib/Utils/messages-media.d.ts +0 -1
- package/lib/Utils/messages.js +44 -58
- package/lib/Utils/process-message.d.ts +3 -2
- package/lib/Utils/process-message.js +43 -24
- package/lib/WABinary/jid-utils.d.ts +2 -0
- package/lib/WABinary/jid-utils.js +4 -1
- package/package.json +1 -1
|
@@ -12,11 +12,10 @@ const Utils_1 = require("../Utils");
|
|
|
12
12
|
const link_preview_1 = require("../Utils/link-preview");
|
|
13
13
|
const WABinary_1 = require("../WABinary");
|
|
14
14
|
const groups_1 = require("./groups");
|
|
15
|
-
var ListType = WAProto_1.proto.Message.ListMessage.ListType;
|
|
16
15
|
const makeMessagesSocket = (config) => {
|
|
17
|
-
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, } = config;
|
|
16
|
+
const { logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, options: axiosOptions, patchMessageBeforeSending, cachedGroupMetadata, } = config;
|
|
18
17
|
const sock = (0, groups_1.makeGroupsSocket)(config);
|
|
19
|
-
const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, generateMessageTag, sendNode, groupMetadata, groupToggleEphemeral } = sock;
|
|
18
|
+
const { ev, authState, processingMutex, signalRepository, upsertMessage, query, fetchPrivacySettings, generateMessageTag, sendNode, groupMetadata, groupToggleEphemeral, } = sock;
|
|
20
19
|
const userDevicesCache = config.userDevicesCache || new node_cache_1.default({
|
|
21
20
|
stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.USER_DEVICES,
|
|
22
21
|
useClones: false
|
|
@@ -222,6 +221,28 @@ const makeMessagesSocket = (config) => {
|
|
|
222
221
|
}
|
|
223
222
|
return didFetchNewSession;
|
|
224
223
|
};
|
|
224
|
+
const sendPeerDataOperationMessage = async (pdoMessage) => {
|
|
225
|
+
var _a;
|
|
226
|
+
//TODO: for later, abstract the logic to send a Peer Message instead of just PDO - useful for App State Key Resync with phone
|
|
227
|
+
if (!((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
228
|
+
throw new boom_1.Boom('Not authenticated');
|
|
229
|
+
}
|
|
230
|
+
const protocolMessage = {
|
|
231
|
+
protocolMessage: {
|
|
232
|
+
peerDataOperationRequestMessage: pdoMessage,
|
|
233
|
+
type: WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_MESSAGE
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
const meJid = (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id);
|
|
237
|
+
const msgId = await relayMessage(meJid, protocolMessage, {
|
|
238
|
+
additionalAttributes: {
|
|
239
|
+
category: 'peer',
|
|
240
|
+
// eslint-disable-next-line camelcase
|
|
241
|
+
push_priority: 'high_force',
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
return msgId;
|
|
245
|
+
};
|
|
225
246
|
const createParticipantNodes = async (jids, message, extraAttrs) => {
|
|
226
247
|
const patched = await patchMessageBeforeSending(message, jids);
|
|
227
248
|
const bytes = (0, Utils_1.encodeWAMessage)(patched);
|
|
@@ -249,7 +270,7 @@ const makeMessagesSocket = (config) => {
|
|
|
249
270
|
}));
|
|
250
271
|
return { nodes, shouldIncludeDeviceIdentity };
|
|
251
272
|
};
|
|
252
|
-
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache,
|
|
273
|
+
const relayMessage = async (jid, message, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }) => {
|
|
253
274
|
var _a;
|
|
254
275
|
const meId = authState.creds.me.id;
|
|
255
276
|
let shouldIncludeDeviceIdentity = false;
|
|
@@ -260,6 +281,7 @@ const makeMessagesSocket = (config) => {
|
|
|
260
281
|
const isLid = server === 'lid';
|
|
261
282
|
msgId = msgId || (0, Utils_1.generateMessageIDV2)((_a = sock.user) === null || _a === void 0 ? void 0 : _a.id);
|
|
262
283
|
useUserDevicesCache = useUserDevicesCache !== false;
|
|
284
|
+
useCachedGroupMetadata = useCachedGroupMetadata !== false && !isStatus;
|
|
263
285
|
const participants = [];
|
|
264
286
|
const destinationJid = (!isStatus) ? (0, WABinary_1.jidEncode)(user, isLid ? 'lid' : isGroup ? 'g.us' : 's.whatsapp.net') : statusJid;
|
|
265
287
|
const binaryNodeContent = [];
|
|
@@ -270,6 +292,7 @@ const makeMessagesSocket = (config) => {
|
|
|
270
292
|
message
|
|
271
293
|
}
|
|
272
294
|
};
|
|
295
|
+
const extraAttrs = {};
|
|
273
296
|
if (participant) {
|
|
274
297
|
// when the retry request is not for a group
|
|
275
298
|
// only send to the specific device that asked for a retry
|
|
@@ -281,16 +304,22 @@ const makeMessagesSocket = (config) => {
|
|
|
281
304
|
devices.push({ user, device });
|
|
282
305
|
}
|
|
283
306
|
await authState.keys.transaction(async () => {
|
|
284
|
-
var _a, _b;
|
|
307
|
+
var _a, _b, _c, _d, _e;
|
|
285
308
|
const mediaType = getMediaType(message);
|
|
309
|
+
if (mediaType) {
|
|
310
|
+
extraAttrs['mediatype'] = mediaType;
|
|
311
|
+
}
|
|
312
|
+
if ((_a = (0, Utils_1.normalizeMessageContent)(message)) === null || _a === void 0 ? void 0 : _a.pinInChatMessage) {
|
|
313
|
+
extraAttrs['decrypt-fail'] = 'hide';
|
|
314
|
+
}
|
|
286
315
|
if (isGroup || isStatus) {
|
|
287
316
|
const [groupData, senderKeyMap] = await Promise.all([
|
|
288
317
|
(async () => {
|
|
289
|
-
let groupData = cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
|
|
290
|
-
if (groupData) {
|
|
318
|
+
let groupData = useCachedGroupMetadata && cachedGroupMetadata ? await cachedGroupMetadata(jid) : undefined;
|
|
319
|
+
if (groupData && Array.isArray(groupData === null || groupData === void 0 ? void 0 : groupData.participants)) {
|
|
291
320
|
logger.trace({ jid, participants: groupData.participants.length }, 'using cached group metadata');
|
|
292
321
|
}
|
|
293
|
-
if (!
|
|
322
|
+
else if (!isStatus) {
|
|
294
323
|
groupData = await groupMetadata(jid);
|
|
295
324
|
}
|
|
296
325
|
return groupData;
|
|
@@ -339,7 +368,7 @@ const makeMessagesSocket = (config) => {
|
|
|
339
368
|
}
|
|
340
369
|
};
|
|
341
370
|
await assertSessions(senderKeyJids, false);
|
|
342
|
-
const result = await createParticipantNodes(senderKeyJids, senderKeyMsg,
|
|
371
|
+
const result = await createParticipantNodes(senderKeyJids, senderKeyMsg, extraAttrs);
|
|
343
372
|
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || result.shouldIncludeDeviceIdentity;
|
|
344
373
|
participants.push(...result.nodes);
|
|
345
374
|
}
|
|
@@ -355,18 +384,20 @@ const makeMessagesSocket = (config) => {
|
|
|
355
384
|
if (!participant) {
|
|
356
385
|
devices.push({ user });
|
|
357
386
|
// do not send message to self if the device is 0 (mobile)
|
|
358
|
-
if (
|
|
359
|
-
|
|
387
|
+
if (!((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) === 'peer' && user === meUser)) {
|
|
388
|
+
if (meDevice !== undefined && meDevice !== 0) {
|
|
389
|
+
devices.push({ user: meUser });
|
|
390
|
+
}
|
|
391
|
+
const additionalDevices = await getUSyncDevices([meId, jid], !!useUserDevicesCache, true);
|
|
392
|
+
devices.push(...additionalDevices);
|
|
360
393
|
}
|
|
361
|
-
const additionalDevices = await getUSyncDevices([meId, jid], !!useUserDevicesCache, true);
|
|
362
|
-
devices.push(...additionalDevices);
|
|
363
394
|
}
|
|
364
395
|
const allJids = [];
|
|
365
396
|
const meJids = [];
|
|
366
397
|
const otherJids = [];
|
|
367
398
|
for (const { user, device } of devices) {
|
|
368
399
|
const isMe = user === meUser;
|
|
369
|
-
const jid = (0, WABinary_1.jidEncode)(isMe && isLid ? ((
|
|
400
|
+
const jid = (0, WABinary_1.jidEncode)(isMe && isLid ? ((_c = (_b = authState.creds) === null || _b === void 0 ? void 0 : _b.me) === null || _c === void 0 ? void 0 : _c.lid.split(':')[0]) || user : user, isLid ? 'lid' : 's.whatsapp.net', device);
|
|
370
401
|
if (isMe) {
|
|
371
402
|
meJids.push(jid);
|
|
372
403
|
}
|
|
@@ -377,19 +408,27 @@ const makeMessagesSocket = (config) => {
|
|
|
377
408
|
}
|
|
378
409
|
await assertSessions(allJids, false);
|
|
379
410
|
const [{ nodes: meNodes, shouldIncludeDeviceIdentity: s1 }, { nodes: otherNodes, shouldIncludeDeviceIdentity: s2 }] = await Promise.all([
|
|
380
|
-
createParticipantNodes(meJids, meMsg,
|
|
381
|
-
createParticipantNodes(otherJids, message,
|
|
411
|
+
createParticipantNodes(meJids, meMsg, extraAttrs),
|
|
412
|
+
createParticipantNodes(otherJids, message, extraAttrs)
|
|
382
413
|
]);
|
|
383
414
|
participants.push(...meNodes);
|
|
384
415
|
participants.push(...otherNodes);
|
|
385
416
|
shouldIncludeDeviceIdentity = shouldIncludeDeviceIdentity || s1 || s2;
|
|
386
417
|
}
|
|
387
418
|
if (participants.length) {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
419
|
+
if ((additionalAttributes === null || additionalAttributes === void 0 ? void 0 : additionalAttributes['category']) === 'peer') {
|
|
420
|
+
const peerNode = (_e = (_d = participants[0]) === null || _d === void 0 ? void 0 : _d.content) === null || _e === void 0 ? void 0 : _e[0];
|
|
421
|
+
if (peerNode) {
|
|
422
|
+
binaryNodeContent.push(peerNode); // push only enc
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
binaryNodeContent.push({
|
|
427
|
+
tag: 'participants',
|
|
428
|
+
attrs: {},
|
|
429
|
+
content: participants
|
|
430
|
+
});
|
|
431
|
+
}
|
|
393
432
|
}
|
|
394
433
|
const stanza = {
|
|
395
434
|
tag: 'message',
|
|
@@ -427,19 +466,8 @@ const makeMessagesSocket = (config) => {
|
|
|
427
466
|
});
|
|
428
467
|
logger.debug({ jid }, 'adding device identity');
|
|
429
468
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
stanza.content.push({
|
|
433
|
-
tag: 'biz',
|
|
434
|
-
attrs: {},
|
|
435
|
-
content: [
|
|
436
|
-
{
|
|
437
|
-
tag: buttonType,
|
|
438
|
-
attrs: getButtonArgs(message),
|
|
439
|
-
}
|
|
440
|
-
]
|
|
441
|
-
});
|
|
442
|
-
logger.debug({ jid }, 'adding business node');
|
|
469
|
+
if (additionalNodes && additionalNodes.length > 0) {
|
|
470
|
+
stanza.content.push(...additionalNodes);
|
|
443
471
|
}
|
|
444
472
|
logger.debug({ msgId }, `sending message to ${participants.length} devices`);
|
|
445
473
|
await sendNode(stanza);
|
|
@@ -489,38 +517,8 @@ const makeMessagesSocket = (config) => {
|
|
|
489
517
|
else if (message.interactiveResponseMessage) {
|
|
490
518
|
return 'native_flow_response';
|
|
491
519
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if (message.buttonsMessage) {
|
|
495
|
-
return 'buttons';
|
|
496
|
-
}
|
|
497
|
-
else if (message.buttonsResponseMessage) {
|
|
498
|
-
return 'buttons_response';
|
|
499
|
-
}
|
|
500
|
-
else if (message.interactiveResponseMessage) {
|
|
501
|
-
return 'interactive_response';
|
|
502
|
-
}
|
|
503
|
-
else if (message.listMessage) {
|
|
504
|
-
return 'list';
|
|
505
|
-
}
|
|
506
|
-
else if (message.listResponseMessage) {
|
|
507
|
-
return 'list_response';
|
|
508
|
-
}
|
|
509
|
-
};
|
|
510
|
-
const getButtonArgs = (message) => {
|
|
511
|
-
if (message.templateMessage) {
|
|
512
|
-
// TODO: Add attributes
|
|
513
|
-
return {};
|
|
514
|
-
}
|
|
515
|
-
else if (message.listMessage) {
|
|
516
|
-
const type = message.listMessage.listType;
|
|
517
|
-
if (!type) {
|
|
518
|
-
throw new boom_1.Boom('Expected list type inside message');
|
|
519
|
-
}
|
|
520
|
-
return { v: '2', type: ListType[type].toLowerCase() };
|
|
521
|
-
}
|
|
522
|
-
else {
|
|
523
|
-
return {};
|
|
520
|
+
else if (message.groupInviteMessage) {
|
|
521
|
+
return 'url';
|
|
524
522
|
}
|
|
525
523
|
};
|
|
526
524
|
const getPrivacyTokens = async (jids) => {
|
|
@@ -558,11 +556,13 @@ const makeMessagesSocket = (config) => {
|
|
|
558
556
|
relayMessage,
|
|
559
557
|
sendReceipt,
|
|
560
558
|
sendReceipts,
|
|
561
|
-
getButtonArgs,
|
|
562
559
|
readMessages,
|
|
563
560
|
refreshMediaConn,
|
|
564
561
|
waUploadToServer,
|
|
565
562
|
fetchPrivacySettings,
|
|
563
|
+
sendPeerDataOperationMessage,
|
|
564
|
+
createParticipantNodes,
|
|
565
|
+
getUSyncDevices,
|
|
566
566
|
updateMediaMessage: async (message) => {
|
|
567
567
|
const content = (0, Utils_1.assertMediaContent)(message.message);
|
|
568
568
|
const mediaKey = content.mediaKey;
|
|
@@ -632,6 +632,8 @@ const makeMessagesSocket = (config) => {
|
|
|
632
632
|
? waUploadToServer
|
|
633
633
|
: undefined
|
|
634
634
|
}),
|
|
635
|
+
//TODO: CACHE
|
|
636
|
+
getProfilePicUrl: sock.profilePictureUrl,
|
|
635
637
|
upload: waUploadToServer,
|
|
636
638
|
mediaCache: config.mediaCache,
|
|
637
639
|
options: config.options,
|
|
@@ -640,6 +642,7 @@ const makeMessagesSocket = (config) => {
|
|
|
640
642
|
});
|
|
641
643
|
const isDeleteMsg = 'delete' in content && !!content.delete;
|
|
642
644
|
const isEditMsg = 'edit' in content && !!content.edit;
|
|
645
|
+
const isPinMsg = 'pin' in content && !!content.pin;
|
|
643
646
|
const additionalAttributes = {};
|
|
644
647
|
// required for delete
|
|
645
648
|
if (isDeleteMsg) {
|
|
@@ -654,7 +657,13 @@ const makeMessagesSocket = (config) => {
|
|
|
654
657
|
else if (isEditMsg) {
|
|
655
658
|
additionalAttributes.edit = '1';
|
|
656
659
|
}
|
|
657
|
-
|
|
660
|
+
else if (isPinMsg) {
|
|
661
|
+
additionalAttributes.edit = '2';
|
|
662
|
+
}
|
|
663
|
+
if ('cachedGroupMetadata' in options) {
|
|
664
|
+
console.warn('cachedGroupMetadata in sendMessage are deprecated, now cachedGroupMetadata is part of the socket config.');
|
|
665
|
+
}
|
|
666
|
+
await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, useCachedGroupMetadata: options.useCachedGroupMetadata, additionalAttributes, statusJidList: options.statusJidList });
|
|
658
667
|
if (config.emitOwnEvents) {
|
|
659
668
|
process.nextTick(() => {
|
|
660
669
|
processingMutex.mutex(() => (upsertMessage(fullMsg, 'append')));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="long" />
|
|
1
2
|
/// <reference types="node" />
|
|
2
3
|
import { AxiosRequestConfig } from 'axios';
|
|
3
4
|
import { KeyPair, SignedKeyPair, SocketConfig } from '../Types';
|
|
@@ -21,20 +22,27 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
|
|
|
21
22
|
sendMessageAck: ({ tag, attrs, content }: import("../WABinary").BinaryNode) => Promise<void>;
|
|
22
23
|
sendRetryRequest: (node: import("../WABinary").BinaryNode, forceIncludeKeys?: boolean) => Promise<void>;
|
|
23
24
|
rejectCall: (callId: string, callFrom: string) => Promise<void>;
|
|
25
|
+
fetchMessageHistory: (count: number, oldestMsgKey: import("../Types").WAProto.IMessageKey, oldestMsgTimestamp: number | import("long").Long) => Promise<string>;
|
|
26
|
+
requestPlaceholderResend: (messageKey: import("../Types").WAProto.IMessageKey) => Promise<string | undefined>;
|
|
24
27
|
getPrivacyTokens: (jids: string[]) => Promise<import("../WABinary").BinaryNode>;
|
|
25
28
|
assertSessions: (jids: string[], force: boolean) => Promise<boolean>;
|
|
26
|
-
relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, useUserDevicesCache,
|
|
29
|
+
relayMessage: (jid: string, message: import("../Types").WAProto.IMessage, { messageId: msgId, participant, additionalAttributes, additionalNodes, useUserDevicesCache, useCachedGroupMetadata, statusJidList }: import("../Types").MessageRelayOptions) => Promise<string>;
|
|
27
30
|
sendReceipt: (jid: string, participant: string | undefined, messageIds: string[], type: import("../Types").MessageReceiptType) => Promise<void>;
|
|
28
31
|
sendReceipts: (keys: import("../Types").WAProto.IMessageKey[], type: import("../Types").MessageReceiptType) => Promise<void>;
|
|
29
|
-
getButtonArgs: (message: import("../Types").WAProto.IMessage) => {
|
|
30
|
-
[key: string]: string;
|
|
31
|
-
};
|
|
32
32
|
readMessages: (keys: import("../Types").WAProto.IMessageKey[]) => Promise<void>;
|
|
33
33
|
refreshMediaConn: (forceGet?: boolean) => Promise<import("../Types").MediaConnInfo>;
|
|
34
34
|
waUploadToServer: import("../Types").WAMediaUploadFunction;
|
|
35
35
|
fetchPrivacySettings: (force?: boolean) => Promise<{
|
|
36
36
|
[_: string]: string;
|
|
37
37
|
}>;
|
|
38
|
+
sendPeerDataOperationMessage: (pdoMessage: import("../Types").WAProto.Message.IPeerDataOperationRequestMessage) => Promise<string>;
|
|
39
|
+
createParticipantNodes: (jids: string[], message: import("../Types").WAProto.IMessage, extraAttrs?: {
|
|
40
|
+
[key: string]: string;
|
|
41
|
+
} | undefined) => Promise<{
|
|
42
|
+
nodes: import("../WABinary").BinaryNode[];
|
|
43
|
+
shouldIncludeDeviceIdentity: boolean;
|
|
44
|
+
}>;
|
|
45
|
+
getUSyncDevices: (jids: string[], useCache: boolean, ignoreZeroDevices: boolean) => Promise<import("../WABinary").JidWithDevice[]>;
|
|
38
46
|
updateMediaMessage: (message: import("../Types").WAProto.IWebMessageInfo) => Promise<import("../Types").WAProto.IWebMessageInfo>;
|
|
39
47
|
sendMessage: (jid: string, content: import("../Types").AnyMessageContent, options?: import("../Types").MiscMessageGenerationOptions) => Promise<import("../Types").WAProto.WebMessageInfo | undefined>;
|
|
40
48
|
groupMetadata: (jid: string) => Promise<import("../Types").GroupMetadata>;
|
|
@@ -57,6 +65,7 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
|
|
|
57
65
|
groupInviteCode: (jid: string) => Promise<string | undefined>;
|
|
58
66
|
groupRevokeInvite: (jid: string) => Promise<string | undefined>;
|
|
59
67
|
groupAcceptInvite: (code: string) => Promise<string | undefined>;
|
|
68
|
+
groupRevokeInviteV4: (groupJid: string, invitedJid: string) => Promise<boolean>;
|
|
60
69
|
groupAcceptInviteV4: (key: string | import("../Types").WAProto.IMessageKey, inviteMessage: import("../Types").WAProto.Message.IGroupInviteMessage) => Promise<string>;
|
|
61
70
|
groupGetInviteInfo: (code: string) => Promise<import("../Types").GroupMetadata>;
|
|
62
71
|
groupToggleEphemeral: (jid: string, ephemeralExpiration: number) => Promise<void>;
|
|
@@ -94,7 +103,7 @@ export declare const makeRegistrationSocket: (config: SocketConfig) => {
|
|
|
94
103
|
updateProfilePicturePrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
|
|
95
104
|
updateStatusPrivacy: (value: import("../Types").WAPrivacyValue) => Promise<void>;
|
|
96
105
|
updateReadReceiptsPrivacy: (value: import("../Types").WAReadReceiptsValue) => Promise<void>;
|
|
97
|
-
updateGroupsAddPrivacy: (value: import("../Types").
|
|
106
|
+
updateGroupsAddPrivacy: (value: import("../Types").WAPrivacyGroupAddValue) => Promise<void>;
|
|
98
107
|
updateDefaultDisappearingMode: (duration: number) => Promise<void>;
|
|
99
108
|
getBusinessProfile: (jid: string) => Promise<void | import("../Types").WABusinessProfile>;
|
|
100
109
|
resyncAppState: (collections: readonly ("critical_block" | "critical_unblock_low" | "regular_high" | "regular_low" | "regular")[], isInitialSync: boolean) => Promise<void>;
|
|
@@ -66,7 +66,11 @@ exports.default = (config) => {
|
|
|
66
66
|
ev.on('connection.update', update => {
|
|
67
67
|
Object.assign(state, update);
|
|
68
68
|
});
|
|
69
|
-
ev.on('messaging-history.set', ({ chats: newChats, contacts: newContacts, messages: newMessages, isLatest }) => {
|
|
69
|
+
ev.on('messaging-history.set', ({ chats: newChats, contacts: newContacts, messages: newMessages, isLatest, syncType }) => {
|
|
70
|
+
if (syncType === WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
|
|
71
|
+
return; // FOR NOW,
|
|
72
|
+
//TODO: HANDLE
|
|
73
|
+
}
|
|
70
74
|
if (isLatest) {
|
|
71
75
|
chats.clear();
|
|
72
76
|
for (const id in messages) {
|
package/lib/Types/Chat.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { MinimalMessage } from './Message';
|
|
|
7
7
|
/** privacy settings in WhatsApp Web */
|
|
8
8
|
export type WAPrivacyValue = 'all' | 'contacts' | 'contact_blacklist' | 'none';
|
|
9
9
|
export type WAPrivacyOnlineValue = 'all' | 'match_last_seen';
|
|
10
|
+
export type WAPrivacyGroupAddValue = 'all' | 'contacts' | 'contact_blacklist';
|
|
10
11
|
export type WAReadReceiptsValue = 'all' | 'none';
|
|
11
12
|
export type WAPrivacyCallValue = 'all' | 'known';
|
|
12
13
|
/** set of statuses visible to other people; see updatePresence() in WhatsAppWeb.Send */
|
package/lib/Types/Events.d.ts
CHANGED
|
@@ -19,7 +19,9 @@ export type BaileysEventMap = {
|
|
|
19
19
|
chats: Chat[];
|
|
20
20
|
contacts: Contact[];
|
|
21
21
|
messages: WAMessage[];
|
|
22
|
-
isLatest
|
|
22
|
+
isLatest?: boolean;
|
|
23
|
+
progress?: number | null;
|
|
24
|
+
syncType?: proto.HistorySync.HistorySyncType;
|
|
23
25
|
};
|
|
24
26
|
/** upsert chats */
|
|
25
27
|
'chats.upsert': Chat[];
|
|
@@ -58,10 +60,12 @@ export type BaileysEventMap = {
|
|
|
58
60
|
/**
|
|
59
61
|
* add/update the given messages. If they were received while the connection was online,
|
|
60
62
|
* the update will have type: "notify"
|
|
63
|
+
* if requestId is provided, then the messages was received from the phone due to it being unavailable
|
|
61
64
|
* */
|
|
62
65
|
'messages.upsert': {
|
|
63
66
|
messages: WAMessage[];
|
|
64
67
|
type: MessageUpsertType;
|
|
68
|
+
requestId?: string;
|
|
65
69
|
};
|
|
66
70
|
/** message was reacted to. If reaction was removed -- then "reaction.text" will be falsey */
|
|
67
71
|
'messages.reaction': {
|
package/lib/Types/Message.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { Readable } from 'stream';
|
|
|
7
7
|
import type { URL } from 'url';
|
|
8
8
|
import { proto } from '../../WAProto';
|
|
9
9
|
import { MEDIA_HKDF_KEY_MAPPING } from '../Defaults';
|
|
10
|
+
import { BinaryNode } from '../WABinary';
|
|
10
11
|
import type { GroupMetadata } from './GroupMetadata';
|
|
11
12
|
import { CacheStore } from './Socket';
|
|
12
13
|
export { proto as WAProto };
|
|
@@ -63,26 +64,9 @@ type Contextable = {
|
|
|
63
64
|
type ViewOnce = {
|
|
64
65
|
viewOnce?: boolean;
|
|
65
66
|
};
|
|
66
|
-
type Buttonable = {
|
|
67
|
-
/** add buttons to the message */
|
|
68
|
-
buttons?: proto.Message.ButtonsMessage.IButton[];
|
|
69
|
-
};
|
|
70
|
-
type Templatable = {
|
|
71
|
-
/** add buttons to the message (conflicts with normal buttons)*/
|
|
72
|
-
templateButtons?: proto.IHydratedTemplateButton[];
|
|
73
|
-
footer?: string;
|
|
74
|
-
};
|
|
75
67
|
type Editable = {
|
|
76
68
|
edit?: WAMessageKey;
|
|
77
69
|
};
|
|
78
|
-
type Listable = {
|
|
79
|
-
/** Sections of the List */
|
|
80
|
-
sections?: proto.Message.ListMessage.ISection[];
|
|
81
|
-
/** Title of a List Message only */
|
|
82
|
-
title?: string;
|
|
83
|
-
/** Text of the bnutton on the list (required) */
|
|
84
|
-
buttonText?: string;
|
|
85
|
-
};
|
|
86
70
|
type WithDimensions = {
|
|
87
71
|
width?: number;
|
|
88
72
|
height?: number;
|
|
@@ -93,6 +77,7 @@ export type PollMessageOptions = {
|
|
|
93
77
|
values: string[];
|
|
94
78
|
/** 32 byte message secret to encrypt poll selections */
|
|
95
79
|
messageSecret?: Uint8Array;
|
|
80
|
+
toAnnouncementGroup?: boolean;
|
|
96
81
|
};
|
|
97
82
|
type SharePhoneNumber = {
|
|
98
83
|
sharePhoneNumber: boolean;
|
|
@@ -105,14 +90,14 @@ export type AnyMediaMessageContent = (({
|
|
|
105
90
|
image: WAMediaUpload;
|
|
106
91
|
caption?: string;
|
|
107
92
|
jpegThumbnail?: string;
|
|
108
|
-
} & Mentionable & Contextable &
|
|
93
|
+
} & Mentionable & Contextable & WithDimensions) | ({
|
|
109
94
|
video: WAMediaUpload;
|
|
110
95
|
caption?: string;
|
|
111
96
|
gifPlayback?: boolean;
|
|
112
97
|
jpegThumbnail?: string;
|
|
113
98
|
/** if set to true, will send as a `video note` */
|
|
114
99
|
ptv?: boolean;
|
|
115
|
-
} & Mentionable & Contextable &
|
|
100
|
+
} & Mentionable & Contextable & WithDimensions) | {
|
|
116
101
|
audio: WAMediaUpload;
|
|
117
102
|
/** if set to true, will send as a `voice note` */
|
|
118
103
|
ptt?: boolean;
|
|
@@ -126,7 +111,7 @@ export type AnyMediaMessageContent = (({
|
|
|
126
111
|
mimetype: string;
|
|
127
112
|
fileName?: string;
|
|
128
113
|
caption?: string;
|
|
129
|
-
} & Contextable
|
|
114
|
+
} & Contextable)) & {
|
|
130
115
|
mimetype?: string;
|
|
131
116
|
} & Editable;
|
|
132
117
|
export type ButtonReplyInfo = {
|
|
@@ -134,15 +119,22 @@ export type ButtonReplyInfo = {
|
|
|
134
119
|
id: string;
|
|
135
120
|
index: number;
|
|
136
121
|
};
|
|
122
|
+
export type GroupInviteInfo = {
|
|
123
|
+
inviteCode: string;
|
|
124
|
+
inviteExpiration: number;
|
|
125
|
+
text: string;
|
|
126
|
+
jid: string;
|
|
127
|
+
subject: string;
|
|
128
|
+
};
|
|
137
129
|
export type WASendableProduct = Omit<proto.Message.ProductMessage.IProductSnapshot, 'productImage'> & {
|
|
138
130
|
productImage: WAMediaUpload;
|
|
139
131
|
};
|
|
140
132
|
export type AnyRegularMessageContent = (({
|
|
141
133
|
text: string;
|
|
142
134
|
linkPreview?: WAUrlInfo | null;
|
|
143
|
-
} & Mentionable & Contextable &
|
|
135
|
+
} & Mentionable & Contextable & Editable) | AnyMediaMessageContent | ({
|
|
144
136
|
poll: PollMessageOptions;
|
|
145
|
-
} & Mentionable & Contextable &
|
|
137
|
+
} & Mentionable & Contextable & Editable) | {
|
|
146
138
|
contacts: {
|
|
147
139
|
displayName?: string;
|
|
148
140
|
contacts: proto.Message.IContactMessage[];
|
|
@@ -154,8 +146,17 @@ export type AnyRegularMessageContent = (({
|
|
|
154
146
|
} | {
|
|
155
147
|
buttonReply: ButtonReplyInfo;
|
|
156
148
|
type: 'template' | 'plain';
|
|
149
|
+
} | {
|
|
150
|
+
groupInvite: GroupInviteInfo;
|
|
157
151
|
} | {
|
|
158
152
|
listReply: Omit<proto.Message.IListResponseMessage, 'contextInfo'>;
|
|
153
|
+
} | {
|
|
154
|
+
pin: WAMessageKey;
|
|
155
|
+
type: proto.PinInChat.Type;
|
|
156
|
+
/**
|
|
157
|
+
* 24 hours, 7 days, 30 days
|
|
158
|
+
*/
|
|
159
|
+
time?: 86400 | 604800 | 2592000;
|
|
159
160
|
} | {
|
|
160
161
|
product: WASendableProduct;
|
|
161
162
|
businessOwnerJid?: string;
|
|
@@ -175,8 +176,8 @@ export type GroupMetadataParticipants = Pick<GroupMetadata, 'participants'>;
|
|
|
175
176
|
type MinimalRelayOptions = {
|
|
176
177
|
/** override the message ID with a custom provided string */
|
|
177
178
|
messageId?: string;
|
|
178
|
-
/**
|
|
179
|
-
|
|
179
|
+
/** should we use group metadata cache, or fetch afresh from the server; default assumed to be "true" */
|
|
180
|
+
useCachedGroupMetadata?: boolean;
|
|
180
181
|
};
|
|
181
182
|
export type MessageRelayOptions = MinimalRelayOptions & {
|
|
182
183
|
/** only send to a specific participant; used when a message decryption fails for a single user */
|
|
@@ -188,6 +189,7 @@ export type MessageRelayOptions = MinimalRelayOptions & {
|
|
|
188
189
|
additionalAttributes?: {
|
|
189
190
|
[_: string]: string;
|
|
190
191
|
};
|
|
192
|
+
additionalNodes?: BinaryNode[];
|
|
191
193
|
/** should we use the devices cache, or fetch afresh from the server; default assumed to be "true" */
|
|
192
194
|
useUserDevicesCache?: boolean;
|
|
193
195
|
/** jid list of participants for status@broadcast */
|
|
@@ -237,6 +239,7 @@ export type MediaGenerationOptions = {
|
|
|
237
239
|
};
|
|
238
240
|
export type MessageContentGenerationOptions = MediaGenerationOptions & {
|
|
239
241
|
getUrlInfo?: (text: string) => Promise<WAUrlInfo | undefined>;
|
|
242
|
+
getProfilePicUrl?: (jid: string, type: 'image' | 'preview') => Promise<string | undefined>;
|
|
240
243
|
};
|
|
241
244
|
export type MessageGenerationOptions = MessageContentGenerationOptions & MessageGenerationOptionsFromContent;
|
|
242
245
|
/**
|
package/lib/Types/Socket.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { Logger } from 'pino';
|
|
|
6
6
|
import type { URL } from 'url';
|
|
7
7
|
import { proto } from '../../WAProto';
|
|
8
8
|
import { AuthenticationState, SignalAuthState, TransactionCapabilityOptions } from './Auth';
|
|
9
|
+
import { GroupMetadata } from './GroupMetadata';
|
|
9
10
|
import { MediaConnInfo } from './Message';
|
|
10
11
|
import { SignalRepository } from './Signal';
|
|
11
12
|
export type WAVersion = [number, number, number];
|
|
@@ -71,6 +72,8 @@ export type SocketConfig = {
|
|
|
71
72
|
userDevicesCache?: CacheStore;
|
|
72
73
|
/** cache to store call offers */
|
|
73
74
|
callOfferCache?: CacheStore;
|
|
75
|
+
/** cache to track placeholder resends */
|
|
76
|
+
placeholderResendCache?: CacheStore;
|
|
74
77
|
/** width for link preview images */
|
|
75
78
|
linkPreviewImageThumbnailWidth: number;
|
|
76
79
|
/** Should Baileys ask the phone for full history, will be received async */
|
|
@@ -105,6 +108,8 @@ export type SocketConfig = {
|
|
|
105
108
|
* (solves the "this message can take a while" issue) can be retried
|
|
106
109
|
* */
|
|
107
110
|
getMessage: (key: proto.IMessageKey) => Promise<proto.IMessage | undefined>;
|
|
111
|
+
/** cached group metadata, use to prevent redundant requests to WA & speed up msg sending */
|
|
112
|
+
cachedGroupMetadata: (jid: string) => Promise<GroupMetadata | undefined>;
|
|
108
113
|
makeSignalRepository: (auth: SignalAuthState) => SignalRepository;
|
|
109
114
|
/** Socket passthrough */
|
|
110
115
|
socket?: any;
|
|
@@ -2,6 +2,7 @@ import { Logger } from 'pino';
|
|
|
2
2
|
import { proto } from '../../WAProto';
|
|
3
3
|
import { SignalRepository } from '../Types';
|
|
4
4
|
import { BinaryNode } from '../WABinary';
|
|
5
|
+
export declare const NO_MESSAGE_FOUND_ERROR_TEXT = "Message absent from node";
|
|
5
6
|
/**
|
|
6
7
|
* Decode the received node as a message.
|
|
7
8
|
* @note this will only parse the message, not decrypt it
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.decryptMessageNode = exports.decodeMessageNode = void 0;
|
|
3
|
+
exports.decryptMessageNode = exports.decodeMessageNode = exports.NO_MESSAGE_FOUND_ERROR_TEXT = void 0;
|
|
4
4
|
const boom_1 = require("@hapi/boom");
|
|
5
5
|
const WAProto_1 = require("../../WAProto");
|
|
6
6
|
const WABinary_1 = require("../WABinary");
|
|
7
7
|
const generics_1 = require("./generics");
|
|
8
|
-
|
|
8
|
+
exports.NO_MESSAGE_FOUND_ERROR_TEXT = 'Message absent from node';
|
|
9
9
|
/**
|
|
10
10
|
* Decode the received node as a message.
|
|
11
11
|
* @note this will only parse the message, not decrypt it
|
|
12
12
|
*/
|
|
13
13
|
function decodeMessageNode(stanza, meId, meLid) {
|
|
14
|
+
var _a;
|
|
14
15
|
let msgType;
|
|
15
16
|
let chatId;
|
|
16
17
|
let author;
|
|
@@ -68,11 +69,16 @@ function decodeMessageNode(stanza, meId, meLid) {
|
|
|
68
69
|
chatId = from;
|
|
69
70
|
author = participant;
|
|
70
71
|
}
|
|
72
|
+
else if ((0, WABinary_1.isJidNewsletter)(from)) {
|
|
73
|
+
msgType = 'newsletter';
|
|
74
|
+
chatId = from;
|
|
75
|
+
author = from;
|
|
76
|
+
}
|
|
71
77
|
else {
|
|
72
78
|
throw new boom_1.Boom('Unknown message type', { data: stanza });
|
|
73
79
|
}
|
|
74
80
|
const fromMe = ((0, WABinary_1.isLidUser)(from) ? isMeLid : isMe)(stanza.attrs.participant || stanza.attrs.from);
|
|
75
|
-
const pushname = stanza.attrs.notify;
|
|
81
|
+
const pushname = (_a = stanza === null || stanza === void 0 ? void 0 : stanza.attrs) === null || _a === void 0 ? void 0 : _a.notify;
|
|
76
82
|
const key = {
|
|
77
83
|
remoteJid: chatId,
|
|
78
84
|
fromMe,
|
|
@@ -111,7 +117,7 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
111
117
|
const details = WAProto_1.proto.VerifiedNameCertificate.Details.decode(cert.details);
|
|
112
118
|
fullMessage.verifiedBizName = details.verifiedName;
|
|
113
119
|
}
|
|
114
|
-
if (tag !== 'enc') {
|
|
120
|
+
if (tag !== 'enc' && tag !== 'plaintext') {
|
|
115
121
|
continue;
|
|
116
122
|
}
|
|
117
123
|
if (!(content instanceof Uint8Array)) {
|
|
@@ -120,7 +126,7 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
120
126
|
decryptables += 1;
|
|
121
127
|
let msgBuffer;
|
|
122
128
|
try {
|
|
123
|
-
const e2eType = attrs.type;
|
|
129
|
+
const e2eType = tag === 'plaintext' ? 'plaintext' : attrs.type;
|
|
124
130
|
switch (e2eType) {
|
|
125
131
|
case 'skmsg':
|
|
126
132
|
msgBuffer = await repository.decryptGroupMessage({
|
|
@@ -138,10 +144,13 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
138
144
|
ciphertext: content
|
|
139
145
|
});
|
|
140
146
|
break;
|
|
147
|
+
case 'plaintext':
|
|
148
|
+
msgBuffer = content;
|
|
149
|
+
break;
|
|
141
150
|
default:
|
|
142
151
|
throw new Error(`Unknown e2e type: ${e2eType}`);
|
|
143
152
|
}
|
|
144
|
-
let msg = WAProto_1.proto.Message.decode((0, generics_1.unpadRandomMax16)(msgBuffer));
|
|
153
|
+
let msg = WAProto_1.proto.Message.decode(e2eType !== 'plaintext' ? (0, generics_1.unpadRandomMax16)(msgBuffer) : msgBuffer);
|
|
145
154
|
msg = ((_a = msg.deviceSentMessage) === null || _a === void 0 ? void 0 : _a.message) || msg;
|
|
146
155
|
if (msg.senderKeyDistributionMessage) {
|
|
147
156
|
try {
|
|
@@ -171,7 +180,7 @@ const decryptMessageNode = (stanza, meId, meLid, repository, logger) => {
|
|
|
171
180
|
// if nothing was found to decrypt
|
|
172
181
|
if (!decryptables) {
|
|
173
182
|
fullMessage.messageStubType = WAProto_1.proto.WebMessageInfo.StubType.CIPHERTEXT;
|
|
174
|
-
fullMessage.messageStubParameters = [NO_MESSAGE_FOUND_ERROR_TEXT
|
|
183
|
+
fullMessage.messageStubParameters = [exports.NO_MESSAGE_FOUND_ERROR_TEXT];
|
|
175
184
|
}
|
|
176
185
|
}
|
|
177
186
|
};
|
package/lib/Utils/history.d.ts
CHANGED
|
@@ -6,10 +6,14 @@ export declare const processHistoryMessage: (item: proto.IHistorySync) => {
|
|
|
6
6
|
chats: Chat[];
|
|
7
7
|
contacts: Contact[];
|
|
8
8
|
messages: proto.IWebMessageInfo[];
|
|
9
|
+
syncType: proto.HistorySync.HistorySyncType;
|
|
10
|
+
progress: number | null | undefined;
|
|
9
11
|
};
|
|
10
12
|
export declare const downloadAndProcessHistorySyncNotification: (msg: proto.Message.IHistorySyncNotification, options: AxiosRequestConfig<any>) => Promise<{
|
|
11
13
|
chats: Chat[];
|
|
12
14
|
contacts: Contact[];
|
|
13
15
|
messages: proto.IWebMessageInfo[];
|
|
16
|
+
syncType: proto.HistorySync.HistorySyncType;
|
|
17
|
+
progress: number | null | undefined;
|
|
14
18
|
}>;
|
|
15
19
|
export declare const getHistoryMsg: (message: proto.IMessage) => proto.Message.IHistorySyncNotification | null | undefined;
|
package/lib/Utils/history.js
CHANGED
|
@@ -32,6 +32,7 @@ const processHistoryMessage = (item) => {
|
|
|
32
32
|
case WAProto_1.proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP:
|
|
33
33
|
case WAProto_1.proto.HistorySync.HistorySyncType.RECENT:
|
|
34
34
|
case WAProto_1.proto.HistorySync.HistorySyncType.FULL:
|
|
35
|
+
case WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND:
|
|
35
36
|
for (const chat of item.conversations) {
|
|
36
37
|
contacts.push({ id: chat.id, name: chat.name || undefined });
|
|
37
38
|
const msgs = chat.messages || [];
|
|
@@ -74,6 +75,8 @@ const processHistoryMessage = (item) => {
|
|
|
74
75
|
chats,
|
|
75
76
|
contacts,
|
|
76
77
|
messages,
|
|
78
|
+
syncType: item.syncType,
|
|
79
|
+
progress: item.progress,
|
|
77
80
|
};
|
|
78
81
|
};
|
|
79
82
|
exports.processHistoryMessage = processHistoryMessage;
|