@itsliaaa/baileys 0.1.28 โ 0.1.30
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 +31 -7
- package/lib/Utils/messages.js +109 -139
- package/lib/Utils/use-single-file-auth-state.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,10 +41,9 @@ Hi everyone,
|
|
|
41
41
|
>
|
|
42
42
|
> Recently, I found a few packages published on npm that are essentially just **renamed** versions of a fork I personally worked on:
|
|
43
43
|
>
|
|
44
|
-
> - https://www.npmjs.com/package/@noya4u_27/baileys
|
|
45
|
-
> - https://www.npmjs.com/package/@phrolovaa/baileys
|
|
46
|
-
> - https://www.npmjs.com/package/@dnuzi/baileys
|
|
47
|
-
> - https://www.npmjs.com/package/@crysnovax/baileys
|
|
44
|
+
> - [@noya4u_27](https://www.npmjs.com/package/@noya4u_27/baileys) **[STEALER]**
|
|
45
|
+
> - [@phrolovaa](https://www.npmjs.com/package/@phrolovaa/baileys) **[STEALER]**
|
|
46
|
+
> - [@dnuzi](https://www.npmjs.com/package/@dnuzi/baileys) **[STEALER]**
|
|
48
47
|
>
|
|
49
48
|
> To be clear, Iโm **not** the original maintainer of Baileys all respect goes to the amazing work behind [@whiskeysockets/baileys](https://github.com/WhiskeySockets/Baileys). I only created and maintained my own fork ([@itsliaaa/baileys](https://www.npmjs.com/package/@itsliaaa/baileys)) where I spent a **lot** of time improving and adapting things on my own.
|
|
50
49
|
>
|
|
@@ -383,6 +382,28 @@ sock.sendMessage(jid, {
|
|
|
383
382
|
})
|
|
384
383
|
```
|
|
385
384
|
|
|
385
|
+
#### ๐ฅ Group Invite
|
|
386
|
+
|
|
387
|
+
```javascript
|
|
388
|
+
const groupJid = '1201111111111@g.us'
|
|
389
|
+
const groupName = '@itsliaaa/baileys'
|
|
390
|
+
const inviteCode = groupUrl
|
|
391
|
+
.split('chat.whatsapp.com/')[1]?
|
|
392
|
+
.split('?')[0]
|
|
393
|
+
|
|
394
|
+
sock.sendMessage(jid, {
|
|
395
|
+
groupInvite: {
|
|
396
|
+
inviteCode,
|
|
397
|
+
inviteExpiration: Date.now() + 86400000,
|
|
398
|
+
text: '๐๐ป Hello, we invite you to join our group.',
|
|
399
|
+
jid: groupJid,
|
|
400
|
+
subject: groupName,
|
|
401
|
+
}
|
|
402
|
+
}, {
|
|
403
|
+
quoted: message
|
|
404
|
+
})
|
|
405
|
+
```
|
|
406
|
+
|
|
386
407
|
#### ๐ Poll
|
|
387
408
|
|
|
388
409
|
```javascript
|
|
@@ -827,7 +848,8 @@ sock.sendMessage(jid, {
|
|
|
827
848
|
copy: '@itsliaaa/baileys'
|
|
828
849
|
}, {
|
|
829
850
|
text: '๐ Source',
|
|
830
|
-
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
851
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
|
852
|
+
useWebview: true // --- Optional
|
|
831
853
|
}, {
|
|
832
854
|
text: '๐ Select',
|
|
833
855
|
sections: [{
|
|
@@ -867,7 +889,8 @@ sock.sendMessage(jid, {
|
|
|
867
889
|
footer: '๐ท๏ธ๏ธ Pinterest',
|
|
868
890
|
nativeFlow: [{
|
|
869
891
|
text: '๐ Source',
|
|
870
|
-
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
|
892
|
+
url: 'https://www.npmjs.com/package/@itsliaaa/baileys',
|
|
893
|
+
useWebview: true
|
|
871
894
|
}]
|
|
872
895
|
}, {
|
|
873
896
|
image: {
|
|
@@ -897,7 +920,8 @@ sock.sendMessage(jid, {
|
|
|
897
920
|
offerExpiration: Date.now() + 3_600_000,
|
|
898
921
|
nativeFlow: [{
|
|
899
922
|
text: '๐ Product',
|
|
900
|
-
id: '#Product'
|
|
923
|
+
id: '#Product',
|
|
924
|
+
icon: 'default'
|
|
901
925
|
}, {
|
|
902
926
|
text: '๐ Source',
|
|
903
927
|
url: 'https://www.npmjs.com/package/@itsliaaa/baileys'
|
package/lib/Utils/messages.js
CHANGED
|
@@ -82,31 +82,24 @@ const assertColor = async (color) => {
|
|
|
82
82
|
return assertedColor;
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
+
// Lia@Changes 21-04-26 --- Refactor prepareWAMessageMedia function
|
|
85
86
|
export const prepareWAMessageMedia = async (message, options) => {
|
|
86
87
|
const logger = options.logger;
|
|
87
|
-
|
|
88
|
-
for (const key of MEDIA_KEYS) {
|
|
89
|
-
if (key in message) {
|
|
90
|
-
mediaType = key;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
88
|
+
const mediaType = MEDIA_KEYS.find(key => key in message);
|
|
93
89
|
if (!mediaType) {
|
|
94
90
|
throw new Boom('Invalid media type', { statusCode: 400 });
|
|
95
91
|
}
|
|
96
|
-
const uploadData = {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
};
|
|
92
|
+
const uploadData = { ...message };
|
|
93
|
+
const mediaPayload = uploadData[mediaType];
|
|
94
|
+
delete uploadData[mediaType];
|
|
100
95
|
if (uploadData.image || uploadData.video) {
|
|
101
96
|
uploadData.annotations = mediaAnnotation;
|
|
102
97
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
'url' in uploadData.media &&
|
|
107
|
-
!!uploadData.media.url &&
|
|
98
|
+
const cacheableKey = typeof mediaPayload === 'object' &&
|
|
99
|
+
'url' in mediaPayload &&
|
|
100
|
+
!!mediaPayload.url &&
|
|
108
101
|
!!options.mediaCache &&
|
|
109
|
-
mediaType
|
|
102
|
+
`${mediaType}:${mediaPayload.url}`;
|
|
110
103
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
111
104
|
uploadData.fileName = LIBRARY_NAME;
|
|
112
105
|
}
|
|
@@ -119,7 +112,7 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
119
112
|
logger?.debug({ cacheableKey }, 'got media cache hit');
|
|
120
113
|
const obj = proto.Message.decode(mediaBuff);
|
|
121
114
|
const key = `${mediaType}Message`;
|
|
122
|
-
Object.assign(obj[key],
|
|
115
|
+
Object.assign(obj[key], uploadData);
|
|
123
116
|
return obj;
|
|
124
117
|
}
|
|
125
118
|
}
|
|
@@ -129,142 +122,118 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
129
122
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true && typeof uploadData.waveform === 'undefined';
|
|
130
123
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
131
124
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation || requiresWaveformProcessing;
|
|
125
|
+
let mediaUrl,
|
|
126
|
+
directPath,
|
|
127
|
+
thumbnailDirectPath,
|
|
128
|
+
thumbnailSha256,
|
|
129
|
+
fileSha256,
|
|
130
|
+
fileLength,
|
|
131
|
+
mediaKey,
|
|
132
|
+
fileEncSha256;
|
|
132
133
|
// Lia@Changes 06-02-26 --- Add few support for sending media to newsletter (โ โงโ โฝโ โฆโ )
|
|
133
134
|
if (isNewsletter) {
|
|
134
135
|
logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
135
|
-
const
|
|
136
|
+
const rawData = await getRawMediaUploadData(mediaPayload, options.mediaTypeOverride || mediaType, logger);
|
|
137
|
+
fileSha256 = rawData.fileSha256;
|
|
138
|
+
fileLength = rawData.fileLength;
|
|
139
|
+
const filePath = rawData.filePath;
|
|
136
140
|
const fileSha256B64 = fileSha256.toString('base64');
|
|
137
|
-
const [
|
|
138
|
-
(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
});
|
|
145
|
-
logger?.debug({ mediaType, cacheableKey }, 'uploaded media');
|
|
146
|
-
return result;
|
|
147
|
-
})(),
|
|
141
|
+
const [uploadResult] = await Promise.all([
|
|
142
|
+
options.upload(filePath, {
|
|
143
|
+
fileEncSha256B64: fileSha256B64,
|
|
144
|
+
mediaType,
|
|
145
|
+
timeoutMs: options.mediaUploadTimeoutMs,
|
|
146
|
+
newsletter: true
|
|
147
|
+
}),
|
|
148
148
|
(async () => {
|
|
149
149
|
try {
|
|
150
150
|
if (requiresThumbnailComputation) {
|
|
151
151
|
const { thumbnail } = await generateThumbnail(filePath, mediaType, options);
|
|
152
152
|
uploadData.jpegThumbnail = thumbnail;
|
|
153
|
-
logger?.debug('generated thumbnail');
|
|
154
153
|
}
|
|
155
154
|
if (requiresDurationComputation) {
|
|
156
155
|
uploadData.seconds = await getAudioDuration(filePath);
|
|
157
|
-
logger?.debug('computed audio duration');
|
|
158
156
|
}
|
|
159
157
|
}
|
|
160
158
|
catch (error) {
|
|
161
159
|
logger?.warn({ trace: error.stack }, 'failed to obtain extra info');
|
|
162
160
|
}
|
|
163
161
|
})()
|
|
164
|
-
])
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
});
|
|
173
|
-
delete uploadData.media;
|
|
174
|
-
const obj = proto.Message.create({
|
|
175
|
-
// todo: add more support here
|
|
176
|
-
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
177
|
-
url: mediaUrl,
|
|
178
|
-
directPath,
|
|
179
|
-
fileSha256,
|
|
180
|
-
fileLength,
|
|
181
|
-
thumbnailDirectPath,
|
|
182
|
-
thumbnailSha256,
|
|
183
|
-
...uploadData
|
|
184
|
-
})
|
|
185
|
-
});
|
|
186
|
-
if (uploadData.ptv) {
|
|
187
|
-
obj.ptvMessage = obj.videoMessage;
|
|
188
|
-
delete obj.videoMessage;
|
|
189
|
-
}
|
|
190
|
-
if (obj.stickerMessage) {
|
|
191
|
-
obj.stickerMessage.stickerSentTs = Date.now();
|
|
192
|
-
}
|
|
193
|
-
if (cacheableKey) {
|
|
194
|
-
logger?.debug({ cacheableKey }, 'set cache');
|
|
195
|
-
await options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish());
|
|
196
|
-
}
|
|
197
|
-
return obj;
|
|
162
|
+
]);
|
|
163
|
+
// todo: add more support here
|
|
164
|
+
mediaUrl = uploadResult.mediaUrl;
|
|
165
|
+
directPath = uploadResult.directPath;
|
|
166
|
+
thumbnailDirectPath = uploadResult.thumbnailDirectPath;
|
|
167
|
+
thumbnailSha256 = uploadResult.thumbnailSha256;
|
|
168
|
+
fs.unlink(filePath).catch(() => logger?.warn('failed to remove tmp file'));
|
|
198
169
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
170
|
+
else {
|
|
171
|
+
const encryptedData = await encryptedStream(mediaPayload, options.mediaTypeOverride || mediaType, {
|
|
172
|
+
logger,
|
|
173
|
+
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
174
|
+
opts: options.options
|
|
175
|
+
});
|
|
176
|
+
mediaKey = encryptedData.mediaKey;
|
|
177
|
+
fileEncSha256 = encryptedData.fileEncSha256;
|
|
178
|
+
fileSha256 = encryptedData.fileSha256;
|
|
179
|
+
fileLength = encryptedData.fileLength;
|
|
180
|
+
const encFilePath = encryptedData.encFilePath;
|
|
181
|
+
const originalFilePath = encryptedData.originalFilePath;
|
|
182
|
+
const fileEncSha256B64 = fileEncSha256.toString('base64');
|
|
183
|
+
const [uploadResult] = await Promise.all([
|
|
184
|
+
options.upload(encFilePath, {
|
|
208
185
|
fileEncSha256B64,
|
|
209
186
|
mediaType,
|
|
210
187
|
timeoutMs: options.mediaUploadTimeoutMs
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
188
|
+
}),
|
|
189
|
+
(async () => {
|
|
190
|
+
try {
|
|
191
|
+
if (requiresThumbnailComputation) {
|
|
192
|
+
const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, options);
|
|
193
|
+
uploadData.jpegThumbnail = thumbnail;
|
|
194
|
+
if (!uploadData.width && originalImageDimensions) {
|
|
195
|
+
uploadData.width = originalImageDimensions.width;
|
|
196
|
+
uploadData.height = originalImageDimensions.height;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (requiresDurationComputation) {
|
|
200
|
+
uploadData.seconds = await getAudioDuration(originalFilePath);
|
|
201
|
+
}
|
|
202
|
+
if (requiresWaveformProcessing) {
|
|
203
|
+
uploadData.waveform = await getAudioWaveform(originalFilePath, logger);
|
|
204
|
+
}
|
|
205
|
+
if (requiresAudioBackground) {
|
|
206
|
+
uploadData.backgroundArgb = await assertColor(options.backgroundColor);
|
|
224
207
|
}
|
|
225
|
-
logger?.debug('generated thumbnail');
|
|
226
|
-
}
|
|
227
|
-
if (requiresDurationComputation) {
|
|
228
|
-
uploadData.seconds = await getAudioDuration(originalFilePath);
|
|
229
|
-
logger?.debug('computed audio duration');
|
|
230
|
-
}
|
|
231
|
-
if (requiresWaveformProcessing) {
|
|
232
|
-
uploadData.waveform = await getAudioWaveform(originalFilePath, logger);
|
|
233
|
-
logger?.debug('processed waveform');
|
|
234
208
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
logger?.debug('computed backgroundColor audio status');
|
|
209
|
+
catch (error) {
|
|
210
|
+
logger?.warn({ trace: error.stack }, 'failed to obtain extra info');
|
|
238
211
|
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
212
|
+
})()
|
|
213
|
+
]);
|
|
214
|
+
mediaUrl = uploadResult.mediaUrl;
|
|
215
|
+
directPath = uploadResult.directPath;
|
|
216
|
+
fs.unlink(encFilePath).catch(() => logger?.warn('failed to remove tmp file'));
|
|
217
|
+
fs.unlink(originalFilePath).catch(() => logger?.warn('failed to remove tmp file'));
|
|
218
|
+
}
|
|
219
|
+
const messagePayload = {
|
|
220
|
+
url: mediaUrl,
|
|
221
|
+
directPath,
|
|
222
|
+
fileSha256,
|
|
223
|
+
fileLength,
|
|
224
|
+
...uploadData
|
|
225
|
+
};
|
|
226
|
+
if (isNewsletter) {
|
|
227
|
+
messagePayload.thumbnailDirectPath = thumbnailDirectPath;
|
|
228
|
+
messagePayload.thumbnailSha256 = thumbnailSha256;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
messagePayload.mediaKey = mediaKey;
|
|
232
|
+
messagePayload.fileEncSha256 = fileEncSha256;
|
|
233
|
+
messagePayload.mediaKeyTimestamp = unixTimestampSeconds();
|
|
234
|
+
}
|
|
257
235
|
const obj = proto.Message.create({
|
|
258
|
-
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject(
|
|
259
|
-
url: mediaUrl,
|
|
260
|
-
directPath,
|
|
261
|
-
mediaKey,
|
|
262
|
-
fileEncSha256,
|
|
263
|
-
fileSha256,
|
|
264
|
-
fileLength,
|
|
265
|
-
mediaKeyTimestamp: unixTimestampSeconds(),
|
|
266
|
-
...uploadData
|
|
267
|
-
})
|
|
236
|
+
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject(messagePayload)
|
|
268
237
|
});
|
|
269
238
|
if (uploadData.ptv) {
|
|
270
239
|
obj.ptvMessage = obj.videoMessage;
|
|
@@ -274,8 +243,8 @@ export const prepareWAMessageMedia = async (message, options) => {
|
|
|
274
243
|
obj.stickerMessage.stickerSentTs = Date.now();
|
|
275
244
|
}
|
|
276
245
|
if (cacheableKey) {
|
|
277
|
-
logger?.debug({ cacheableKey }, 'set cache');
|
|
278
|
-
|
|
246
|
+
logger?.debug({ cacheableKey }, 'set cache (background)');
|
|
247
|
+
options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish()).catch(() => {});
|
|
279
248
|
}
|
|
280
249
|
return obj;
|
|
281
250
|
};
|
|
@@ -524,8 +493,8 @@ const prepareStickerPackMessage = async (message, options) => {
|
|
|
524
493
|
}
|
|
525
494
|
const content = obj;
|
|
526
495
|
if (cacheableKey) {
|
|
527
|
-
options.logger?.debug({ cacheableKey }, 'set cache');
|
|
528
|
-
|
|
496
|
+
options.logger?.debug({ cacheableKey }, 'set cache (background)');
|
|
497
|
+
options.mediaCache.set(cacheableKey, WAProto.Message.StickerPackMessage.encode(content).finish());
|
|
529
498
|
}
|
|
530
499
|
return WAProto.Message.StickerPackMessage.fromObject(content);
|
|
531
500
|
};
|
|
@@ -590,6 +559,7 @@ const prepareNativeFlowButtons = (message) => {
|
|
|
590
559
|
display_text: buttonText || '๐ Visit',
|
|
591
560
|
url: button.url,
|
|
592
561
|
merchant_url: button.url,
|
|
562
|
+
webview_interaction: button.useWebview,
|
|
593
563
|
icon: buttonIcon
|
|
594
564
|
})
|
|
595
565
|
};
|
|
@@ -1318,6 +1288,12 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1318
1288
|
}
|
|
1319
1289
|
m = { invoiceMessage };
|
|
1320
1290
|
}
|
|
1291
|
+
if (shouldIncludeReportingToken(m)) {
|
|
1292
|
+
m.messageContextInfo = m.messageContextInfo || {};
|
|
1293
|
+
if (!m.messageContextInfo.messageSecret) {
|
|
1294
|
+
m.messageContextInfo.messageSecret = randomBytes(32);
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1321
1297
|
// Lia@Changes 31-01-26 --- Add direct externalAdReply access (no need to create contextInfo first)
|
|
1322
1298
|
if (hasOptionalProperty(message, 'externalAdReply') && !!message.externalAdReply) {
|
|
1323
1299
|
const messageType = Object.keys(m)[0];
|
|
@@ -1335,9 +1311,9 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1335
1311
|
mediaType: content.mediaType || 1,
|
|
1336
1312
|
mediaUrl: content.url,
|
|
1337
1313
|
renderLargerThumbnail: content.largeThumbnail,
|
|
1338
|
-
sourceUrl: content.url
|
|
1314
|
+
sourceUrl: content.url,
|
|
1339
1315
|
thumbnail: content.thumbnail,
|
|
1340
|
-
thumbnailUrl: content.url,
|
|
1316
|
+
thumbnailUrl: content.url + '?update=' + Date.now(),
|
|
1341
1317
|
title: content.title || LIBRARY_NAME
|
|
1342
1318
|
};
|
|
1343
1319
|
delete externalAdReply.subTitle;
|
|
@@ -1433,12 +1409,6 @@ export const generateWAMessageContent = async (message, options) => {
|
|
|
1433
1409
|
}
|
|
1434
1410
|
}
|
|
1435
1411
|
}
|
|
1436
|
-
if (shouldIncludeReportingToken(m)) {
|
|
1437
|
-
m.messageContextInfo = m.messageContextInfo || {};
|
|
1438
|
-
if (!m.messageContextInfo.messageSecret) {
|
|
1439
|
-
m.messageContextInfo.messageSecret = randomBytes(32);
|
|
1440
|
-
}
|
|
1441
|
-
}
|
|
1442
1412
|
return proto.Message.create(m);
|
|
1443
1413
|
};
|
|
1444
1414
|
export const generateWAMessageFromContent = (jid, message, options) => {
|
|
@@ -5,6 +5,7 @@ import { initAuthCreds } from './auth-utils.js';
|
|
|
5
5
|
import { BufferJSON } from './generics.js';
|
|
6
6
|
// Lia@Changes 25-03-26 --- Add useSingleFileAuthState with integrated cache
|
|
7
7
|
const FLUSH_TIMEOUT_MS = 3000;
|
|
8
|
+
// Lia@Note 21-04-26 --- Unstable need enhancement soon!
|
|
8
9
|
export const useSingleFileAuthState = async (fileName) => {
|
|
9
10
|
const cache = new Map();
|
|
10
11
|
let isLoaded,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itsliaaa/baileys",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"description": "Enhanced Baileys v7 with fixed newsletter media upload, plus support for interactive messages, albums, and more message types.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"type": "module",
|