@queenanya/baileys 8.2.7 → 8.3.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/WAProto/index.d.ts +1590 -6
- package/WAProto/index.js +4635 -3
- package/engine-requirements.js +1 -1
- package/lib/Defaults/baileys-version.json +1 -1
- package/lib/Defaults/index.d.ts +1 -1
- package/lib/Defaults/index.js +4 -5
- package/lib/Signal/Group/ciphertext-message.d.ts +9 -0
- package/lib/Signal/Group/ciphertext-message.js +15 -0
- package/lib/Signal/Group/group-session-builder.d.ts +14 -0
- package/lib/Signal/Group/group-session-builder.js +64 -0
- package/lib/Signal/Group/group_cipher.d.ts +17 -0
- package/lib/Signal/Group/group_cipher.js +96 -0
- package/lib/Signal/Group/index.d.ts +11 -0
- package/lib/Signal/Group/index.js +57 -0
- package/lib/Signal/Group/keyhelper.d.ts +10 -0
- package/lib/Signal/Group/keyhelper.js +55 -0
- package/lib/Signal/Group/queue-job.d.ts +1 -0
- package/lib/Signal/Group/queue-job.js +57 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +13 -0
- package/lib/Signal/Group/sender-chain-key.js +34 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +16 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +66 -0
- package/lib/Signal/Group/sender-key-message.d.ts +18 -0
- package/lib/Signal/Group/sender-key-message.js +69 -0
- package/lib/Signal/Group/sender-key-name.d.ts +17 -0
- package/lib/Signal/Group/sender-key-name.js +51 -0
- package/lib/Signal/Group/sender-key-record.d.ts +30 -0
- package/lib/Signal/Group/sender-key-record.js +53 -0
- package/lib/Signal/Group/sender-key-state.d.ts +38 -0
- package/lib/Signal/Group/sender-key-state.js +99 -0
- package/lib/Signal/Group/sender-message-key.d.ts +11 -0
- package/{WASignalGroup/sender_message_key.js → lib/Signal/Group/sender-message-key.js} +6 -16
- package/lib/Signal/libsignal.js +33 -20
- package/lib/Socket/Client/types.d.ts +1 -0
- package/lib/Socket/Client/websocket.d.ts +1 -0
- package/lib/Socket/Client/websocket.js +11 -1
- package/lib/Socket/business.d.ts +5 -8
- package/lib/Socket/chats.d.ts +4 -8
- package/lib/Socket/chats.js +7 -87
- package/lib/Socket/groups.d.ts +4 -6
- package/lib/Socket/groups.js +13 -9
- package/lib/Socket/index.d.ts +5 -8
- package/lib/Socket/messages-recv.d.ts +5 -8
- package/lib/Socket/messages-recv.js +20 -25
- package/lib/Socket/messages-send.d.ts +5 -8
- package/lib/Socket/messages-send.js +116 -81
- package/lib/Socket/newsletter.d.ts +4 -6
- package/lib/Socket/newsletter.js +2 -4
- package/lib/Socket/socket.js +63 -1
- package/lib/Socket/usync.js +15 -10
- package/lib/Types/Chat.d.ts +2 -8
- package/lib/Types/Contact.d.ts +4 -5
- package/lib/Types/GroupMetadata.d.ts +4 -3
- package/lib/Types/Label.d.ts +0 -11
- package/lib/Types/Message.d.ts +15 -2
- package/lib/Types/Socket.d.ts +0 -2
- package/lib/Utils/chat-utils.d.ts +8 -8
- package/lib/Utils/chat-utils.js +4 -30
- package/lib/Utils/crypto.d.ts +1 -1
- package/lib/Utils/crypto.js +1 -3
- package/lib/Utils/decode-wa-message.d.ts +2 -4
- package/lib/Utils/decode-wa-message.js +18 -161
- package/lib/Utils/generics.d.ts +18 -8
- package/lib/Utils/generics.js +93 -7
- package/lib/Utils/history.js +1 -1
- package/lib/Utils/index.d.ts +1 -0
- package/lib/Utils/index.js +1 -0
- package/lib/Utils/messages-media.d.ts +9 -16
- package/lib/Utils/messages-media.js +186 -98
- package/lib/Utils/messages.d.ts +1 -1
- package/lib/Utils/messages.js +27 -17
- package/lib/Utils/use-single-file-auth-state.d.ts +5 -0
- package/lib/Utils/use-single-file-auth-state.js +66 -0
- package/lib/Utils/validate-connection.js +7 -7
- package/lib/WABinary/constants.d.ts +4 -4
- package/lib/WABinary/constants.js +1271 -8
- package/lib/WABinary/encode.js +5 -7
- package/lib/WABinary/jid-utils.d.ts +3 -3
- package/lib/WABinary/jid-utils.js +18 -18
- package/lib/WAM/constants.d.ts +2 -3
- package/lib/WAM/encode.js +2 -2
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +2 -2
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +3 -3
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +2 -2
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +1 -1
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +1 -1
- package/lib/WAUSync/USyncQuery.js +13 -17
- package/package.json +10 -5
- package/WASignalGroup/GroupProtocol.js +0 -1697
- package/WASignalGroup/ciphertext_message.js +0 -16
- package/WASignalGroup/group_cipher.js +0 -120
- package/WASignalGroup/group_session_builder.js +0 -46
- package/WASignalGroup/index.js +0 -5
- package/WASignalGroup/keyhelper.js +0 -21
- package/WASignalGroup/protobufs.js +0 -3
- package/WASignalGroup/queue_job.js +0 -69
- package/WASignalGroup/sender_chain_key.js +0 -50
- package/WASignalGroup/sender_key_distribution_message.js +0 -78
- package/WASignalGroup/sender_key_message.js +0 -92
- package/WASignalGroup/sender_key_name.js +0 -70
- package/WASignalGroup/sender_key_record.js +0 -56
- package/WASignalGroup/sender_key_state.js +0 -129
- package/lib/Store/make-cache-manager-store.d.ts +0 -14
- package/lib/Store/make-cache-manager-store.js +0 -83
|
@@ -9,31 +9,24 @@ import { ILogger } from './logger';
|
|
|
9
9
|
export declare const hkdfInfoKey: (type: MediaType) => string;
|
|
10
10
|
/** generates all the keys required to encrypt/decrypt & sign a media message */
|
|
11
11
|
export declare function getMediaKeys(buffer: Uint8Array | string | null | undefined, mediaType: MediaType): Promise<MediaDecryptionKeyInfo>;
|
|
12
|
+
export declare function uploadFile(buffer: Buffer, logger?: ILogger): Promise<string>;
|
|
13
|
+
export declare function vid2jpg(videoUrl: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Originally written by Techwiz (https://github.com/techwiz37)
|
|
16
|
+
* Modified for customization and improvements
|
|
17
|
+
*/
|
|
18
|
+
export declare const extractVideoThumb: (videoPath: string) => Promise<Buffer<ArrayBufferLike>>;
|
|
12
19
|
export declare const extractImageThumb: (bufferOrFilePath: Readable | Buffer | string, width?: number) => Promise<{
|
|
13
20
|
buffer: Buffer<ArrayBufferLike>;
|
|
14
21
|
original: {
|
|
15
|
-
width: number
|
|
16
|
-
height: number
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
17
24
|
};
|
|
18
25
|
}>;
|
|
19
26
|
export declare const encodeBase64EncodedStringForUpload: (b64: string) => string;
|
|
20
27
|
export declare const generateProfilePicture: (mediaUpload: WAMediaUpload) => Promise<{
|
|
21
28
|
img: Buffer<ArrayBufferLike>;
|
|
22
29
|
}>;
|
|
23
|
-
export declare const generateProfilePictureFull: (img: any) => Promise<{
|
|
24
|
-
img: any;
|
|
25
|
-
}>;
|
|
26
|
-
export declare const generateProfilePictureFP: (buffer: any) => Promise<{
|
|
27
|
-
img: any;
|
|
28
|
-
preview: any;
|
|
29
|
-
}>;
|
|
30
|
-
export declare const generatePP: (buffer: any) => Promise<{
|
|
31
|
-
img: any;
|
|
32
|
-
preview: any;
|
|
33
|
-
}>;
|
|
34
|
-
export declare const changeprofileFull: (img: any) => Promise<{
|
|
35
|
-
img: any;
|
|
36
|
-
}>;
|
|
37
30
|
/** gets the SHA256 of the given media message */
|
|
38
31
|
export declare const mediaMessageSHA256B64: (message: WAMessageContent) => string | null | undefined;
|
|
39
32
|
export declare function getAudioDuration(buffer: Buffer | string | Readable): Promise<number | undefined>;
|
|
@@ -36,15 +36,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.prepareStream = exports.getHttpStream = exports.getStream = exports.toBuffer = exports.toReadable = exports.mediaMessageSHA256B64 = exports.
|
|
39
|
+
exports.getStatusCodeForMediaRetry = exports.decryptMediaRetryData = exports.decodeMediaRetryNode = exports.encryptMediaRetryRequest = exports.getWAUploadToServer = exports.downloadEncryptedContent = exports.downloadContentFromMessage = exports.getUrlFromDirectPath = exports.encryptedStream = exports.prepareStream = exports.getHttpStream = exports.getStream = exports.toBuffer = exports.toReadable = exports.mediaMessageSHA256B64 = exports.generateProfilePicture = exports.encodeBase64EncodedStringForUpload = exports.extractImageThumb = exports.extractVideoThumb = exports.hkdfInfoKey = void 0;
|
|
40
40
|
exports.getMediaKeys = getMediaKeys;
|
|
41
|
+
exports.uploadFile = uploadFile;
|
|
42
|
+
exports.vid2jpg = vid2jpg;
|
|
41
43
|
exports.getAudioDuration = getAudioDuration;
|
|
42
44
|
exports.getAudioWaveform = getAudioWaveform;
|
|
43
45
|
exports.generateThumbnail = generateThumbnail;
|
|
44
46
|
exports.extensionForMediaMessage = extensionForMediaMessage;
|
|
45
47
|
const boom_1 = require("@hapi/boom");
|
|
46
48
|
const axios_1 = __importDefault(require("axios"));
|
|
47
|
-
const
|
|
49
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
50
|
+
const cheerio = __importStar(require("cheerio"));
|
|
48
51
|
const Crypto = __importStar(require("crypto"));
|
|
49
52
|
const events_1 = require("events");
|
|
50
53
|
const fs_1 = require("fs");
|
|
@@ -99,18 +102,163 @@ async function getMediaKeys(buffer, mediaType) {
|
|
|
99
102
|
macKey: expandedMediaKey.slice(48, 80),
|
|
100
103
|
};
|
|
101
104
|
}
|
|
102
|
-
|
|
103
|
-
const
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
async function uploadFile(buffer, logger) {
|
|
106
|
+
const { fromBuffer } = await Promise.resolve().then(() => __importStar(require('file-type')));
|
|
107
|
+
const fileType = await fromBuffer(buffer);
|
|
108
|
+
if (!fileType)
|
|
109
|
+
throw new Error("Failed to detect file type.");
|
|
110
|
+
const { ext, mime } = fileType;
|
|
111
|
+
const services = [
|
|
112
|
+
{
|
|
113
|
+
name: "catbox",
|
|
114
|
+
url: "https://catbox.moe/user/api.php",
|
|
115
|
+
buildForm: () => {
|
|
116
|
+
const form = new form_data_1.default();
|
|
117
|
+
form.append("fileToUpload", buffer, {
|
|
118
|
+
filename: `file.${ext}`,
|
|
119
|
+
contentType: mime || "application/octet-stream"
|
|
120
|
+
});
|
|
121
|
+
form.append("reqtype", "fileupload");
|
|
122
|
+
return form;
|
|
123
|
+
},
|
|
124
|
+
parseResponse: res => res.data
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: "pdi.moe",
|
|
128
|
+
url: "https://scdn.pdi.moe/upload",
|
|
129
|
+
buildForm: () => {
|
|
130
|
+
const form = new form_data_1.default();
|
|
131
|
+
form.append("file", buffer, {
|
|
132
|
+
filename: `file.${ext}`,
|
|
133
|
+
contentType: mime
|
|
134
|
+
});
|
|
135
|
+
return form;
|
|
136
|
+
},
|
|
137
|
+
parseResponse: res => res.data.result.url
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "qu.ax",
|
|
141
|
+
url: "https://qu.ax/upload.php",
|
|
142
|
+
buildForm: () => {
|
|
143
|
+
const form = new form_data_1.default();
|
|
144
|
+
form.append("files[]", buffer, {
|
|
145
|
+
filename: `file.${ext}`,
|
|
146
|
+
contentType: mime || "application/octet-stream"
|
|
147
|
+
});
|
|
148
|
+
return form;
|
|
149
|
+
},
|
|
150
|
+
parseResponse: res => {
|
|
151
|
+
var _a, _b, _c;
|
|
152
|
+
if (!((_c = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.url))
|
|
153
|
+
throw new Error("Failed to get URL from qu.ax");
|
|
154
|
+
return res.data.files[0].url;
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: "uguu.se",
|
|
159
|
+
url: "https://uguu.se/upload.php",
|
|
160
|
+
buildForm: () => {
|
|
161
|
+
const form = new form_data_1.default();
|
|
162
|
+
form.append("files[]", buffer, {
|
|
163
|
+
filename: `file.${ext}`,
|
|
164
|
+
contentType: mime || "application/octet-stream"
|
|
165
|
+
});
|
|
166
|
+
return form;
|
|
167
|
+
},
|
|
168
|
+
parseResponse: res => {
|
|
169
|
+
var _a, _b, _c;
|
|
170
|
+
if (!((_c = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.url))
|
|
171
|
+
throw new Error("Failed to get URL from uguu.se");
|
|
172
|
+
return res.data.files[0].url;
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "tmpfiles",
|
|
177
|
+
url: "https://tmpfiles.org/api/v1/upload",
|
|
178
|
+
buildForm: () => {
|
|
179
|
+
const form = new form_data_1.default();
|
|
180
|
+
form.append("file", buffer, {
|
|
181
|
+
filename: `file.${ext}`,
|
|
182
|
+
contentType: mime
|
|
183
|
+
});
|
|
184
|
+
return form;
|
|
185
|
+
},
|
|
186
|
+
parseResponse: res => {
|
|
187
|
+
const match = res.data.data.url.match(/https:\/\/tmpfiles\.org\/(.*)/);
|
|
188
|
+
if (!match)
|
|
189
|
+
throw new Error("Failed to parse tmpfiles URL.");
|
|
190
|
+
return `https://tmpfiles.org/dl/${match[1]}`;
|
|
191
|
+
}
|
|
108
192
|
}
|
|
109
|
-
|
|
110
|
-
|
|
193
|
+
];
|
|
194
|
+
for (const service of services) {
|
|
195
|
+
try {
|
|
196
|
+
const form = service.buildForm();
|
|
197
|
+
const res = await axios_1.default.post(service.url, form, {
|
|
198
|
+
headers: form.getHeaders()
|
|
199
|
+
});
|
|
200
|
+
const url = service.parseResponse(res);
|
|
201
|
+
return url;
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
logger === null || logger === void 0 ? void 0 : logger.debug(`[${service.name}] eror:`, (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
throw new Error("All upload services failed.");
|
|
208
|
+
}
|
|
209
|
+
async function vid2jpg(videoUrl) {
|
|
210
|
+
try {
|
|
211
|
+
const { data } = await axios_1.default.get(`https://ezgif.com/video-to-jpg?url=${encodeURIComponent(videoUrl)}`);
|
|
212
|
+
const $ = cheerio.load(data);
|
|
213
|
+
const fileToken = $('input[name="file"]').attr("value");
|
|
214
|
+
if (!fileToken) {
|
|
215
|
+
throw new Error("Failed to retrieve file token. The video URL may be invalid or inaccessible.");
|
|
111
216
|
}
|
|
217
|
+
const formData = new URLSearchParams();
|
|
218
|
+
formData.append("file", fileToken);
|
|
219
|
+
formData.append("end", "1");
|
|
220
|
+
formData.append("video-to-jpg", "Convert to JPG!");
|
|
221
|
+
const convert = await axios_1.default.post(`https://ezgif.com/video-to-jpg/${fileToken}`, formData);
|
|
222
|
+
const $2 = cheerio.load(convert.data);
|
|
223
|
+
let imageUrl = $2("#output img").first().attr("src");
|
|
224
|
+
if (!imageUrl) {
|
|
225
|
+
throw new Error("Could not locate the converted image output.");
|
|
226
|
+
}
|
|
227
|
+
if (imageUrl.startsWith("//")) {
|
|
228
|
+
imageUrl = "https:" + imageUrl;
|
|
229
|
+
}
|
|
230
|
+
else if (imageUrl.startsWith("/")) {
|
|
231
|
+
const cdnMatch = imageUrl.match(/\/(s\d+\..+?)\/.*/);
|
|
232
|
+
if (cdnMatch) {
|
|
233
|
+
imageUrl = "https://" + imageUrl.slice(2);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
imageUrl = "https://ezgif.com" + imageUrl;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return imageUrl;
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
throw new Error("Failed to convert video to JPG: " + error.message);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Originally written by Techwiz (https://github.com/techwiz37)
|
|
247
|
+
* Modified for customization and improvements
|
|
248
|
+
*/
|
|
249
|
+
const extractVideoThumb = async (videoPath) => {
|
|
250
|
+
const videoBuffer = await fs_1.promises.readFile(videoPath);
|
|
251
|
+
const dataUrl = await uploadFile(videoBuffer);
|
|
252
|
+
if (!dataUrl || typeof dataUrl !== 'string') {
|
|
253
|
+
throw new Error('Failed to upload video: Invalid or missing URL');
|
|
254
|
+
}
|
|
255
|
+
const jpgUrl = await vid2jpg(dataUrl);
|
|
256
|
+
const { data: imageBuffer } = await axios_1.default.get(jpgUrl, {
|
|
257
|
+
responseType: 'arraybuffer',
|
|
112
258
|
});
|
|
113
|
-
|
|
259
|
+
return imageBuffer;
|
|
260
|
+
};
|
|
261
|
+
exports.extractVideoThumb = extractVideoThumb;
|
|
114
262
|
const extractImageThumb = async (bufferOrFilePath, width = 32) => {
|
|
115
263
|
var _a, _b;
|
|
116
264
|
if (bufferOrFilePath instanceof stream_1.Readable) {
|
|
@@ -180,76 +328,6 @@ const generateProfilePicture = async (mediaUpload) => {
|
|
|
180
328
|
};
|
|
181
329
|
};
|
|
182
330
|
exports.generateProfilePicture = generateProfilePicture;
|
|
183
|
-
const generateProfilePictureFull = async (img) => {
|
|
184
|
-
const Jimp = require('jimp');
|
|
185
|
-
const { read, MIME_JPEG, RESIZE_BILINEAR } = require('jimp');
|
|
186
|
-
const jimp = await read(img);
|
|
187
|
-
const min = Math.min(jimp.getWidth(), jimp.getHeight());
|
|
188
|
-
const cropped = jimp.crop(0, 0, jimp.getWidth(), jimp.getHeight());
|
|
189
|
-
let width = jimp.getWidth(), hight = jimp.getHeight(), ratio;
|
|
190
|
-
if (width > hight) {
|
|
191
|
-
ratio = jimp.getWidth() / 720;
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
ratio = jimp.getWidth() / 324;
|
|
195
|
-
}
|
|
196
|
-
;
|
|
197
|
-
width = width / ratio;
|
|
198
|
-
hight = hight / ratio;
|
|
199
|
-
img = cropped.quality(100).resize(width, hight).getBufferAsync(MIME_JPEG);
|
|
200
|
-
return {
|
|
201
|
-
img: await cropped.quality(100).resize(width, hight).getBufferAsync(MIME_JPEG),
|
|
202
|
-
};
|
|
203
|
-
};
|
|
204
|
-
exports.generateProfilePictureFull = generateProfilePictureFull;
|
|
205
|
-
const generateProfilePictureFP = async (buffer) => {
|
|
206
|
-
const Jimp = require('jimp');
|
|
207
|
-
const { read, MIME_JPEG, RESIZE_BILINEAR } = require('jimp');
|
|
208
|
-
const jimp = await Jimp.read(buffer);
|
|
209
|
-
const min = jimp.getWidth();
|
|
210
|
-
const max = jimp.getHeight();
|
|
211
|
-
const cropped = jimp.crop(0, 0, min, max);
|
|
212
|
-
return {
|
|
213
|
-
img: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG),
|
|
214
|
-
preview: await cropped.normalize().getBufferAsync(Jimp.MIME_JPEG),
|
|
215
|
-
};
|
|
216
|
-
};
|
|
217
|
-
exports.generateProfilePictureFP = generateProfilePictureFP;
|
|
218
|
-
const generatePP = async (buffer) => {
|
|
219
|
-
const Jimp = require('jimp');
|
|
220
|
-
const { read, MIME_JPEG, RESIZE_BILINEAR } = require('jimp');
|
|
221
|
-
const jimp = await Jimp.read(buffer);
|
|
222
|
-
const min = jimp.getWidth();
|
|
223
|
-
const max = jimp.getHeight();
|
|
224
|
-
const cropped = jimp.crop(0, 0, min, max);
|
|
225
|
-
return {
|
|
226
|
-
img: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG),
|
|
227
|
-
preview: await cropped.normalize().getBufferAsync(Jimp.MIME_JPEG),
|
|
228
|
-
};
|
|
229
|
-
};
|
|
230
|
-
exports.generatePP = generatePP;
|
|
231
|
-
const changeprofileFull = async (img) => {
|
|
232
|
-
const Jimp = require('jimp');
|
|
233
|
-
const { read, MIME_JPEG, RESIZE_BILINEAR } = require('jimp');
|
|
234
|
-
const jimp = await read(img);
|
|
235
|
-
const min = Math.min(jimp.getWidth(), jimp.getHeight());
|
|
236
|
-
const cropped = jimp.crop(0, 0, jimp.getWidth(), jimp.getHeight());
|
|
237
|
-
let width = jimp.getWidth(), hight = jimp.getHeight(), ratio;
|
|
238
|
-
if (width > hight) {
|
|
239
|
-
ratio = jimp.getWidth() / 720;
|
|
240
|
-
}
|
|
241
|
-
else {
|
|
242
|
-
ratio = jimp.getWidth() / 324;
|
|
243
|
-
}
|
|
244
|
-
;
|
|
245
|
-
width = width / ratio;
|
|
246
|
-
hight = hight / ratio;
|
|
247
|
-
img = cropped.quality(100).resize(width, hight).getBufferAsync(MIME_JPEG);
|
|
248
|
-
return {
|
|
249
|
-
img: await cropped.quality(100).resize(width, hight).getBufferAsync(MIME_JPEG),
|
|
250
|
-
};
|
|
251
|
-
};
|
|
252
|
-
exports.changeprofileFull = changeprofileFull;
|
|
253
331
|
/** gets the SHA256 of the given media message */
|
|
254
332
|
const mediaMessageSHA256B64 = (message) => {
|
|
255
333
|
const media = Object.values(message)[0];
|
|
@@ -259,20 +337,17 @@ exports.mediaMessageSHA256B64 = mediaMessageSHA256B64;
|
|
|
259
337
|
async function getAudioDuration(buffer) {
|
|
260
338
|
const musicMetadata = await Promise.resolve().then(() => __importStar(require('music-metadata')));
|
|
261
339
|
let metadata;
|
|
340
|
+
const options = {
|
|
341
|
+
duration: true
|
|
342
|
+
};
|
|
262
343
|
if (Buffer.isBuffer(buffer)) {
|
|
263
|
-
metadata = await musicMetadata.parseBuffer(buffer, undefined,
|
|
344
|
+
metadata = await musicMetadata.parseBuffer(buffer, undefined, options);
|
|
264
345
|
}
|
|
265
346
|
else if (typeof buffer === 'string') {
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
metadata = await musicMetadata.parseStream(rStream, undefined, { duration: true });
|
|
269
|
-
}
|
|
270
|
-
finally {
|
|
271
|
-
rStream.destroy();
|
|
272
|
-
}
|
|
347
|
+
metadata = await musicMetadata.parseFile(buffer, options);
|
|
273
348
|
}
|
|
274
349
|
else {
|
|
275
|
-
metadata = await musicMetadata.parseStream(buffer, undefined,
|
|
350
|
+
metadata = await musicMetadata.parseStream(buffer, undefined, options);
|
|
276
351
|
}
|
|
277
352
|
return metadata.format.duration;
|
|
278
353
|
}
|
|
@@ -362,11 +437,18 @@ async function generateThumbnail(file, mediaType, options) {
|
|
|
362
437
|
}
|
|
363
438
|
}
|
|
364
439
|
else if (mediaType === 'video') {
|
|
365
|
-
const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageIDV2)() + '.jpg');
|
|
366
440
|
try {
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
|
|
441
|
+
const thumbnailBuffer = await (0, exports.extractVideoThumb)(file);
|
|
442
|
+
const imgFilename = (0, path_1.join)(getTmpFilesDirectory(), (0, generics_1.generateMessageIDV2)() + '.jpg');
|
|
443
|
+
await fs_1.promises.writeFile(imgFilename, thumbnailBuffer);
|
|
444
|
+
const { buffer: processedThumbnailBuffer, original } = await (0, exports.extractImageThumb)(imgFilename);
|
|
445
|
+
thumbnail = processedThumbnailBuffer.toString('base64');
|
|
446
|
+
if (original.width && original.height) {
|
|
447
|
+
originalImageDimensions = {
|
|
448
|
+
width: original.width,
|
|
449
|
+
height: original.height,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
370
452
|
await fs_1.promises.unlink(imgFilename);
|
|
371
453
|
}
|
|
372
454
|
catch (err) {
|
|
@@ -437,7 +519,7 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
437
519
|
let writeStream;
|
|
438
520
|
let didSaveToTmpPath = false;
|
|
439
521
|
if (type === 'file') {
|
|
440
|
-
bodyPath = media.url
|
|
522
|
+
bodyPath = media.url;
|
|
441
523
|
}
|
|
442
524
|
else if (saveOriginalFileIfRequired) {
|
|
443
525
|
bodyPath = (0, path_1.join)(getTmpFilesDirectory(), mediaType + (0, generics_1.generateMessageIDV2)());
|
|
@@ -460,8 +542,10 @@ const encryptedStream = async (media, mediaType, { logger, saveOriginalFileIfReq
|
|
|
460
542
|
});
|
|
461
543
|
}
|
|
462
544
|
sha256Plain = sha256Plain.update(data);
|
|
463
|
-
if (writeStream
|
|
464
|
-
|
|
545
|
+
if (writeStream) {
|
|
546
|
+
if (!writeStream.write(data)) {
|
|
547
|
+
await (0, events_1.once)(writeStream, 'drain');
|
|
548
|
+
}
|
|
465
549
|
}
|
|
466
550
|
onChunk(aes.update(data));
|
|
467
551
|
}
|
|
@@ -520,7 +604,11 @@ const toSmallestChunkSize = (num) => {
|
|
|
520
604
|
const getUrlFromDirectPath = (directPath) => `https://${DEF_HOST}${directPath}`;
|
|
521
605
|
exports.getUrlFromDirectPath = getUrlFromDirectPath;
|
|
522
606
|
const downloadContentFromMessage = async ({ mediaKey, directPath, url }, type, opts = {}) => {
|
|
523
|
-
const
|
|
607
|
+
const isValidMediaUrl = url === null || url === void 0 ? void 0 : url.startsWith('https://mmg.whatsapp.net/');
|
|
608
|
+
const downloadUrl = isValidMediaUrl ? url : (0, exports.getUrlFromDirectPath)(directPath);
|
|
609
|
+
if (!downloadUrl) {
|
|
610
|
+
throw new boom_1.Boom('No valid media URL or directPath present in message', { statusCode: 400 });
|
|
611
|
+
}
|
|
524
612
|
const keys = await getMediaKeys(mediaKey, type);
|
|
525
613
|
return (0, exports.downloadEncryptedContent)(downloadUrl, keys, opts);
|
|
526
614
|
};
|
package/lib/Utils/messages.d.ts
CHANGED
|
@@ -38,7 +38,7 @@ export declare const extractMessageContent: (content: WAMessageContent | undefin
|
|
|
38
38
|
/**
|
|
39
39
|
* Returns the device predicted by message ID
|
|
40
40
|
*/
|
|
41
|
-
export declare const getDevice: (id: string) => "
|
|
41
|
+
export declare const getDevice: (id: string) => "web" | "unknown" | "android" | "ios" | "desktop";
|
|
42
42
|
/** Upserts a receipt in the message */
|
|
43
43
|
export declare const updateMessageWithReceipt: (msg: Pick<WAMessage, "userReceipt">, receipt: MessageUserReceipt) => void;
|
|
44
44
|
/** Update the message with a new reaction */
|
package/lib/Utils/messages.js
CHANGED
|
@@ -275,9 +275,6 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
275
275
|
extContent.font = options.font;
|
|
276
276
|
}
|
|
277
277
|
m.extendedTextMessage = extContent;
|
|
278
|
-
m.messageContextInfo = {
|
|
279
|
-
messageSecret: (0, crypto_1.randomBytes)(32)
|
|
280
|
-
};
|
|
281
278
|
}
|
|
282
279
|
else if ('contacts' in message) {
|
|
283
280
|
const contactLen = message.contacts.contacts.length;
|
|
@@ -437,12 +434,12 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
437
434
|
m.pollCreationMessageV2 = pollCreationMessage;
|
|
438
435
|
}
|
|
439
436
|
else {
|
|
440
|
-
if (message.poll.selectableCount
|
|
437
|
+
if (message.poll.selectableCount === 1) {
|
|
441
438
|
// poll v3 is for single select polls
|
|
442
439
|
m.pollCreationMessageV3 = pollCreationMessage;
|
|
443
440
|
}
|
|
444
441
|
else {
|
|
445
|
-
// poll
|
|
442
|
+
// poll for multiple choice polls
|
|
446
443
|
m.pollCreationMessage = pollCreationMessage;
|
|
447
444
|
}
|
|
448
445
|
}
|
|
@@ -502,6 +499,14 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
502
499
|
else if ('requestPhoneNumber' in message) {
|
|
503
500
|
m.requestPhoneNumberMessage = {};
|
|
504
501
|
}
|
|
502
|
+
else if ('album' in message) {
|
|
503
|
+
const imageMessages = message.album.filter(item => 'image' in item);
|
|
504
|
+
const videoMessages = message.album.filter(item => 'video' in item);
|
|
505
|
+
m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
|
|
506
|
+
expectedImageCount: imageMessages.length,
|
|
507
|
+
expectedVideoCount: videoMessages.length,
|
|
508
|
+
});
|
|
509
|
+
}
|
|
505
510
|
else {
|
|
506
511
|
m = await (0, exports.prepareWAMessageMedia)(message, options);
|
|
507
512
|
}
|
|
@@ -566,7 +571,7 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
566
571
|
title: message.title,
|
|
567
572
|
footerText: message.footer,
|
|
568
573
|
description: message.text,
|
|
569
|
-
listType:
|
|
574
|
+
listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
|
|
570
575
|
};
|
|
571
576
|
m = { listMessage };
|
|
572
577
|
}
|
|
@@ -804,7 +809,9 @@ const normalizeMessageContent = (content) => {
|
|
|
804
809
|
|| (message === null || message === void 0 ? void 0 : message.groupStatusMessage)
|
|
805
810
|
|| (message === null || message === void 0 ? void 0 : message.limitSharingMessage)
|
|
806
811
|
|| (message === null || message === void 0 ? void 0 : message.botTaskMessage)
|
|
807
|
-
|| (message === null || message === void 0 ? void 0 : message.questionMessage)
|
|
812
|
+
|| (message === null || message === void 0 ? void 0 : message.questionMessage)
|
|
813
|
+
|| (message === null || message === void 0 ? void 0 : message.groupStatusMessageV2)
|
|
814
|
+
|| (message === null || message === void 0 ? void 0 : message.botForwardedMessage));
|
|
808
815
|
}
|
|
809
816
|
};
|
|
810
817
|
exports.normalizeMessageContent = normalizeMessageContent;
|
|
@@ -877,9 +884,8 @@ const updateMessageWithReaction = (msg, reaction) => {
|
|
|
877
884
|
const authorID = (0, generics_1.getKeyAuthor)(reaction.key);
|
|
878
885
|
const reactions = (msg.reactions || [])
|
|
879
886
|
.filter(r => (0, generics_1.getKeyAuthor)(r.key) !== authorID);
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
}
|
|
887
|
+
reaction.text = reaction.text || '';
|
|
888
|
+
reactions.push(reaction);
|
|
883
889
|
msg.reactions = reactions;
|
|
884
890
|
};
|
|
885
891
|
exports.updateMessageWithReaction = updateMessageWithReaction;
|
|
@@ -959,13 +965,17 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
959
965
|
const result = await downloadMsg()
|
|
960
966
|
.catch(async (error) => {
|
|
961
967
|
var _a;
|
|
962
|
-
if (ctx
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
968
|
+
if (ctx) {
|
|
969
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
970
|
+
// check if the message requires a reupload
|
|
971
|
+
if (REUPLOAD_REQUIRED_STATUS.includes((_a = error.response) === null || _a === void 0 ? void 0 : _a.status)) {
|
|
972
|
+
ctx.logger.info({ key: message.key }, 'sending reupload media request...');
|
|
973
|
+
// request reupload
|
|
974
|
+
message = await ctx.reuploadRequest(message);
|
|
975
|
+
const result = await downloadMsg();
|
|
976
|
+
return result;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
969
979
|
}
|
|
970
980
|
throw error;
|
|
971
981
|
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useSingleFileAuthState = void 0;
|
|
7
|
+
const async_lock_1 = __importDefault(require("async-lock"));
|
|
8
|
+
const promises_1 = require("fs/promises");
|
|
9
|
+
const index_1 = require("../../WAProto/index");
|
|
10
|
+
const auth_utils_1 = require("./auth-utils");
|
|
11
|
+
const generics_1 = require("./generics");
|
|
12
|
+
const fileLock = new async_lock_1.default({ maxPending: Infinity });
|
|
13
|
+
const useSingleFileAuthState = async (filepath) => {
|
|
14
|
+
const filePath = filepath + '.json';
|
|
15
|
+
const writeData = (data) => {
|
|
16
|
+
return fileLock.acquire(filePath, () => (0, promises_1.writeFile)(filePath, JSON.stringify(data, generics_1.BufferJSON.replacer)));
|
|
17
|
+
};
|
|
18
|
+
const readData = async () => {
|
|
19
|
+
try {
|
|
20
|
+
const data = await fileLock.acquire(filePath, () => (0, promises_1.readFile)(filePath, { encoding: 'utf-8' }));
|
|
21
|
+
return JSON.parse(data, generics_1.BufferJSON.reviver);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const fileInfo = await (0, promises_1.stat)(filePath).catch(() => null);
|
|
28
|
+
if (fileInfo && !fileInfo.isFile()) {
|
|
29
|
+
throw new Error(`A non-file exists at ${filePath}, please delete it or specify a different path.`);
|
|
30
|
+
}
|
|
31
|
+
// Initialize with default credentials if the file is empty or doesn't exist
|
|
32
|
+
const { creds = (0, auth_utils_1.initAuthCreds)(), keys = {} } = await readData() || {};
|
|
33
|
+
return {
|
|
34
|
+
state: {
|
|
35
|
+
creds,
|
|
36
|
+
keys: {
|
|
37
|
+
get: async (type, ids) => {
|
|
38
|
+
const data = {};
|
|
39
|
+
for (const id of ids) {
|
|
40
|
+
const value = keys[`${type}-${id}`];
|
|
41
|
+
data[id] = type === 'app-state-sync-key' && value
|
|
42
|
+
? index_1.proto.Message.AppStateSyncKeyData.fromObject(value)
|
|
43
|
+
: value;
|
|
44
|
+
}
|
|
45
|
+
return data;
|
|
46
|
+
},
|
|
47
|
+
set: async (data) => {
|
|
48
|
+
for (const category in data) {
|
|
49
|
+
for (const id in data[category]) {
|
|
50
|
+
const value = data[category][id];
|
|
51
|
+
if (value) {
|
|
52
|
+
keys[`${category}-${id}`] = value;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
delete keys[`${category}-${id}`];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
await writeData({ creds, keys });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
saveCreds: () => writeData({ creds, keys })
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
exports.useSingleFileAuthState = useSingleFileAuthState;
|
|
@@ -22,7 +22,7 @@ const getUserAgent = (config) => {
|
|
|
22
22
|
device: 'Desktop',
|
|
23
23
|
osBuildNumber: '0.1',
|
|
24
24
|
localeLanguageIso6391: 'en',
|
|
25
|
-
localeCountryIso31661Alpha2:
|
|
25
|
+
localeCountryIso31661Alpha2: 'US'
|
|
26
26
|
};
|
|
27
27
|
};
|
|
28
28
|
const PLATFORM_MAP = {
|
|
@@ -103,21 +103,21 @@ const configureSuccessfulPairing = (stanza, { advSecretKey, signedIdentityKey, s
|
|
|
103
103
|
}
|
|
104
104
|
const bizName = businessNode === null || businessNode === void 0 ? void 0 : businessNode.attrs.name;
|
|
105
105
|
const jid = deviceNode.attrs.jid;
|
|
106
|
-
const { details, hmac } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
|
|
107
|
-
|
|
108
|
-
const
|
|
106
|
+
const { details, hmac, accountType } = WAProto_1.proto.ADVSignedDeviceIdentityHMAC.decode(deviceIdentityNode.content);
|
|
107
|
+
const isHostedAccount = accountType !== undefined && accountType === WAProto_1.proto.ADVEncryptionType.HOSTED;
|
|
108
|
+
const hmacPrefix = isHostedAccount ? Buffer.from([6, 5]) : Buffer.alloc(0);
|
|
109
|
+
const advSign = (0, crypto_2.hmacSign)(Buffer.concat([hmacPrefix, details]), Buffer.from(advSecretKey, 'base64'));
|
|
109
110
|
if (Buffer.compare(hmac, advSign) !== 0) {
|
|
110
111
|
throw new boom_1.Boom('Invalid account signature');
|
|
111
112
|
}
|
|
112
113
|
const account = WAProto_1.proto.ADVSignedDeviceIdentity.decode(details);
|
|
113
114
|
const { accountSignatureKey, accountSignature, details: deviceDetails } = account;
|
|
114
|
-
// verify the device signature matches
|
|
115
115
|
const accountMsg = Buffer.concat([Buffer.from([6, 0]), deviceDetails, signedIdentityKey.public]);
|
|
116
116
|
if (!crypto_2.Curve.verify(accountSignatureKey, accountMsg, accountSignature)) {
|
|
117
117
|
throw new boom_1.Boom('Failed to verify account signature');
|
|
118
118
|
}
|
|
119
|
-
|
|
120
|
-
const deviceMsg = Buffer.concat([
|
|
119
|
+
const devicePrefix = isHostedAccount ? Buffer.from([6, 6]) : Buffer.from([6, 1]);
|
|
120
|
+
const deviceMsg = Buffer.concat([devicePrefix, deviceDetails, signedIdentityKey.public, accountSignatureKey]);
|
|
121
121
|
account.deviceSignature = crypto_2.Curve.sign(signedIdentityKey.private, deviceMsg);
|
|
122
122
|
const identity = (0, signal_1.createSignalIdentity)(jid, accountSignatureKey);
|
|
123
123
|
const accountEnc = (0, exports.encodeSignedDeviceIdentity)(account, false);
|