@lordmega/baileys 0.3.23 → 0.3.25
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 +35 -1434
- package/WAProto/index.d.ts +26 -0
- package/WAProto/index.js +203 -0
- package/lib/Defaults/index.d.ts +1 -0
- package/lib/Defaults/index.d.ts.map +1 -1
- package/lib/Defaults/index.js +1 -0
- package/lib/Defaults/index.js.map +1 -1
- package/lib/Signal/libsignal.js +4 -4
- package/lib/Socket/Client/websocket.js +10 -5
- package/lib/Socket/business.d.ts +1 -1
- package/lib/Socket/chats.d.ts +1 -1
- package/lib/Socket/chats.js +8 -6
- package/lib/Socket/chats.js.map +1 -1
- package/lib/Socket/communities.d.ts +1 -1
- package/lib/Socket/communities.js +3 -2
- package/lib/Socket/groups.d.ts +1 -1
- package/lib/Socket/groups.js +24 -8
- package/lib/Socket/index.d.ts +1 -1
- package/lib/Socket/messages-recv.d.ts +1 -1
- package/lib/Socket/messages-recv.js +92 -24
- package/lib/Socket/messages-send.d.ts +2 -1
- package/lib/Socket/messages-send.js +68 -8
- package/lib/Socket/messages-send.js.map +1 -1
- package/lib/Socket/newsletter.d.ts +1 -1
- package/lib/Socket/newsletter.js +28 -1
- package/lib/Socket/socket.js +41 -13
- package/lib/Store/make-in-memory-store.js +7 -2
- package/lib/Utils/browser-utils.d.ts +1 -0
- package/lib/Utils/browser-utils.js +1 -0
- package/lib/Utils/crypto.js +34 -1
- package/lib/Utils/decode-wa-message.d.ts.map +1 -1
- package/lib/Utils/decode-wa-message.js.map +1 -1
- package/lib/Utils/event-buffer.js +19 -2
- package/lib/Utils/generics.js +3 -6
- package/lib/Utils/index.js.map +1 -1
- package/lib/Utils/message-retry-manager.d.ts +1 -0
- package/lib/Utils/message-retry-manager.js +7 -0
- package/lib/Utils/messages-media.js +108 -41
- package/lib/Utils/messages.d.ts.map +1 -1
- package/lib/Utils/messages.js +49 -140
- package/lib/Utils/messages.js.map +1 -1
- package/lib/Utils/process-message.d.ts +1 -0
- package/lib/Utils/process-message.d.ts.map +1 -1
- package/lib/Utils/process-message.js +154 -78
- package/lib/Utils/process-message.js.map +1 -1
- package/lib/Utils/reporting-utils.d.ts +1 -0
- package/lib/Utils/reporting-utils.js +1 -1
- package/lib/Utils/rich-message-utils.d.ts.map +1 -1
- package/lib/Utils/rich-message-utils.js.map +1 -1
- package/lib/Utils/tc-token-utils.js +9 -11
- package/lib/Utils/use-multi-file-auth-state.js +10 -11
- package/lib/Utils/use-single-file-auth-state.js +8 -2
- package/lib/Utils/validate-connection.js +10 -4
- package/lib/WABinary/constants.d.ts.map +1 -1
- package/lib/WABinary/constants.js.map +1 -1
- package/lib/WAUSync/USyncQuery.js +24 -2
- package/package.json +10 -7
- package/lib/Utils/use-sqlite-auth-state.d.ts.map +0 -1
- package/lib/Utils/use-sqlite-auth-state.js.map +0 -1
|
@@ -11,7 +11,7 @@ import { proto } from '../../WAProto/index.js';
|
|
|
11
11
|
import { DEFAULT_ORIGIN, MEDIA_HKDF_KEY_MAPPING, MEDIA_PATH_MAP, NEWSLETTER_MEDIA_PATH_MAP } from '../Defaults/index.js';
|
|
12
12
|
import { getBinaryNodeChild, getBinaryNodeChildBuffer, jidNormalizedUser } from '../WABinary/index.js';
|
|
13
13
|
import { aesDecryptGCM, aesEncryptGCM, hkdf } from './crypto.js';
|
|
14
|
-
import { generateMessageIDV2 } from './generics.js';
|
|
14
|
+
import { delay, generateMessageIDV2 } from './generics.js';
|
|
15
15
|
const getTmpFilesDirectory = () => tmpdir();
|
|
16
16
|
let imageProcessingLibrary;
|
|
17
17
|
export const getImageProcessingLibrary = async () => {
|
|
@@ -621,10 +621,14 @@ export const uploadWithNodeHttp = async ({ url, filePath, headers, timeoutMs, ag
|
|
|
621
621
|
res.on('data', chunk => (body += chunk));
|
|
622
622
|
res.on('end', () => {
|
|
623
623
|
try {
|
|
624
|
-
|
|
624
|
+
const parsed = JSON.parse(body);
|
|
625
|
+
// attach status so caller can log/branch on it
|
|
626
|
+
parsed._status = res.statusCode;
|
|
627
|
+
resolve(parsed);
|
|
625
628
|
}
|
|
626
629
|
catch {
|
|
627
|
-
resolve
|
|
630
|
+
// non-JSON body — resolve with status-only object
|
|
631
|
+
resolve({ _status: res.statusCode, _body: body.substring(0, 200) });
|
|
628
632
|
}
|
|
629
633
|
});
|
|
630
634
|
});
|
|
@@ -656,10 +660,12 @@ const uploadWithFetch = async ({ url, filePath, headers, timeoutMs, agent }) =>
|
|
|
656
660
|
signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined
|
|
657
661
|
});
|
|
658
662
|
try {
|
|
659
|
-
|
|
663
|
+
const parsed = await response.json();
|
|
664
|
+
parsed._status = response.status;
|
|
665
|
+
return parsed;
|
|
660
666
|
}
|
|
661
667
|
catch {
|
|
662
|
-
return
|
|
668
|
+
return { _status: response.status };
|
|
663
669
|
}
|
|
664
670
|
};
|
|
665
671
|
/**
|
|
@@ -692,7 +698,13 @@ const uploadMedia = async (params, logger) => {
|
|
|
692
698
|
export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, options }, refreshMediaConn) => {
|
|
693
699
|
return async (filePath, { mediaType, fileEncSha256B64, timeoutMs, newsletter }) => {
|
|
694
700
|
// send a query JSON to obtain the url & auth token to upload our media
|
|
695
|
-
let uploadInfo
|
|
701
|
+
let uploadInfo;
|
|
702
|
+
try {
|
|
703
|
+
uploadInfo = await refreshMediaConn(false);
|
|
704
|
+
}
|
|
705
|
+
catch (err) {
|
|
706
|
+
throw new Boom(`Media upload failed: cannot fetch media connection (${err?.message})`, { statusCode: 503, data: err });
|
|
707
|
+
}
|
|
696
708
|
let urls;
|
|
697
709
|
const hosts = [...customUploadHosts, ...uploadInfo.hosts];
|
|
698
710
|
fileEncSha256B64 = encodeBase64EncodedStringForUpload(fileEncSha256B64);
|
|
@@ -708,47 +720,102 @@ export const getWAUploadToServer = ({ customUploadHosts, fetchAgent, logger, opt
|
|
|
708
720
|
'Content-Type': 'application/octet-stream',
|
|
709
721
|
Origin: DEFAULT_ORIGIN
|
|
710
722
|
};
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
723
|
+
// deduplicate hosts — WA server sometimes returns same host multiple times
|
|
724
|
+
const seenHosts = new Set();
|
|
725
|
+
const uniqueHosts = hosts.filter(h => {
|
|
726
|
+
if (seenHosts.has(h.hostname)) return false;
|
|
727
|
+
seenHosts.add(h.hostname);
|
|
728
|
+
return true;
|
|
729
|
+
});
|
|
730
|
+
// Lia@Changes 12-06-26 --- mediaConn auth can go stale on long-lived sessions; WA then
|
|
731
|
+
// rejects EVERY host with HTTP 500 (not 401), so plain host-rotation never recovers.
|
|
732
|
+
// Force-refresh once on the first auth-suspect failure and retry the SAME host with fresh auth.
|
|
733
|
+
const AUTH_SUSPECT_STATUS = new Set([401, 403, 408, 500, 502, 503]);
|
|
734
|
+
let refreshedOnce = false;
|
|
735
|
+
// Lia@Changes 06-02-26 --- Switch media path map for newsletter uploads
|
|
736
|
+
const mediaPathMap = newsletter ? NEWSLETTER_MEDIA_PATH_MAP : MEDIA_PATH_MAP;
|
|
737
|
+
const mediaPath = mediaPathMap[mediaType];
|
|
738
|
+
if (!mediaPath && mediaPath !== '') {
|
|
739
|
+
throw new Boom(`Unknown mediaType "${mediaType}" — no upload path defined`, { statusCode: 400 });
|
|
740
|
+
}
|
|
741
|
+
// Lia@Changes 20-03-26 --- Add server thumb for newsletter media.
|
|
742
|
+
// Lia@Changes 12-06-26 --- Gated behind options.newsletterServerThumbGen (default on) so
|
|
743
|
+
// it can be A/B disabled — a non-standard query param is a suspect when newsletter uploads 500.
|
|
744
|
+
const useServerThumb = newsletter && (options?.newsletterServerThumbGen ?? true);
|
|
745
|
+
const serverThumb = useServerThumb ? '&server_thumb_gen=1' : '';
|
|
746
|
+
// Lia@Changes 12-06-26 --- Datacenter/VPS IPs get throttled by the WA media CDN, which
|
|
747
|
+
// surfaces as ALL hosts failing in one pass. Wrap the host sweep in bounded retry ROUNDS
|
|
748
|
+
// with exponential backoff (modeled on whatsmeow's download retry path) so a transient
|
|
749
|
+
// CDN/IP throttle recovers instead of bubbling up a hard "failed on all hosts".
|
|
750
|
+
const maxRounds = Math.max(1, options?.mediaUploadMaxRetries ?? 3);
|
|
751
|
+
for (let round = 0; round < maxRounds && !urls; round++) {
|
|
752
|
+
if (round > 0) {
|
|
753
|
+
// exponential backoff: 1s, 2s, 4s ... capped at 15s
|
|
754
|
+
const backoffMs = Math.min(1000 * Math.pow(2, round - 1), 15000);
|
|
755
|
+
logger.warn({ round, backoffMs }, `all hosts failed, retrying upload round (${round + 1}/${maxRounds}) after backoff`);
|
|
756
|
+
await delay(backoffMs);
|
|
757
|
+
// fresh mediaConn between rounds — auth/host list may have rotated server-side
|
|
758
|
+
try {
|
|
741
759
|
uploadInfo = await refreshMediaConn(true);
|
|
742
|
-
|
|
760
|
+
}
|
|
761
|
+
catch (refreshErr) {
|
|
762
|
+
logger.warn({ trace: refreshErr?.stack }, 'mediaConn refresh between rounds failed');
|
|
743
763
|
}
|
|
744
764
|
}
|
|
745
|
-
|
|
746
|
-
const
|
|
747
|
-
|
|
765
|
+
for (let i = 0; i < uniqueHosts.length && !urls; i++) {
|
|
766
|
+
const { hostname } = uniqueHosts[i];
|
|
767
|
+
const isLast = i === uniqueHosts.length - 1;
|
|
768
|
+
// attempt 0 = first try; attempt 1 = retry same host after a forced mediaConn refresh
|
|
769
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
770
|
+
const auth = encodeURIComponent(uploadInfo.auth);
|
|
771
|
+
const url = `https://${hostname}${mediaPath}/${fileEncSha256B64}?auth=${auth}&token=${fileEncSha256B64}${serverThumb}`;
|
|
772
|
+
logger.debug({ hostname, mediaType, round, attempt, url: url.split('?')[0] }, `uploading to host (${i + 1}/${uniqueHosts.length})`);
|
|
773
|
+
let result;
|
|
774
|
+
try {
|
|
775
|
+
result = await uploadMedia({
|
|
776
|
+
url,
|
|
777
|
+
filePath,
|
|
778
|
+
headers,
|
|
779
|
+
timeoutMs,
|
|
780
|
+
agent: fetchAgent
|
|
781
|
+
}, logger);
|
|
782
|
+
if (result?.url || result?.direct_path) {
|
|
783
|
+
urls = {
|
|
784
|
+
mediaUrl: result.url,
|
|
785
|
+
directPath: result.direct_path,
|
|
786
|
+
meta_hmac: result.meta_hmac,
|
|
787
|
+
fbid: result.fbid,
|
|
788
|
+
ts: result.ts,
|
|
789
|
+
thumbnailDirectPath: result.thumbnail_info?.thumbnail_direct_path,
|
|
790
|
+
thumbnailSha256: result.thumbnail_info?.thumbnail_sha256
|
|
791
|
+
};
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
throw new Error(`upload failed, status=${result?._status ?? 'unknown'}, reason: ${JSON.stringify(result)}`);
|
|
795
|
+
}
|
|
796
|
+
catch (error) {
|
|
797
|
+
const status = result?._status;
|
|
798
|
+
// Stale auth often surfaces as a 5xx/408, not just 401/403. Refresh once globally,
|
|
799
|
+
// then immediately retry THIS host with the new token before giving up on it.
|
|
800
|
+
if (!refreshedOnce && AUTH_SUSPECT_STATUS.has(status) && attempt === 0) {
|
|
801
|
+
refreshedOnce = true;
|
|
802
|
+
try {
|
|
803
|
+
uploadInfo = await refreshMediaConn(true);
|
|
804
|
+
logger.warn({ hostname, status }, 'mediaConn refreshed after auth-suspect failure, retrying same host');
|
|
805
|
+
continue; // retry same host, attempt 1
|
|
806
|
+
}
|
|
807
|
+
catch (refreshErr) {
|
|
808
|
+
logger.warn({ trace: refreshErr?.stack }, 'mediaConn refresh failed');
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
logger.warn({ trace: error?.stack, uploadResult: result, status }, `Error uploading to ${hostname}${isLast ? ' (last host this round)' : ', retrying next host...'}`);
|
|
812
|
+
break; // move to next host
|
|
813
|
+
}
|
|
814
|
+
}
|
|
748
815
|
}
|
|
749
816
|
}
|
|
750
817
|
if (!urls) {
|
|
751
|
-
throw new Boom(
|
|
818
|
+
throw new Boom(`Media upload failed on all hosts after ${maxRounds} round(s) (${uniqueHosts.map(h => h.hostname).join(', ')})`, { statusCode: 500 });
|
|
752
819
|
}
|
|
753
820
|
return urls;
|
|
754
821
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/Utils/messages.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/Utils/messages.js"],"names":[],"mappings":"AAgnDA;;;;;GAKG;AACH;;;qBAgCC;AACD;;;;;GAKG;AACH;;qBAgBC;AApnDM,mDAA+D;AAC/D,qGAYN;AAeM,0FAmKN;AAuTM,kGAaN;AAMM,oFAwBN;AACM,uEAKN;AACM,iEAKN;AAEM,sDAGN;AACM,6DAMN;AAEM,0DAIN;AACM,mFAixBN;AACM,yGA4EN;AACM,uGAQN;AAEM,iEAMN;AAOM,2DA0CN;AAKM,yDAkCN;AAIM,sFAQoB;AAEpB,uEASN;AAEM,yEAMN;AAEM,yEAON;AAEM,4EAKN;AAgEM,gEAgBN;AAKM,oGA8CN;AAEM,sDAWN;AAkEM,8DAUN;sBAt0DqB,wBAAwB"}
|