@fer2809fl/baileys 7.0.0 → 7.0.2
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 +259 -595
- package/WAProto/WAProto.proto +916 -360
- package/WAProto/fix-imports.js +18 -22
- package/WAProto/index.d.ts +15471 -8638
- package/WAProto/index.js +80576 -45941
- package/lib/Defaults/index.d.ts +14 -18
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +110 -115
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/Group/group_cipher.js.map +1 -1
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -1
- package/lib/Signal/Group/keyhelper.js.map +1 -1
- package/lib/Signal/Group/sender-chain-key.js.map +1 -1
- package/lib/Signal/Group/sender-key-message.js.map +1 -1
- package/lib/Signal/Group/sender-message-key.js.map +1 -1
- package/lib/Signal/libsignal.d.ts.map +1 -1
- package/lib/Signal/libsignal.js +17 -45
- package/lib/Signal/libsignal.js.map +1 -1
- package/lib/Signal/lid-mapping.d.ts +0 -4
- package/lib/Signal/lid-mapping.d.ts.map +1 -1
- package/lib/Signal/lid-mapping.js +0 -6
- package/lib/Signal/lid-mapping.js.map +1 -1
- package/lib/Socket/business.d.ts +532 -280
- package/lib/Socket/business.d.ts.map +1 -1
- package/lib/Socket/business.js +401 -358
- package/lib/Socket/chats.d.ts +2 -22
- package/lib/Socket/chats.d.ts.map +1 -1
- package/lib/Socket/chats.js +43 -314
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +641 -336
- package/lib/Socket/communities.d.ts.map +1 -1
- package/lib/Socket/communities.js +3 -6
- package/lib/Socket/communities.js.map +1 -1
- package/lib/Socket/dugong.d.ts +130 -0
- package/lib/Socket/dugong.d.ts.map +1 -0
- package/lib/Socket/dugong.js +772 -0
- package/lib/Socket/dugong.js.map +1 -0
- package/lib/Socket/groups.d.ts +2 -23
- package/lib/Socket/groups.d.ts.map +1 -1
- package/lib/Socket/groups.js +8 -171
- package/lib/Socket/groups.js.map +1 -1
- package/lib/Socket/index.d.ts +631 -322
- package/lib/Socket/index.d.ts.map +1 -1
- package/lib/Socket/index.js +12 -9
- package/lib/Socket/index.js.map +1 -1
- package/lib/Socket/messages-recv.d.ts +52 -84
- package/lib/Socket/messages-recv.d.ts.map +1 -1
- package/lib/Socket/messages-recv.js +185 -686
- package/lib/Socket/messages-recv.js.map +1 -1
- package/lib/Socket/messages-send.d.ts +643 -262
- package/lib/Socket/messages-send.d.ts.map +1 -1
- package/lib/Socket/messages-send.js +1559 -1359
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/mex.d.ts +0 -1
- package/lib/Socket/mex.d.ts.map +1 -1
- package/lib/Socket/mex.js +8 -22
- package/lib/Socket/mex.js.map +1 -1
- package/lib/Socket/native-buttons.js +231 -0
- package/lib/Socket/newsletter.d.ts +27 -42
- package/lib/Socket/newsletter.d.ts.map +1 -1
- package/lib/Socket/newsletter.js +439 -402
- package/lib/Socket/newsletter.js.map +1 -1
- package/lib/Socket/socket.d.ts +2 -6
- package/lib/Socket/socket.d.ts.map +1 -1
- package/lib/Socket/socket.js +26 -62
- package/lib/Socket/socket.js.map +1 -1
- package/lib/Types/Auth.d.ts +0 -1
- package/lib/Types/Auth.d.ts.map +1 -1
- package/lib/Types/Bussines.d.ts +34 -22
- package/lib/Types/Call.d.ts +1 -1
- package/lib/Types/Call.d.ts.map +1 -1
- package/lib/Types/Chat.d.ts +0 -1
- package/lib/Types/Chat.d.ts.map +1 -1
- package/lib/Types/Contact.d.ts +0 -2
- package/lib/Types/Contact.d.ts.map +1 -1
- package/lib/Types/Events.d.ts +1 -20
- package/lib/Types/Events.d.ts.map +1 -1
- package/lib/Types/GroupMetadata.d.ts +1 -4
- package/lib/Types/GroupMetadata.d.ts.map +1 -1
- package/lib/Types/Message.d.ts +348 -354
- package/lib/Types/Message.d.ts.map +1 -1
- package/lib/Types/Message.js +0 -4
- package/lib/Types/Message.js.map +1 -1
- package/lib/Types/{Mex.d.ts → Newsletter.d.ts} +7 -26
- package/lib/Types/Newsletter.d.ts.map +1 -0
- package/lib/Types/{Mex.js → Newsletter.js} +3 -11
- package/lib/Types/Newsletter.js.map +1 -0
- package/lib/Types/Signal.d.ts +1 -12
- package/lib/Types/Signal.d.ts.map +1 -1
- package/lib/Types/Socket.d.ts +148 -135
- package/lib/Types/Socket.d.ts.map +1 -1
- package/lib/Types/Socket.js.map +1 -1
- package/lib/Types/State.d.ts +0 -65
- package/lib/Types/State.d.ts.map +1 -1
- package/lib/Types/State.js +0 -43
- package/lib/Types/State.js.map +1 -1
- package/lib/Types/index.d.ts +52 -52
- package/lib/Types/index.d.ts.map +1 -1
- package/lib/Types/index.js +30 -23
- package/lib/Types/index.js.map +1 -1
- package/lib/Utils/auth-utils.d.ts +0 -5
- package/lib/Utils/auth-utils.d.ts.map +1 -1
- package/lib/Utils/auth-utils.js +0 -12
- package/lib/Utils/auth-utils.js.map +1 -1
- package/lib/Utils/browser-utils.d.ts.map +1 -1
- package/lib/Utils/browser-utils.js +0 -1
- package/lib/Utils/browser-utils.js.map +1 -1
- package/lib/Utils/chat-utils.d.ts +4 -34
- package/lib/Utils/chat-utils.d.ts.map +1 -1
- package/lib/Utils/chat-utils.js +20 -80
- package/lib/Utils/chat-utils.js.map +1 -1
- package/lib/Utils/crypto.d.ts +12 -12
- package/lib/Utils/crypto.d.ts.map +1 -1
- package/lib/Utils/crypto.js.map +1 -1
- package/lib/Utils/decode-wa-message.d.ts +0 -18
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js +0 -34
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.d.ts +0 -2
- package/lib/Utils/event-buffer.d.ts.map +1 -1
- package/lib/Utils/event-buffer.js +1 -49
- package/lib/Utils/event-buffer.js.map +1 -1
- package/lib/Utils/generics.d.ts +2 -3
- package/lib/Utils/generics.d.ts.map +1 -1
- package/lib/Utils/generics.js +1 -10
- package/lib/Utils/generics.js.map +1 -1
- package/lib/Utils/history.d.ts +0 -2
- package/lib/Utils/history.d.ts.map +1 -1
- package/lib/Utils/history.js +9 -12
- package/lib/Utils/history.js.map +1 -1
- package/lib/Utils/identity-change-handler.d.ts +0 -7
- package/lib/Utils/identity-change-handler.d.ts.map +1 -1
- package/lib/Utils/identity-change-handler.js +0 -1
- package/lib/Utils/identity-change-handler.js.map +1 -1
- package/lib/Utils/index.d.ts +23 -30
- package/lib/Utils/index.d.ts.map +1 -1
- package/lib/Utils/index.js +2 -9
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/link-preview.js +2 -2
- package/lib/Utils/link-preview.js.map +1 -1
- package/lib/Utils/message-retry-manager.d.ts +0 -5
- package/lib/Utils/message-retry-manager.d.ts.map +1 -1
- package/lib/Utils/message-retry-manager.js +0 -40
- package/lib/Utils/message-retry-manager.js.map +1 -1
- package/lib/Utils/messages-media.d.ts +13 -45
- package/lib/Utils/messages-media.d.ts.map +1 -1
- package/lib/Utils/messages-media.js +98 -293
- package/lib/Utils/messages-media.js.map +1 -1
- package/lib/Utils/messages.d.ts +3 -16
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +1123 -1219
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/noise-handler.d.ts +1 -1
- package/lib/Utils/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +1 -103
- package/lib/Utils/process-message.js.map +1 -1
- package/lib/Utils/rich-messages.d.ts +277 -0
- package/lib/Utils/rich-messages.d.ts.map +1 -0
- package/lib/Utils/rich-messages.js +1144 -0
- package/lib/Utils/rich-messages.js.map +1 -0
- package/lib/Utils/signal.d.ts +0 -13
- package/lib/Utils/signal.d.ts.map +1 -1
- package/lib/Utils/signal.js +0 -42
- package/lib/Utils/signal.js.map +1 -1
- package/lib/Utils/sticker-pack.d.ts +10 -0
- package/lib/Utils/sticker-pack.js +111 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -1
- package/lib/Utils/sync-action-utils.js +0 -1
- package/lib/Utils/sync-action-utils.js.map +1 -1
- package/lib/Utils/tc-token-utils.d.ts +1 -26
- package/lib/Utils/tc-token-utils.d.ts.map +1 -1
- package/lib/Utils/tc-token-utils.js +5 -151
- package/lib/Utils/tc-token-utils.js.map +1 -1
- package/lib/Utils/validate-connection.d.ts +0 -1
- package/lib/Utils/validate-connection.d.ts.map +1 -1
- package/lib/Utils/validate-connection.js +3 -13
- package/lib/Utils/validate-connection.js.map +1 -1
- package/lib/WABinary/decode.d.ts +1 -1
- package/lib/WABinary/decode.d.ts.map +1 -1
- package/lib/WABinary/generic-utils.d.ts +3 -1
- package/lib/WABinary/generic-utils.d.ts.map +1 -1
- package/lib/WABinary/generic-utils.js +78 -0
- package/lib/WABinary/generic-utils.js.map +1 -1
- package/lib/WABinary/jid-utils.d.ts +0 -11
- package/lib/WABinary/jid-utils.d.ts.map +1 -1
- package/lib/WABinary/jid-utils.js +0 -33
- package/lib/WABinary/jid-utils.js.map +1 -1
- package/lib/WAM/encode.d.ts +1 -1
- package/lib/WAM/encode.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +3 -26
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -1
- package/lib/WAUSync/Protocols/index.d.ts +0 -1
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -1
- package/lib/WAUSync/Protocols/index.js +0 -1
- package/lib/WAUSync/Protocols/index.js.map +1 -1
- package/lib/WAUSync/USyncQuery.d.ts +0 -1
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -1
- package/lib/WAUSync/USyncQuery.js +2 -6
- package/lib/WAUSync/USyncQuery.js.map +1 -1
- package/lib/WAUSync/USyncUser.d.ts +0 -4
- package/lib/WAUSync/USyncUser.d.ts.map +1 -1
- package/lib/WAUSync/USyncUser.js +0 -8
- package/lib/WAUSync/USyncUser.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -4
- package/lib/index.js.map +1 -1
- package/package.json +30 -34
- package/LICENSE +0 -21
- package/engine-requirements.js +0 -10
- package/lib/Socket/smgss.d.ts +0 -119
- package/lib/Socket/smgss.d.ts.map +0 -1
- package/lib/Socket/smgss.js +0 -453
- package/lib/Socket/smgss.js.map +0 -1
- package/lib/Store/index.d.ts +0 -4
- package/lib/Store/index.d.ts.map +0 -1
- package/lib/Store/index.js +0 -4
- package/lib/Store/index.js.map +0 -1
- package/lib/Store/make-in-memory-store.d.ts +0 -132
- package/lib/Store/make-in-memory-store.d.ts.map +0 -1
- package/lib/Store/make-in-memory-store.js +0 -450
- package/lib/Store/make-in-memory-store.js.map +0 -1
- package/lib/Store/make-ordered-dictionary.d.ts +0 -14
- package/lib/Store/make-ordered-dictionary.d.ts.map +0 -1
- package/lib/Store/make-ordered-dictionary.js +0 -80
- package/lib/Store/make-ordered-dictionary.js.map +0 -1
- package/lib/Store/object-repository.d.ts +0 -13
- package/lib/Store/object-repository.d.ts.map +0 -1
- package/lib/Store/object-repository.js +0 -24
- package/lib/Store/object-repository.js.map +0 -1
- package/lib/Types/Mex.d.ts.map +0 -1
- package/lib/Types/Mex.js.map +0 -1
- package/lib/Utils/button-handler.d.ts +0 -28
- package/lib/Utils/button-handler.d.ts.map +0 -1
- package/lib/Utils/button-handler.js +0 -140
- package/lib/Utils/button-handler.js.map +0 -1
- package/lib/Utils/companion-reg-client-utils.d.ts +0 -17
- package/lib/Utils/companion-reg-client-utils.d.ts.map +0 -1
- package/lib/Utils/companion-reg-client-utils.js +0 -35
- package/lib/Utils/companion-reg-client-utils.js.map +0 -1
- package/lib/Utils/interactive.d.ts +0 -60
- package/lib/Utils/interactive.d.ts.map +0 -1
- package/lib/Utils/interactive.js +0 -224
- package/lib/Utils/interactive.js.map +0 -1
- package/lib/Utils/message-composer.d.ts +0 -93
- package/lib/Utils/message-composer.d.ts.map +0 -1
- package/lib/Utils/message-composer.js +0 -311
- package/lib/Utils/message-composer.js.map +0 -1
- package/lib/Utils/messages-newsletter.d.ts +0 -74
- package/lib/Utils/messages-newsletter.d.ts.map +0 -1
- package/lib/Utils/messages-newsletter.js +0 -128
- package/lib/Utils/messages-newsletter.js.map +0 -1
- package/lib/Utils/shortcake-crypto.d.ts +0 -36
- package/lib/Utils/shortcake-crypto.d.ts.map +0 -1
- package/lib/Utils/shortcake-crypto.js +0 -71
- package/lib/Utils/shortcake-crypto.js.map +0 -1
- package/lib/Utils/shortcake.d.ts +0 -36
- package/lib/Utils/shortcake.d.ts.map +0 -1
- package/lib/Utils/shortcake.js +0 -162
- package/lib/Utils/shortcake.js.map +0 -1
- package/lib/Utils/use-single-file-auth-state.d.ts +0 -6
- package/lib/Utils/use-single-file-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-single-file-auth-state.js +0 -111
- package/lib/Utils/use-single-file-auth-state.js.map +0 -1
- package/lib/Utils/use-sqlite-auth-state.d.ts +0 -14
- package/lib/Utils/use-sqlite-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-sqlite-auth-state.js +0 -107
- package/lib/Utils/use-sqlite-auth-state.js.map +0 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +0 -1
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -25
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Boom } from '@hapi/boom';
|
|
2
|
-
import {
|
|
2
|
+
import { exec } from 'child_process';
|
|
3
3
|
import * as Crypto from 'crypto';
|
|
4
4
|
import { once } from 'events';
|
|
5
5
|
import { createReadStream, createWriteStream, promises as fs, WriteStream } from 'fs';
|
|
@@ -13,31 +13,16 @@ import { getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from
|
|
|
13
13
|
import { aesDecryptGCM, aesEncryptGCM, hkdf } from './crypto.js';
|
|
14
14
|
import { generateMessageIDV2 } from './generics.js';
|
|
15
15
|
const getTmpFilesDirectory = () => tmpdir();
|
|
16
|
-
|
|
17
|
-
export const getImageProcessingLibrary = async () => {
|
|
18
|
-
if (imageProcessingLibrary) {
|
|
19
|
-
return imageProcessingLibrary;
|
|
20
|
-
}
|
|
16
|
+
const getImageProcessingLibrary = async () => {
|
|
21
17
|
//@ts-ignore
|
|
22
|
-
const [jimp, sharp
|
|
23
|
-
import('jimp').catch(() => { }),
|
|
24
|
-
import('sharp').catch(() => { }),
|
|
25
|
-
//@ts-ignore
|
|
26
|
-
import('@napi-rs/image').catch(() => { })
|
|
27
|
-
]);
|
|
18
|
+
const [jimp, sharp] = await Promise.all([import('jimp').catch(() => { }), import('sharp').catch(() => { })]);
|
|
28
19
|
if (sharp) {
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
else if (napi) {
|
|
32
|
-
imageProcessingLibrary = { napi };
|
|
33
|
-
}
|
|
34
|
-
else if (jimp) {
|
|
35
|
-
imageProcessingLibrary = { jimp };
|
|
20
|
+
return { sharp };
|
|
36
21
|
}
|
|
37
|
-
|
|
38
|
-
|
|
22
|
+
if (jimp) {
|
|
23
|
+
return { jimp };
|
|
39
24
|
}
|
|
40
|
-
|
|
25
|
+
throw new Boom('No image processing library available');
|
|
41
26
|
};
|
|
42
27
|
export const hkdfInfoKey = (type) => {
|
|
43
28
|
const hkdfInfo = MEDIA_HKDF_KEY_MAPPING[type];
|
|
@@ -99,32 +84,13 @@ export async function getMediaKeys(buffer, mediaType) {
|
|
|
99
84
|
}
|
|
100
85
|
/** Extracts video thumb using FFMPEG */
|
|
101
86
|
const extractVideoThumb = async (path, destPath, time, size) => new Promise((resolve, reject) => {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
path,
|
|
107
|
-
'-y',
|
|
108
|
-
'-vf',
|
|
109
|
-
`scale=${size.width}:-1`,
|
|
110
|
-
'-vframes',
|
|
111
|
-
'1',
|
|
112
|
-
'-f',
|
|
113
|
-
'image2',
|
|
114
|
-
destPath
|
|
115
|
-
];
|
|
116
|
-
const child = spawn('ffmpeg', args);
|
|
117
|
-
let stderr = '';
|
|
118
|
-
child.stderr?.on('data', chunk => {
|
|
119
|
-
stderr += chunk;
|
|
120
|
-
});
|
|
121
|
-
child.on('error', reject);
|
|
122
|
-
child.on('close', code => {
|
|
123
|
-
if (code === 0) {
|
|
124
|
-
resolve();
|
|
87
|
+
const cmd = `ffmpeg -ss ${time} -i ${path} -y -vf scale=${size.width}:-1 -vframes 1 -f image2 ${destPath}`;
|
|
88
|
+
exec(cmd, err => {
|
|
89
|
+
if (err) {
|
|
90
|
+
reject(err);
|
|
125
91
|
}
|
|
126
92
|
else {
|
|
127
|
-
|
|
93
|
+
resolve();
|
|
128
94
|
}
|
|
129
95
|
});
|
|
130
96
|
});
|
|
@@ -161,28 +127,14 @@ export const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
|
161
127
|
original: dimensions
|
|
162
128
|
};
|
|
163
129
|
}
|
|
164
|
-
else if ('napi' in lib && typeof lib.napi?.Transformer === 'function') {
|
|
165
|
-
const input = typeof bufferOrFilePath === 'string' ? await fs.readFile(bufferOrFilePath) : bufferOrFilePath;
|
|
166
|
-
const img = new lib.napi.Transformer(input);
|
|
167
|
-
const meta = await img.metadata();
|
|
168
|
-
const buffer = await img.resize(width).jpeg(50);
|
|
169
|
-
return {
|
|
170
|
-
buffer,
|
|
171
|
-
original: {
|
|
172
|
-
width: meta.width,
|
|
173
|
-
height: meta.height
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
130
|
else {
|
|
178
131
|
throw new Boom('No image processing library available');
|
|
179
132
|
}
|
|
180
133
|
};
|
|
181
134
|
export const encodeBase64EncodedStringForUpload = (b64) => encodeURIComponent(b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, ''));
|
|
182
|
-
export const generateProfilePicture = async (mediaUpload, dimensions
|
|
135
|
+
export const generateProfilePicture = async (mediaUpload, dimensions) => {
|
|
183
136
|
let buffer;
|
|
184
|
-
const {
|
|
185
|
-
const { width: w = full ? 720 : 640, height: h = full ? 720 : 640 } = dimensions || {};
|
|
137
|
+
const { width: w = 640, height: h = 640 } = dimensions || {};
|
|
186
138
|
if (Buffer.isBuffer(mediaUpload)) {
|
|
187
139
|
buffer = mediaUpload;
|
|
188
140
|
}
|
|
@@ -197,38 +149,17 @@ export const generateProfilePicture = async (mediaUpload, dimensions, opts) => {
|
|
|
197
149
|
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
198
150
|
img = lib.sharp
|
|
199
151
|
.default(buffer)
|
|
200
|
-
.resize(w, h
|
|
152
|
+
.resize(w, h)
|
|
201
153
|
.jpeg({
|
|
202
|
-
quality:
|
|
154
|
+
quality: 50
|
|
203
155
|
})
|
|
204
156
|
.toBuffer();
|
|
205
157
|
}
|
|
206
158
|
else if ('jimp' in lib && typeof lib.jimp?.Jimp === 'function') {
|
|
207
159
|
const jimp = await lib.jimp.Jimp.read(buffer);
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const targetW = Math.max(1, Math.round(jimp.width * scale));
|
|
212
|
-
const targetH = Math.max(1, Math.round(jimp.height * scale));
|
|
213
|
-
resized = jimp.resize({ w: targetW, h: targetH, mode: lib.jimp.ResizeStrategy.BILINEAR });
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
const min = Math.min(jimp.width, jimp.height);
|
|
217
|
-
const cropped = jimp.crop({ x: 0, y: 0, w: min, h: min });
|
|
218
|
-
resized = cropped.resize({ w, h, mode: lib.jimp.ResizeStrategy.BILINEAR });
|
|
219
|
-
}
|
|
220
|
-
img = resized.getBuffer('image/jpeg', { quality: full ? 100 : 50 });
|
|
221
|
-
}
|
|
222
|
-
else if ('napi' in lib && typeof lib.napi?.Transformer === 'function') {
|
|
223
|
-
const transformer = new lib.napi.Transformer(buffer);
|
|
224
|
-
const meta = await transformer.metadata();
|
|
225
|
-
if (full) {
|
|
226
|
-
img = transformer.resize(w, h).jpeg(100);
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
const min = Math.min(meta.width, meta.height);
|
|
230
|
-
img = transformer.crop(0, 0, min, min).resize(w, h).jpeg(50);
|
|
231
|
-
}
|
|
160
|
+
const min = Math.min(jimp.width, jimp.height);
|
|
161
|
+
const cropped = jimp.crop({ x: 0, y: 0, w: min, h: min });
|
|
162
|
+
img = cropped.resize({ w, h, mode: lib.jimp.ResizeStrategy.BILINEAR }).getBuffer('image/jpeg', { quality: 50 });
|
|
232
163
|
}
|
|
233
164
|
else {
|
|
234
165
|
throw new Boom('No image processing library available');
|
|
@@ -375,34 +306,35 @@ export const getHttpStream = async (url, options = {}) => {
|
|
|
375
306
|
// @ts-ignore Node18+ Readable.fromWeb exists
|
|
376
307
|
return response.body instanceof Readable ? response.body : Readable.fromWeb(response.body);
|
|
377
308
|
};
|
|
378
|
-
export const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts } = {}) => {
|
|
309
|
+
export const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfRequired, opts, mediaKey: providedMediaKey } = {}) => {
|
|
379
310
|
const { stream, type } = await getStream(media, opts);
|
|
380
|
-
|
|
381
|
-
const mediaKey = Crypto.randomBytes(32);
|
|
311
|
+
let finalStream = stream;
|
|
312
|
+
const mediaKey = providedMediaKey || Crypto.randomBytes(32);
|
|
382
313
|
const { cipherKey, iv, macKey } = await getMediaKeys(mediaKey, mediaType);
|
|
383
|
-
const
|
|
384
|
-
|
|
385
|
-
let
|
|
386
|
-
let
|
|
387
|
-
if (
|
|
388
|
-
|
|
389
|
-
|
|
314
|
+
const encWriteStream = new Readable({ read: () => {}, highWaterMark: 64 * 1024 });
|
|
315
|
+
let bodyPath;
|
|
316
|
+
let writeStream;
|
|
317
|
+
let didSaveToTmpPath = false;
|
|
318
|
+
if (type === 'file') {
|
|
319
|
+
bodyPath = media.url?.toString?.() || media.url;
|
|
320
|
+
}
|
|
321
|
+
else if (saveOriginalFileIfRequired) {
|
|
322
|
+
bodyPath = join(getTmpFilesDirectory(), mediaType + generateMessageIDV2());
|
|
323
|
+
writeStream = createWriteStream(bodyPath);
|
|
324
|
+
didSaveToTmpPath = true;
|
|
390
325
|
}
|
|
391
326
|
let fileLength = 0;
|
|
392
327
|
const aes = Crypto.createCipheriv('aes-256-cbc', cipherKey, iv);
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
const onChunk =
|
|
397
|
-
sha256Enc.update(buff);
|
|
398
|
-
hmac.update(buff);
|
|
399
|
-
|
|
400
|
-
if (!encFileWriteStream.write(buff)) {
|
|
401
|
-
await once(encFileWriteStream, 'drain');
|
|
402
|
-
}
|
|
328
|
+
let hmac = Crypto.createHmac('sha256', macKey).update(iv);
|
|
329
|
+
let sha256Plain = Crypto.createHash('sha256');
|
|
330
|
+
let sha256Enc = Crypto.createHash('sha256');
|
|
331
|
+
const onChunk = (buff) => {
|
|
332
|
+
sha256Enc = sha256Enc.update(buff);
|
|
333
|
+
hmac = hmac.update(buff);
|
|
334
|
+
encWriteStream.push(buff);
|
|
403
335
|
};
|
|
404
336
|
try {
|
|
405
|
-
for await (const data of
|
|
337
|
+
for await (const data of finalStream) {
|
|
406
338
|
fileLength += data.length;
|
|
407
339
|
if (type === 'remote' &&
|
|
408
340
|
opts?.maxContentLength &&
|
|
@@ -411,82 +343,59 @@ export const encryptedStream = async (media, mediaType, { logger, saveOriginalFi
|
|
|
411
343
|
data: { media, type }
|
|
412
344
|
});
|
|
413
345
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
346
|
+
sha256Plain = sha256Plain.update(data);
|
|
347
|
+
if (writeStream) {
|
|
348
|
+
if (!writeStream.write(data)) {
|
|
349
|
+
await once(writeStream, 'drain');
|
|
417
350
|
}
|
|
418
351
|
}
|
|
419
|
-
|
|
420
|
-
await onChunk(aes.update(data));
|
|
352
|
+
onChunk(aes.update(data));
|
|
421
353
|
}
|
|
422
|
-
|
|
354
|
+
onChunk(aes.final());
|
|
423
355
|
const mac = hmac.digest().slice(0, 10);
|
|
424
|
-
sha256Enc.update(mac);
|
|
356
|
+
sha256Enc = sha256Enc.update(mac);
|
|
425
357
|
const fileSha256 = sha256Plain.digest();
|
|
426
358
|
const fileEncSha256 = sha256Enc.digest();
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
stream.destroy();
|
|
433
|
-
// Wait for write streams to fully flush to disk
|
|
434
|
-
// This helps reduce memory pressure by allowing OS to release buffers
|
|
435
|
-
await encFinishPromise;
|
|
436
|
-
await originalFinishPromise;
|
|
437
|
-
logger?.debug('encrypted data successfully');
|
|
359
|
+
encWriteStream.push(mac);
|
|
360
|
+
encWriteStream.push(null);
|
|
361
|
+
writeStream?.end?.();
|
|
362
|
+
if (writeStream) await once(writeStream, 'finish');
|
|
363
|
+
finalStream.destroy();
|
|
438
364
|
return {
|
|
439
365
|
mediaKey,
|
|
440
|
-
|
|
441
|
-
|
|
366
|
+
encWriteStream,
|
|
367
|
+
bodyPath,
|
|
442
368
|
mac,
|
|
443
369
|
fileEncSha256,
|
|
444
370
|
fileSha256,
|
|
445
|
-
fileLength
|
|
371
|
+
fileLength,
|
|
372
|
+
didSaveToTmpPath
|
|
446
373
|
};
|
|
447
374
|
}
|
|
448
375
|
catch (error) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
originalFileStream?.destroy?.();
|
|
376
|
+
encWriteStream.destroy();
|
|
377
|
+
writeStream?.destroy?.();
|
|
452
378
|
aes.destroy();
|
|
453
379
|
hmac.destroy();
|
|
454
380
|
sha256Plain.destroy();
|
|
455
381
|
sha256Enc.destroy();
|
|
456
382
|
stream.destroy();
|
|
457
|
-
|
|
458
|
-
await fs.unlink(
|
|
459
|
-
if (originalFilePath) {
|
|
460
|
-
await fs.unlink(originalFilePath);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
catch (err) {
|
|
464
|
-
logger?.error({ err }, 'failed deleting tmp files');
|
|
383
|
+
if (didSaveToTmpPath) {
|
|
384
|
+
try { await fs.unlink(bodyPath); } catch (_) {}
|
|
465
385
|
}
|
|
466
386
|
throw error;
|
|
467
387
|
}
|
|
468
388
|
};
|
|
469
|
-
|
|
389
|
+
|
|
390
|
+
const DEF_HOST = 'mmg.whatsapp.net';
|
|
470
391
|
const AES_CHUNK_SIZE = 16;
|
|
471
392
|
const toSmallestChunkSize = (num) => {
|
|
472
393
|
return Math.floor(num / AES_CHUNK_SIZE) * AES_CHUNK_SIZE;
|
|
473
394
|
};
|
|
474
|
-
export const getUrlFromDirectPath = (directPath
|
|
475
|
-
const extractHost = (url) => {
|
|
476
|
-
if (!url)
|
|
477
|
-
return undefined;
|
|
478
|
-
try {
|
|
479
|
-
return new URL(url).host;
|
|
480
|
-
}
|
|
481
|
-
catch {
|
|
482
|
-
return undefined;
|
|
483
|
-
}
|
|
484
|
-
};
|
|
395
|
+
export const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
485
396
|
export const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
const fallbackHost = opts.host ?? extractHost(url);
|
|
489
|
-
const downloadUrl = directPath ? getUrlFromDirectPath(directPath, fallbackHost) : url;
|
|
397
|
+
const isValidMediaUrl = url?.startsWith('https://mmg.whatsapp.net/');
|
|
398
|
+
const downloadUrl = isValidMediaUrl ? url : getUrlFromDirectPath(directPath);
|
|
490
399
|
if (!downloadUrl) {
|
|
491
400
|
throw new Boom('No valid media URL or directPath present in message', { statusCode: 400 });
|
|
492
401
|
}
|
|
@@ -546,7 +455,7 @@ export const downloadEncryptedContent = async (downloadUrl, { cipherKey, iv }, {
|
|
|
546
455
|
};
|
|
547
456
|
const output = new Transform({
|
|
548
457
|
transform(chunk, _, callback) {
|
|
549
|
-
let data =
|
|
458
|
+
let data = Buffer.concat([remainingBytes, chunk]);
|
|
550
459
|
const decryptLength = toSmallestChunkSize(data.length);
|
|
551
460
|
remainingBytes = data.slice(decryptLength);
|
|
552
461
|
data = data.slice(0, decryptLength);
|
|
@@ -665,10 +574,8 @@ const uploadWithFetch = async ({ url, filePath, headers, timeoutMs, agent }) =>
|
|
|
665
574
|
// Convert Node.js Readable to Web ReadableStream
|
|
666
575
|
const nodeStream = createReadStream(filePath);
|
|
667
576
|
const webStream = Readable.toWeb(nodeStream);
|
|
668
|
-
// Native fetch only accepts Undici-style dispatchers, not generic https Agents.
|
|
669
|
-
const dispatcher = typeof agent?.dispatch === 'function' ? agent : undefined;
|
|
670
577
|
const response = await fetch(url, {
|
|
671
|
-
|
|
578
|
+
dispatcher: agent,
|
|
672
579
|
method: 'POST',
|
|
673
580
|
body: webStream,
|
|
674
581
|
headers,
|
|
@@ -710,17 +617,14 @@ const uploadMedia = async (params, logger) => {
|
|
|
710
617
|
}
|
|
711
618
|
};
|
|
712
619
|
export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
713
|
-
return async (
|
|
714
|
-
// send a query JSON to obtain the url & auth token to upload our media
|
|
620
|
+
return async (streamOrPath, { mediaType, fileEncSha256B64, newsletter, timeoutMs }) => {
|
|
715
621
|
let uploadInfo = await refreshMediaConn(false);
|
|
716
622
|
let urls;
|
|
717
623
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
718
624
|
fileEncSha256B64 = encodeBase64EncodedStringForUpload(fileEncSha256B64);
|
|
719
|
-
// Prepare common headers
|
|
720
625
|
const customHeaders = (() => {
|
|
721
626
|
const hdrs = options?.headers;
|
|
722
|
-
if (!hdrs)
|
|
723
|
-
return {};
|
|
627
|
+
if (!hdrs) return {};
|
|
724
628
|
return Array.isArray(hdrs) ? Object.fromEntries(hdrs) : hdrs;
|
|
725
629
|
})();
|
|
726
630
|
const headers = {
|
|
@@ -728,23 +632,43 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, opt
|
|
|
728
632
|
'Content-Type': 'application/octet-stream',
|
|
729
633
|
Origin: DEFAULT_ORIGIN
|
|
730
634
|
};
|
|
635
|
+
let reqBuffer;
|
|
636
|
+
if (Buffer.isBuffer(streamOrPath)) {
|
|
637
|
+
reqBuffer = streamOrPath;
|
|
638
|
+
}
|
|
639
|
+
else if (typeof streamOrPath === 'string') {
|
|
640
|
+
reqBuffer = await fs.readFile(streamOrPath);
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
const chunks = [];
|
|
644
|
+
for await (const chunk of streamOrPath) chunks.push(chunk);
|
|
645
|
+
reqBuffer = Buffer.concat(chunks);
|
|
646
|
+
}
|
|
647
|
+
let mediaPath = MEDIA_PATH_MAP[mediaType];
|
|
648
|
+
if (newsletter && mediaPath) {
|
|
649
|
+
mediaPath = mediaPath.replace('/mms/', '/newsletter/newsletter-');
|
|
650
|
+
}
|
|
731
651
|
for (const { hostname } of hosts) {
|
|
732
652
|
logger.debug(`uploading to "${hostname}"`);
|
|
733
653
|
const auth = encodeURIComponent(uploadInfo.auth);
|
|
734
|
-
const url = `https://${hostname}${
|
|
654
|
+
const url = `https://${hostname}${mediaPath}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}`;
|
|
735
655
|
let result;
|
|
736
656
|
try {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
filePath,
|
|
657
|
+
const axios = (await import('axios')).default;
|
|
658
|
+
const body = await axios.post(url, reqBuffer, {
|
|
740
659
|
headers,
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
660
|
+
httpsAgent: fetchAgent,
|
|
661
|
+
timeout: timeoutMs,
|
|
662
|
+
responseType: 'json',
|
|
663
|
+
maxBodyLength: Infinity,
|
|
664
|
+
maxContentLength: Infinity
|
|
665
|
+
});
|
|
666
|
+
result = body.data;
|
|
744
667
|
if (result?.url || result?.direct_path) {
|
|
745
668
|
urls = {
|
|
746
669
|
mediaUrl: result.url,
|
|
747
670
|
directPath: result.direct_path,
|
|
671
|
+
handle: result.handle,
|
|
748
672
|
meta_hmac: result.meta_hmac,
|
|
749
673
|
fbid: result.fbid,
|
|
750
674
|
ts: result.ts
|
|
@@ -767,6 +691,7 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, opt
|
|
|
767
691
|
return urls;
|
|
768
692
|
};
|
|
769
693
|
};
|
|
694
|
+
|
|
770
695
|
const getMediaRetryKey = (mediaKey) => {
|
|
771
696
|
return hkdf(mediaKey, 32, { info: 'WhatsApp Media Retry Notification' });
|
|
772
697
|
};
|
|
@@ -854,124 +779,4 @@ const MEDIA_RETRY_STATUS_MAP = {
|
|
|
854
779
|
[proto.MediaRetryNotification.ResultType.NOT_FOUND]: 404,
|
|
855
780
|
[proto.MediaRetryNotification.ResultType.GENERAL_ERROR]: 418
|
|
856
781
|
};
|
|
857
|
-
const runFfmpegBuffer = (args, input) => {
|
|
858
|
-
return new Promise((resolve, reject) => {
|
|
859
|
-
const ff = spawn('ffmpeg', args, { stdio: ['pipe', 'pipe', 'ignore'] });
|
|
860
|
-
const chunks = [];
|
|
861
|
-
let len = 0;
|
|
862
|
-
ff.stdout.on('data', (c) => {
|
|
863
|
-
chunks.push(c);
|
|
864
|
-
len += c.length;
|
|
865
|
-
});
|
|
866
|
-
ff.on('close', code => (code === 0 ? resolve(Buffer.concat(chunks, len)) : reject(new Boom(`ffmpeg exited with code ${code}`))));
|
|
867
|
-
ff.on('error', reject);
|
|
868
|
-
ff.stdin.end(input);
|
|
869
|
-
});
|
|
870
|
-
};
|
|
871
|
-
export const resizeImage = async (buf, width, height, opts = {}) => {
|
|
872
|
-
const { quality = 80 } = opts;
|
|
873
|
-
const lib = await getImageProcessingLibrary();
|
|
874
|
-
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
875
|
-
return lib.sharp.default(buf).resize(width, height, { fit: 'inside' }).jpeg({ quality }).toBuffer();
|
|
876
|
-
}
|
|
877
|
-
//@ts-ignore
|
|
878
|
-
const jimpMod = await import('jimp').catch(() => undefined);
|
|
879
|
-
if (jimpMod) {
|
|
880
|
-
const Jimp = jimpMod.default || jimpMod;
|
|
881
|
-
const img = await Jimp.read(buf);
|
|
882
|
-
img.resize(width, height);
|
|
883
|
-
img.quality(quality);
|
|
884
|
-
return img.getBufferAsync(Jimp.MIME_JPEG);
|
|
885
|
-
}
|
|
886
|
-
throw new Boom('resizeImage requires "sharp" or "jimp" to be installed', { statusCode: 500 });
|
|
887
|
-
};
|
|
888
|
-
export const convertMedia = async (buf, opts) => {
|
|
889
|
-
const fmt = opts.to.toLowerCase().replace('.', '');
|
|
890
|
-
const imageFormats = { jpeg: 'jpeg', jpg: 'jpeg', png: 'png', webp: 'webp' };
|
|
891
|
-
if (imageFormats[fmt]) {
|
|
892
|
-
const lib = await getImageProcessingLibrary();
|
|
893
|
-
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
894
|
-
return lib.sharp.default(buf).toFormat(imageFormats[fmt]).toBuffer();
|
|
895
|
-
}
|
|
896
|
-
throw new Boom('convertMedia to an image format requires "sharp" to be installed', { statusCode: 500 });
|
|
897
|
-
}
|
|
898
|
-
const args = ['-i', 'pipe:0', '-y'];
|
|
899
|
-
if (fmt === 'mp4') {
|
|
900
|
-
args.push('-movflags', 'frag_keyframe+empty_moov', '-f', 'mp4');
|
|
901
|
-
}
|
|
902
|
-
else {
|
|
903
|
-
args.push('-f', fmt);
|
|
904
|
-
}
|
|
905
|
-
args.push('pipe:1');
|
|
906
|
-
return runFfmpegBuffer(args, buf);
|
|
907
|
-
};
|
|
908
|
-
export const imageToWebpSticker = async (buf, opts = {}) => {
|
|
909
|
-
const { quality = 80 } = opts;
|
|
910
|
-
const lib = await getImageProcessingLibrary();
|
|
911
|
-
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
912
|
-
return lib.sharp
|
|
913
|
-
.default(buf)
|
|
914
|
-
.resize(512, 512, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } })
|
|
915
|
-
.webp({ quality })
|
|
916
|
-
.toBuffer();
|
|
917
|
-
}
|
|
918
|
-
throw new Boom('imageToWebpSticker requires "sharp" to be installed', { statusCode: 500 });
|
|
919
|
-
};
|
|
920
|
-
export const compressMedia = async (buf, opts = {}) => {
|
|
921
|
-
const { quality = 50 } = opts;
|
|
922
|
-
const lib = await getImageProcessingLibrary();
|
|
923
|
-
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
924
|
-
try {
|
|
925
|
-
const { format } = await lib.sharp.default(buf).metadata();
|
|
926
|
-
if (format) {
|
|
927
|
-
return lib.sharp.default(buf).toFormat(format, { quality }).toBuffer();
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
catch { }
|
|
931
|
-
}
|
|
932
|
-
const crf = String(Math.round(51 - (quality / 100) * 51));
|
|
933
|
-
return runFfmpegBuffer(['-i', 'pipe:0', '-y', '-crf', crf, '-preset', 'ultrafast', '-movflags', 'frag_keyframe+empty_moov', '-f', 'mp4', 'pipe:1'], buf);
|
|
934
|
-
};
|
|
935
|
-
export const getMediaMetadata = async (buf) => {
|
|
936
|
-
const result = { size: buf.length };
|
|
937
|
-
const lib = await getImageProcessingLibrary();
|
|
938
|
-
if ('sharp' in lib && typeof lib.sharp?.default === 'function') {
|
|
939
|
-
try {
|
|
940
|
-
const meta = await lib.sharp.default(buf).metadata();
|
|
941
|
-
if (meta.format) {
|
|
942
|
-
result.mimetype = `image/${meta.format}`;
|
|
943
|
-
result.width = meta.width;
|
|
944
|
-
result.height = meta.height;
|
|
945
|
-
result.channels = meta.channels;
|
|
946
|
-
result.hasAlpha = meta.hasAlpha;
|
|
947
|
-
return result;
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
catch { }
|
|
951
|
-
}
|
|
952
|
-
return new Promise(resolve => {
|
|
953
|
-
const ff = spawn('ffprobe', ['-v', 'quiet', '-print_format', 'json', '-show_format', '-show_streams', 'pipe:0'], {
|
|
954
|
-
stdio: ['pipe', 'pipe', 'ignore']
|
|
955
|
-
});
|
|
956
|
-
const chunks = [];
|
|
957
|
-
ff.stdout.on('data', (c) => chunks.push(c));
|
|
958
|
-
ff.on('close', () => {
|
|
959
|
-
try {
|
|
960
|
-
const d = JSON.parse(Buffer.concat(chunks).toString());
|
|
961
|
-
const vid = d.streams?.find((s) => s.codec_type === 'video');
|
|
962
|
-
const aud = d.streams?.find((s) => s.codec_type === 'audio');
|
|
963
|
-
if (vid) {
|
|
964
|
-
result.width = vid.width;
|
|
965
|
-
result.height = vid.height;
|
|
966
|
-
}
|
|
967
|
-
result.duration = parseFloat(d.format?.duration) || undefined;
|
|
968
|
-
result.mimetype = vid ? 'video/mp4' : aud ? 'audio/mpeg' : undefined;
|
|
969
|
-
}
|
|
970
|
-
catch { }
|
|
971
|
-
resolve(result);
|
|
972
|
-
});
|
|
973
|
-
ff.on('error', () => resolve(result));
|
|
974
|
-
ff.stdin.end(buf);
|
|
975
|
-
});
|
|
976
|
-
};
|
|
977
782
|
//# sourceMappingURL=messages-media.js.map
|