@d0v3riz/baileys 6.7.4 → 6.7.6
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 +5 -4
- package/lib/Defaults/index.js +3 -1
- package/lib/Socket/business.d.ts +8 -5
- package/lib/Socket/chats.d.ts +3 -8
- package/lib/Socket/chats.js +15 -1
- package/lib/Socket/groups.d.ts +9 -1
- package/lib/Socket/groups.js +12 -1
- package/lib/Socket/index.d.ts +8 -5
- package/lib/Socket/messages-recv.d.ts +8 -6
- package/lib/Socket/messages-recv.js +105 -12
- package/lib/Socket/messages-send.d.ts +5 -3
- package/lib/Socket/messages-send.js +83 -71
- package/lib/Socket/registration.d.ts +8 -5
- package/lib/Socket/socket.js +2 -2
- package/lib/Store/make-in-memory-store.js +5 -1
- package/lib/Types/Chat.d.ts +2 -0
- package/lib/Types/Events.d.ts +5 -1
- package/lib/Types/GroupMetadata.d.ts +1 -1
- package/lib/Types/Message.d.ts +27 -24
- package/lib/Types/Socket.d.ts +5 -0
- package/lib/Types/index.d.ts +7 -0
- package/lib/Utils/crypto.d.ts +1 -1
- package/lib/Utils/crypto.js +4 -2
- package/lib/Utils/decode-wa-message.d.ts +1 -0
- package/lib/Utils/decode-wa-message.js +16 -7
- package/lib/Utils/generics.d.ts +4 -9
- package/lib/Utils/generics.js +34 -8
- package/lib/Utils/history.d.ts +4 -0
- package/lib/Utils/history.js +3 -0
- package/lib/Utils/messages-media.js +8 -14
- package/lib/Utils/messages.js +48 -58
- package/lib/Utils/noise-handler.d.ts +1 -1
- package/lib/Utils/noise-handler.js +2 -2
- package/lib/Utils/process-message.d.ts +3 -2
- package/lib/Utils/process-message.js +47 -24
- package/lib/Utils/signal.js +26 -16
- package/lib/WABinary/decode.d.ts +2 -2
- package/lib/WABinary/decode.js +6 -4
- package/lib/WABinary/encode.d.ts +1 -1
- package/lib/WABinary/encode.js +8 -4
- package/lib/WABinary/jid-utils.d.ts +2 -0
- package/lib/WABinary/jid-utils.js +4 -1
- package/package.json +6 -5
|
@@ -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/generics.d.ts
CHANGED
|
@@ -2,16 +2,10 @@
|
|
|
2
2
|
import { AxiosRequestConfig } from 'axios';
|
|
3
3
|
import { Logger } from 'pino';
|
|
4
4
|
import { proto } from '../../WAProto';
|
|
5
|
-
import { BaileysEventEmitter, BaileysEventMap, WACallUpdateType, WAVersion } from '../Types';
|
|
5
|
+
import { BaileysEventEmitter, BaileysEventMap, BrowsersMap, WACallUpdateType, WAVersion } from '../Types';
|
|
6
6
|
import { BinaryNode } from '../WABinary';
|
|
7
|
-
export declare const Browsers:
|
|
8
|
-
|
|
9
|
-
macOS: (browser: any) => [string, string, string];
|
|
10
|
-
baileys: (browser: any) => [string, string, string];
|
|
11
|
-
windows: (browser: any) => [string, string, string];
|
|
12
|
-
/** The appropriate browser based on your OS & release */
|
|
13
|
-
appropriate: (browser: any) => [string, string, string];
|
|
14
|
-
};
|
|
7
|
+
export declare const Browsers: BrowsersMap;
|
|
8
|
+
export declare const getPlatformId: (browser: string) => any;
|
|
15
9
|
export declare const BufferJSON: {
|
|
16
10
|
replacer: (k: any, value: any) => any;
|
|
17
11
|
reviver: (_: any, value: any) => any;
|
|
@@ -38,6 +32,7 @@ export declare const delayCancellable: (ms: number) => {
|
|
|
38
32
|
cancel: () => void;
|
|
39
33
|
};
|
|
40
34
|
export declare function promiseTimeout<T>(ms: number | undefined, promise: (resolve: (v: T) => void, reject: (error: any) => void) => void): Promise<T>;
|
|
35
|
+
export declare const generateMessageIDV2: (userId?: string) => string;
|
|
41
36
|
export declare const generateMessageID: () => string;
|
|
42
37
|
export declare function bindWaitForEvent<T extends keyof BaileysEventMap>(ev: BaileysEventEmitter, event: T): (check: (u: BaileysEventMap[T]) => boolean | undefined, timeoutMs?: number) => Promise<void>;
|
|
43
38
|
export declare const bindWaitForConnectionUpdate: (ev: BaileysEventEmitter) => (check: (u: Partial<import("../Types").ConnectionState>) => boolean | undefined, timeoutMs?: number) => Promise<void>;
|
package/lib/Utils/generics.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.bytesToCrockford = exports.trimUndefined = exports.isWABusinessPlatform = exports.getCodeFromWSError = exports.getCallStatusFromNode = exports.getErrorCodeFromStreamError = exports.getStatusFromReceiptType = exports.generateMdTagPrefix = exports.fetchLatestWaWebVersion = exports.fetchLatestBaileysVersion = exports.printQRIfNecessaryListener = exports.bindWaitForConnectionUpdate = exports.bindWaitForEvent = exports.generateMessageID = exports.promiseTimeout = exports.delayCancellable = exports.delay = exports.debouncedTimeout = exports.unixTimestampSeconds = exports.toNumber = exports.encodeBigEndian = exports.generateRegistrationId = exports.encodeWAMessage = exports.unpadRandomMax16 = exports.writeRandomPadMax16 = exports.getKeyAuthor = exports.BufferJSON = exports.Browsers = void 0;
|
|
6
|
+
exports.bytesToCrockford = exports.trimUndefined = exports.isWABusinessPlatform = exports.getCodeFromWSError = exports.getCallStatusFromNode = exports.getErrorCodeFromStreamError = exports.getStatusFromReceiptType = exports.generateMdTagPrefix = exports.fetchLatestWaWebVersion = exports.fetchLatestBaileysVersion = exports.printQRIfNecessaryListener = exports.bindWaitForConnectionUpdate = exports.bindWaitForEvent = exports.generateMessageID = exports.generateMessageIDV2 = exports.promiseTimeout = exports.delayCancellable = exports.delay = exports.debouncedTimeout = exports.unixTimestampSeconds = exports.toNumber = exports.encodeBigEndian = exports.generateRegistrationId = exports.encodeWAMessage = exports.unpadRandomMax16 = exports.writeRandomPadMax16 = exports.getKeyAuthor = exports.BufferJSON = exports.getPlatformId = exports.Browsers = void 0;
|
|
7
7
|
const boom_1 = require("@hapi/boom");
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
9
|
const crypto_1 = require("crypto");
|
|
@@ -16,16 +16,24 @@ const PLATFORM_MAP = {
|
|
|
16
16
|
'aix': 'AIX',
|
|
17
17
|
'darwin': 'Mac OS',
|
|
18
18
|
'win32': 'Windows',
|
|
19
|
-
'android': 'Android'
|
|
19
|
+
'android': 'Android',
|
|
20
|
+
'freebsd': 'FreeBSD',
|
|
21
|
+
'openbsd': 'OpenBSD',
|
|
22
|
+
'sunos': 'Solaris'
|
|
20
23
|
};
|
|
21
24
|
exports.Browsers = {
|
|
22
|
-
ubuntu: browser => ['Ubuntu', browser, '
|
|
23
|
-
macOS: browser => ['Mac OS', browser, '
|
|
24
|
-
baileys: browser => ['Baileys', browser, '
|
|
25
|
-
windows: browser => ['Windows', browser, '10.0.
|
|
25
|
+
ubuntu: (browser) => ['Ubuntu', browser, '22.04.4'],
|
|
26
|
+
macOS: (browser) => ['Mac OS', browser, '14.4.1'],
|
|
27
|
+
baileys: (browser) => ['Baileys', browser, '6.5.0'],
|
|
28
|
+
windows: (browser) => ['Windows', browser, '10.0.22631'],
|
|
26
29
|
/** The appropriate browser based on your OS & release */
|
|
27
|
-
appropriate: browser => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
|
|
30
|
+
appropriate: (browser) => [PLATFORM_MAP[(0, os_1.platform)()] || 'Ubuntu', browser, (0, os_1.release)()]
|
|
28
31
|
};
|
|
32
|
+
const getPlatformId = (browser) => {
|
|
33
|
+
const platformType = WAProto_1.proto.DeviceProps.PlatformType[browser.toUpperCase()];
|
|
34
|
+
return platformType ? platformType.toString().charCodeAt(0).toString() : '49'; //chrome
|
|
35
|
+
};
|
|
36
|
+
exports.getPlatformId = getPlatformId;
|
|
29
37
|
exports.BufferJSON = {
|
|
30
38
|
replacer: (k, value) => {
|
|
31
39
|
if (Buffer.isBuffer(value) || value instanceof Uint8Array || (value === null || value === void 0 ? void 0 : value.type) === 'Buffer') {
|
|
@@ -147,8 +155,26 @@ async function promiseTimeout(ms, promise) {
|
|
|
147
155
|
return p;
|
|
148
156
|
}
|
|
149
157
|
exports.promiseTimeout = promiseTimeout;
|
|
158
|
+
// inspired from whatsmeow code
|
|
159
|
+
// https://github.com/tulir/whatsmeow/blob/64bc969fbe78d31ae0dd443b8d4c80a5d026d07a/send.go#L42
|
|
160
|
+
const generateMessageIDV2 = (userId) => {
|
|
161
|
+
const data = Buffer.alloc(8 + 20 + 16);
|
|
162
|
+
data.writeBigUInt64BE(BigInt(Math.floor(Date.now() / 1000)));
|
|
163
|
+
if (userId) {
|
|
164
|
+
const id = (0, WABinary_1.jidDecode)(userId);
|
|
165
|
+
if (id === null || id === void 0 ? void 0 : id.user) {
|
|
166
|
+
data.write(id.user, 8);
|
|
167
|
+
data.write('@c.us', 8 + id.user.length);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const random = (0, crypto_1.randomBytes)(16);
|
|
171
|
+
random.copy(data, 28);
|
|
172
|
+
const hash = (0, crypto_1.createHash)('sha256').update(data).digest();
|
|
173
|
+
return (process.env.WHATSAPP_CONN_IDMSG || 'WHPI') + hash.toString('hex').toUpperCase().substring(0, 18);
|
|
174
|
+
};
|
|
175
|
+
exports.generateMessageIDV2 = generateMessageIDV2;
|
|
150
176
|
// generate a random ID to attach to a message
|
|
151
|
-
const generateMessageID = () => (process.env.WHATSAPP_CONN_IDMSG || 'WHPI') + (0, crypto_1.randomBytes)(
|
|
177
|
+
const generateMessageID = () => (process.env.WHATSAPP_CONN_IDMSG || 'WHPI') + (0, crypto_1.randomBytes)(18).toString('hex').toUpperCase();
|
|
152
178
|
exports.generateMessageID = generateMessageID;
|
|
153
179
|
function bindWaitForEvent(ev, event) {
|
|
154
180
|
return async (check, timeoutMs) => {
|
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;
|
|
@@ -22,9 +22,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
25
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
29
|
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.extensionForMediaMessage = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.getHttpStream = exports.generateThumbnail = exports.getStream = exports.toBuffer = exports.toReadable = exports.getAudioWaveform = exports.getAudioDuration = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.getMediaKeys = exports.hkdfInfoKey = void 0;
|
|
27
30
|
const boom_1 = require("@hapi/boom");
|
|
31
|
+
const axios_1 = __importDefault(require("axios"));
|
|
28
32
|
const child_process_1 = require("child_process");
|
|
29
33
|
const Crypto = __importStar(require("crypto"));
|
|
30
34
|
const events_1 = require("events");
|
|
@@ -313,8 +317,7 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
313
317
|
}
|
|
314
318
|
exports.generateThumbnail = generateThumbnail;
|
|
315
319
|
const getHttpStream = async (url, options = {}) => {
|
|
316
|
-
const
|
|
317
|
-
const fetched = await axios.get(url.toString(), { ...options, responseType: 'stream' });
|
|
320
|
+
const fetched = await axios_1.default.get(url.toString(), { ...options, responseType: 'stream' });
|
|
318
321
|
return fetched.data;
|
|
319
322
|
};
|
|
320
323
|
exports.getHttpStream = getHttpStream;
|
|
@@ -525,27 +528,18 @@ exports.extensionForMediaMessage = extensionForMediaMessage;
|
|
|
525
528
|
const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
526
529
|
return async (stream, { mediaType, fileEncSha256B64, timeoutMs }) => {
|
|
527
530
|
var _a, _b;
|
|
528
|
-
const { default: axios } = await import('axios');
|
|
529
531
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
530
532
|
let uploadInfo = await refreshMediaConn(false);
|
|
531
533
|
let urls;
|
|
532
534
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
533
|
-
const chunks = [];
|
|
534
|
-
for await (const chunk of stream) {
|
|
535
|
-
chunks.push(chunk);
|
|
536
|
-
}
|
|
537
|
-
const reqBody = Buffer.concat(chunks);
|
|
538
535
|
fileEncSha256B64 = (0, exports.encodeBase64EncodedStringForUpload)(fileEncSha256B64);
|
|
539
|
-
for (const { hostname
|
|
536
|
+
for (const { hostname } of hosts) {
|
|
540
537
|
logger.debug(`uploading to "${hostname}"`);
|
|
541
538
|
const auth = encodeURIComponent(uploadInfo.auth); // the auth token
|
|
542
539
|
const url = `https://${hostname}${Defaults_1.MEDIA_PATH_MAP[mediaType]}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
543
540
|
let result;
|
|
544
541
|
try {
|
|
545
|
-
|
|
546
|
-
throw new boom_1.Boom(`Body too large for "${hostname}"`, { statusCode: 413 });
|
|
547
|
-
}
|
|
548
|
-
const body = await axios.post(url, reqBody, {
|
|
542
|
+
const body = await axios_1.default.post(url, stream, {
|
|
549
543
|
...options,
|
|
550
544
|
headers: {
|
|
551
545
|
...options.headers || {},
|
|
@@ -572,7 +566,7 @@ const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options },
|
|
|
572
566
|
}
|
|
573
567
|
}
|
|
574
568
|
catch (error) {
|
|
575
|
-
if (
|
|
569
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
576
570
|
result = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data;
|
|
577
571
|
}
|
|
578
572
|
const isLast = hostname === ((_b = hosts[uploadInfo.hosts.length - 1]) === null || _b === void 0 ? void 0 : _b.hostname);
|
package/lib/Utils/messages.js
CHANGED
|
@@ -30,7 +30,6 @@ const MessageTypeProto = {
|
|
|
30
30
|
'sticker': Types_1.WAProto.Message.StickerMessage,
|
|
31
31
|
'document': Types_1.WAProto.Message.DocumentMessage,
|
|
32
32
|
};
|
|
33
|
-
const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType;
|
|
34
33
|
/**
|
|
35
34
|
* Uses a regex to test whether the string contains a URL, and returns the URL if it does.
|
|
36
35
|
* @param text eg. hello https://google.com
|
|
@@ -238,7 +237,7 @@ const generateForwardMessageContent = (message, forceForward) => {
|
|
|
238
237
|
exports.generateForwardMessageContent = generateForwardMessageContent;
|
|
239
238
|
const generateWAMessageContent = async (message, options) => {
|
|
240
239
|
var _a;
|
|
241
|
-
var _b;
|
|
240
|
+
var _b, _c;
|
|
242
241
|
let m = {};
|
|
243
242
|
if ('text' in message) {
|
|
244
243
|
const extContent = { text: message.text };
|
|
@@ -308,6 +307,33 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
308
307
|
message.disappearingMessagesInChat;
|
|
309
308
|
m = (0, exports.prepareDisappearingMessageSettingContent)(exp);
|
|
310
309
|
}
|
|
310
|
+
else if ('groupInvite' in message) {
|
|
311
|
+
m.groupInviteMessage = {};
|
|
312
|
+
m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
|
|
313
|
+
m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
|
|
314
|
+
m.groupInviteMessage.caption = message.groupInvite.text;
|
|
315
|
+
m.groupInviteMessage.groupJid = message.groupInvite.jid;
|
|
316
|
+
m.groupInviteMessage.groupName = message.groupInvite.subject;
|
|
317
|
+
//TODO: use built-in interface and get disappearing mode info etc.
|
|
318
|
+
//TODO: cache / use store!?
|
|
319
|
+
if (options.getProfilePicUrl) {
|
|
320
|
+
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
321
|
+
if (pfpUrl) {
|
|
322
|
+
const resp = await axios_1.default.get(pfpUrl, { responseType: 'arraybuffer' });
|
|
323
|
+
if (resp.status === 200) {
|
|
324
|
+
m.groupInviteMessage.jpegThumbnail = resp.data;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
else if ('pin' in message) {
|
|
330
|
+
m.pinInChatMessage = {};
|
|
331
|
+
m.messageContextInfo = {};
|
|
332
|
+
m.pinInChatMessage.key = message.pin;
|
|
333
|
+
m.pinInChatMessage.type = message.type;
|
|
334
|
+
m.pinInChatMessage.senderTimestampMs = Date.now();
|
|
335
|
+
m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
|
|
336
|
+
}
|
|
311
337
|
else if ('buttonReply' in message) {
|
|
312
338
|
switch (message.type) {
|
|
313
339
|
case 'template':
|
|
@@ -326,6 +352,10 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
326
352
|
break;
|
|
327
353
|
}
|
|
328
354
|
}
|
|
355
|
+
else if ('ptv' in message && message.ptv) {
|
|
356
|
+
const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options);
|
|
357
|
+
m.ptvMessage = videoMessage;
|
|
358
|
+
}
|
|
329
359
|
else if ('product' in message) {
|
|
330
360
|
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options);
|
|
331
361
|
m.productMessage = Types_1.WAProto.Message.ProductMessage.fromObject({
|
|
@@ -341,6 +371,7 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
341
371
|
}
|
|
342
372
|
else if ('poll' in message) {
|
|
343
373
|
(_b = message.poll).selectableCount || (_b.selectableCount = 0);
|
|
374
|
+
(_c = message.poll).toAnnouncementGroup || (_c.toAnnouncementGroup = false);
|
|
344
375
|
if (!Array.isArray(message.poll.values)) {
|
|
345
376
|
throw new boom_1.Boom('Invalid poll values', { statusCode: 400 });
|
|
346
377
|
}
|
|
@@ -352,11 +383,25 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
352
383
|
// encKey
|
|
353
384
|
messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32),
|
|
354
385
|
};
|
|
355
|
-
|
|
386
|
+
const pollCreationMessage = {
|
|
356
387
|
name: message.poll.name,
|
|
357
388
|
selectableOptionsCount: message.poll.selectableCount,
|
|
358
389
|
options: message.poll.values.map(optionName => ({ optionName })),
|
|
359
390
|
};
|
|
391
|
+
if (message.poll.toAnnouncementGroup) {
|
|
392
|
+
// poll v2 is for community announcement groups (single select and multiple)
|
|
393
|
+
m.pollCreationMessageV2 = pollCreationMessage;
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
if (message.poll.selectableCount > 0) {
|
|
397
|
+
//poll v3 is for single select polls
|
|
398
|
+
m.pollCreationMessageV3 = pollCreationMessage;
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
// poll v3 for multiple choice polls
|
|
402
|
+
m.pollCreationMessage = pollCreationMessage;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
360
405
|
}
|
|
361
406
|
else if ('sharePhoneNumber' in message) {
|
|
362
407
|
m.protocolMessage = {
|
|
@@ -369,61 +414,6 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
369
414
|
else {
|
|
370
415
|
m = await (0, exports.prepareWAMessageMedia)(message, options);
|
|
371
416
|
}
|
|
372
|
-
if ('buttons' in message && !!message.buttons) {
|
|
373
|
-
const buttonsMessage = {
|
|
374
|
-
buttons: message.buttons.map(b => ({ ...b, type: WAProto_1.proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
|
|
375
|
-
};
|
|
376
|
-
if ('text' in message) {
|
|
377
|
-
buttonsMessage.contentText = message.text;
|
|
378
|
-
buttonsMessage.headerType = ButtonType.EMPTY;
|
|
379
|
-
}
|
|
380
|
-
else {
|
|
381
|
-
if ('caption' in message) {
|
|
382
|
-
buttonsMessage.contentText = message.caption;
|
|
383
|
-
}
|
|
384
|
-
const type = Object.keys(m)[0].replace('Message', '').toUpperCase();
|
|
385
|
-
buttonsMessage.headerType = ButtonType[type];
|
|
386
|
-
Object.assign(buttonsMessage, m);
|
|
387
|
-
}
|
|
388
|
-
if ('footer' in message && !!message.footer) {
|
|
389
|
-
buttonsMessage.footerText = message.footer;
|
|
390
|
-
}
|
|
391
|
-
m = { buttonsMessage };
|
|
392
|
-
}
|
|
393
|
-
else if ('templateButtons' in message && !!message.templateButtons) {
|
|
394
|
-
const msg = {
|
|
395
|
-
hydratedButtons: message.templateButtons
|
|
396
|
-
};
|
|
397
|
-
if ('text' in message) {
|
|
398
|
-
msg.hydratedContentText = message.text;
|
|
399
|
-
}
|
|
400
|
-
else {
|
|
401
|
-
if ('caption' in message) {
|
|
402
|
-
msg.hydratedContentText = message.caption;
|
|
403
|
-
}
|
|
404
|
-
Object.assign(msg, m);
|
|
405
|
-
}
|
|
406
|
-
if ('footer' in message && !!message.footer) {
|
|
407
|
-
msg.hydratedFooterText = message.footer;
|
|
408
|
-
}
|
|
409
|
-
m = {
|
|
410
|
-
templateMessage: {
|
|
411
|
-
fourRowTemplate: msg,
|
|
412
|
-
hydratedTemplate: msg
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
if ('sections' in message && !!message.sections) {
|
|
417
|
-
const listMessage = {
|
|
418
|
-
sections: message.sections,
|
|
419
|
-
buttonText: message.buttonText,
|
|
420
|
-
title: message.title,
|
|
421
|
-
footerText: message.footer,
|
|
422
|
-
description: message.text,
|
|
423
|
-
listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
|
|
424
|
-
};
|
|
425
|
-
m = { listMessage };
|
|
426
|
-
}
|
|
427
417
|
if ('viewOnce' in message && !!message.viewOnce) {
|
|
428
418
|
m = { viewOnceMessage: { message: m } };
|
|
429
419
|
}
|
|
@@ -17,5 +17,5 @@ export declare const makeNoiseHandler: ({ keyPair: { private: privateKey, public
|
|
|
17
17
|
finishInit: () => void;
|
|
18
18
|
processHandshake: ({ serverHello }: proto.HandshakeMessage, noiseKey: KeyPair) => Buffer;
|
|
19
19
|
encodeFrame: (data: Buffer | Uint8Array) => Buffer;
|
|
20
|
-
decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => void
|
|
20
|
+
decodeFrame: (newData: Buffer | Uint8Array, onFrame: (buff: Uint8Array | BinaryNode) => void) => Promise<void>;
|
|
21
21
|
};
|
|
@@ -125,7 +125,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
125
125
|
frame.set(data, introSize + 3);
|
|
126
126
|
return frame;
|
|
127
127
|
},
|
|
128
|
-
decodeFrame: (newData, onFrame) => {
|
|
128
|
+
decodeFrame: async (newData, onFrame) => {
|
|
129
129
|
var _a;
|
|
130
130
|
// the binary protocol uses its own framing mechanism
|
|
131
131
|
// on top of the WS frames
|
|
@@ -143,7 +143,7 @@ const makeNoiseHandler = ({ keyPair: { private: privateKey, public: publicKey },
|
|
|
143
143
|
inBytes = inBytes.slice(size + 3);
|
|
144
144
|
if (isFinished) {
|
|
145
145
|
const result = decrypt(frame);
|
|
146
|
-
frame = (0, WABinary_1.decodeBinaryNode)(result);
|
|
146
|
+
frame = await (0, WABinary_1.decodeBinaryNode)(result);
|
|
147
147
|
}
|
|
148
148
|
logger.trace({ msg: (_a = frame === null || frame === void 0 ? void 0 : frame.attrs) === null || _a === void 0 ? void 0 : _a.id }, 'recv frame');
|
|
149
149
|
onFrame(frame);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AxiosRequestConfig } from 'axios';
|
|
2
2
|
import type { Logger } from 'pino';
|
|
3
3
|
import { proto } from '../../WAProto';
|
|
4
|
-
import { AuthenticationCreds, BaileysEventEmitter, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
|
|
4
|
+
import { AuthenticationCreds, BaileysEventEmitter, CacheStore, SignalKeyStoreWithTransaction, SocketConfig } from '../Types';
|
|
5
5
|
type ProcessMessageContext = {
|
|
6
6
|
shouldProcessHistoryMsg: boolean;
|
|
7
|
+
placeholderResendCache?: CacheStore;
|
|
7
8
|
creds: AuthenticationCreds;
|
|
8
9
|
keyStore: SignalKeyStoreWithTransaction;
|
|
9
10
|
ev: BaileysEventEmitter;
|
|
@@ -37,5 +38,5 @@ type PollContext = {
|
|
|
37
38
|
* @returns list of SHA256 options
|
|
38
39
|
*/
|
|
39
40
|
export declare function decryptPollVote({ encPayload, encIv }: proto.Message.IPollEncValue, { pollCreatorJid, pollMsgId, pollEncKey, voterJid, }: PollContext): proto.Message.PollVoteMessage;
|
|
40
|
-
declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
|
|
41
|
+
declare const processMessage: (message: proto.IWebMessageInfo, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }: ProcessMessageContext) => Promise<void>;
|
|
41
42
|
export default processMessage;
|
|
@@ -102,8 +102,8 @@ function decryptPollVote({ encPayload, encIv }, { pollCreatorJid, pollMsgId, pol
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
exports.decryptPollVote = decryptPollVote;
|
|
105
|
-
const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, keyStore, logger, options, getMessage }) => {
|
|
106
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
105
|
+
const processMessage = async (message, { shouldProcessHistoryMsg, placeholderResendCache, ev, creds, keyStore, logger, options, getMessage }) => {
|
|
106
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
107
107
|
const meId = creds.me.id;
|
|
108
108
|
const { accountSettings } = creds;
|
|
109
109
|
const chat = { id: (0, WABinary_1.jidNormalizedUser)((0, exports.getChatId)(message.key)) };
|
|
@@ -137,14 +137,21 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
137
137
|
isLatest,
|
|
138
138
|
}, 'got history notification');
|
|
139
139
|
if (process) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
140
|
+
if (histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND) {
|
|
141
|
+
ev.emit('creds.update', {
|
|
142
|
+
processedHistoryMessages: [
|
|
143
|
+
...(creds.processedHistoryMessages || []),
|
|
144
|
+
{ key: message.key, messageTimestamp: message.messageTimestamp }
|
|
145
|
+
]
|
|
146
|
+
});
|
|
147
|
+
}
|
|
146
148
|
const data = await (0, history_1.downloadAndProcessHistorySyncNotification)(histNotification, options);
|
|
147
|
-
ev.emit('messaging-history.set', {
|
|
149
|
+
ev.emit('messaging-history.set', {
|
|
150
|
+
...data,
|
|
151
|
+
isLatest: histNotification.syncType !== WAProto_1.proto.HistorySync.HistorySyncType.ON_DEMAND
|
|
152
|
+
? isLatest
|
|
153
|
+
: undefined
|
|
154
|
+
});
|
|
148
155
|
}
|
|
149
156
|
break;
|
|
150
157
|
case WAProto_1.proto.Message.ProtocolMessage.Type.APP_STATE_SYNC_KEY_SHARE:
|
|
@@ -187,14 +194,21 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
187
194
|
case WAProto_1.proto.Message.ProtocolMessage.Type.PEER_DATA_OPERATION_REQUEST_RESPONSE_MESSAGE:
|
|
188
195
|
const response = protocolMsg.peerDataOperationRequestResponseMessage;
|
|
189
196
|
if (response) {
|
|
197
|
+
placeholderResendCache === null || placeholderResendCache === void 0 ? void 0 : placeholderResendCache.del(response.stanzaId);
|
|
198
|
+
// TODO: IMPLEMENT HISTORY SYNC ETC (sticker uploads etc.).
|
|
190
199
|
const { peerDataOperationResult } = response;
|
|
191
200
|
for (const result of peerDataOperationResult) {
|
|
192
201
|
const { placeholderMessageResendResponse: retryResponse } = result;
|
|
193
202
|
if (retryResponse) {
|
|
194
203
|
const webMessageInfo = WAProto_1.proto.WebMessageInfo.decode(retryResponse.webMessageInfoBytes);
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
204
|
+
// wait till another upsert event is available, don't want it to be part of the PDO response message
|
|
205
|
+
setTimeout(() => {
|
|
206
|
+
ev.emit('messages.upsert', {
|
|
207
|
+
messages: [webMessageInfo],
|
|
208
|
+
type: 'notify',
|
|
209
|
+
requestId: response.stanzaId
|
|
210
|
+
});
|
|
211
|
+
}, 500);
|
|
198
212
|
}
|
|
199
213
|
}
|
|
200
214
|
}
|
|
@@ -208,11 +222,11 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
208
222
|
};
|
|
209
223
|
ev.emit('messages.reaction', [{
|
|
210
224
|
reaction,
|
|
211
|
-
key: content.reactionMessage.key,
|
|
225
|
+
key: (_d = content.reactionMessage) === null || _d === void 0 ? void 0 : _d.key,
|
|
212
226
|
}]);
|
|
213
227
|
}
|
|
214
228
|
else if (message.messageStubType) {
|
|
215
|
-
const jid = message.key.remoteJid;
|
|
229
|
+
const jid = (_e = message.key) === null || _e === void 0 ? void 0 : _e.remoteJid;
|
|
216
230
|
//let actor = whatsappID (message.participant)
|
|
217
231
|
let participants;
|
|
218
232
|
const emitParticipantsUpdate = (action) => (ev.emit('group-participants.update', { id: jid, author: message.participant, participants, action }));
|
|
@@ -225,6 +239,10 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
225
239
|
};
|
|
226
240
|
const participantsIncludesMe = () => participants.find(jid => (0, WABinary_1.areJidsSameUser)(meId, jid));
|
|
227
241
|
switch (message.messageStubType) {
|
|
242
|
+
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_CHANGE_NUMBER:
|
|
243
|
+
participants = message.messageStubParameters || [];
|
|
244
|
+
emitParticipantsUpdate('modify');
|
|
245
|
+
break;
|
|
228
246
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_LEAVE:
|
|
229
247
|
case Types_1.WAMessageStubType.GROUP_PARTICIPANT_REMOVE:
|
|
230
248
|
participants = message.messageStubParameters || [];
|
|
@@ -252,34 +270,39 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
252
270
|
emitParticipantsUpdate('promote');
|
|
253
271
|
break;
|
|
254
272
|
case Types_1.WAMessageStubType.GROUP_CHANGE_ANNOUNCE:
|
|
255
|
-
const announceValue = (
|
|
273
|
+
const announceValue = (_f = message.messageStubParameters) === null || _f === void 0 ? void 0 : _f[0];
|
|
256
274
|
emitGroupUpdate({ announce: announceValue === 'true' || announceValue === 'on' });
|
|
257
275
|
break;
|
|
258
276
|
case Types_1.WAMessageStubType.GROUP_CHANGE_RESTRICT:
|
|
259
|
-
const restrictValue = (
|
|
277
|
+
const restrictValue = (_g = message.messageStubParameters) === null || _g === void 0 ? void 0 : _g[0];
|
|
260
278
|
emitGroupUpdate({ restrict: restrictValue === 'true' || restrictValue === 'on' });
|
|
261
279
|
break;
|
|
262
280
|
case Types_1.WAMessageStubType.GROUP_CHANGE_SUBJECT:
|
|
263
|
-
const name = (
|
|
281
|
+
const name = (_h = message.messageStubParameters) === null || _h === void 0 ? void 0 : _h[0];
|
|
264
282
|
chat.name = name;
|
|
265
283
|
emitGroupUpdate({ subject: name });
|
|
266
284
|
break;
|
|
285
|
+
case Types_1.WAMessageStubType.GROUP_CHANGE_DESCRIPTION:
|
|
286
|
+
const description = (_j = message.messageStubParameters) === null || _j === void 0 ? void 0 : _j[0];
|
|
287
|
+
chat.description = description;
|
|
288
|
+
emitGroupUpdate({ desc: description });
|
|
289
|
+
break;
|
|
267
290
|
case Types_1.WAMessageStubType.GROUP_CHANGE_INVITE_LINK:
|
|
268
|
-
const code = (
|
|
291
|
+
const code = (_k = message.messageStubParameters) === null || _k === void 0 ? void 0 : _k[0];
|
|
269
292
|
emitGroupUpdate({ inviteCode: code });
|
|
270
293
|
break;
|
|
271
294
|
case Types_1.WAMessageStubType.GROUP_MEMBER_ADD_MODE:
|
|
272
|
-
const memberAddValue = (
|
|
295
|
+
const memberAddValue = (_l = message.messageStubParameters) === null || _l === void 0 ? void 0 : _l[0];
|
|
273
296
|
emitGroupUpdate({ memberAddMode: memberAddValue === 'all_member_add' });
|
|
274
297
|
break;
|
|
275
298
|
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_MODE:
|
|
276
|
-
const approvalMode = (
|
|
299
|
+
const approvalMode = (_m = message.messageStubParameters) === null || _m === void 0 ? void 0 : _m[0];
|
|
277
300
|
emitGroupUpdate({ joinApprovalMode: approvalMode === 'on' });
|
|
278
301
|
break;
|
|
279
302
|
case Types_1.WAMessageStubType.GROUP_MEMBERSHIP_JOIN_APPROVAL_REQUEST_NON_ADMIN_ADD:
|
|
280
|
-
const participant = (
|
|
281
|
-
const action = (
|
|
282
|
-
const method = (
|
|
303
|
+
const participant = (_o = message.messageStubParameters) === null || _o === void 0 ? void 0 : _o[0];
|
|
304
|
+
const action = (_p = message.messageStubParameters) === null || _p === void 0 ? void 0 : _p[1];
|
|
305
|
+
const method = (_q = message.messageStubParameters) === null || _q === void 0 ? void 0 : _q[2];
|
|
283
306
|
emitGroupRequestJoin(participant, action, method);
|
|
284
307
|
break;
|
|
285
308
|
}
|
|
@@ -292,7 +315,7 @@ const processMessage = async (message, { shouldProcessHistoryMsg, ev, creds, key
|
|
|
292
315
|
const meIdNormalised = (0, WABinary_1.jidNormalizedUser)(meId);
|
|
293
316
|
const pollCreatorJid = (0, generics_1.getKeyAuthor)(creationMsgKey, meIdNormalised);
|
|
294
317
|
const voterJid = (0, generics_1.getKeyAuthor)(message.key, meIdNormalised);
|
|
295
|
-
const pollEncKey = (
|
|
318
|
+
const pollEncKey = (_r = pollMsg.messageContextInfo) === null || _r === void 0 ? void 0 : _r.messageSecret;
|
|
296
319
|
try {
|
|
297
320
|
const voteMsg = decryptPollVote(content.pollUpdateMessage.vote, {
|
|
298
321
|
pollEncKey,
|