@badzz88/baileys 8.5.6 → 8.5.8
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 +337 -1055
- package/WAProto/WAProto.proto +28 -1189
- package/WAProto/fix-imports.js +79 -69
- package/WAProto/index.d.ts +71491 -15254
- package/WAProto/index.js +126436 -19814
- package/engine-requirements.js +8 -15
- package/lib/Defaults/index.js +130 -0
- package/{src → lib}/Signal/Group/ciphertext-message.js +2 -5
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/{src → lib}/Signal/Group/group_cipher.js +11 -11
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +18 -0
- package/{src → lib}/Signal/Group/sender-chain-key.js +6 -9
- package/{src → lib}/Signal/Group/sender-key-distribution-message.js +6 -9
- package/{src → lib}/Signal/Group/sender-key-message.js +9 -12
- package/{src → lib}/Signal/Group/sender-key-name.js +2 -5
- package/{src → lib}/Signal/Group/sender-key-record.js +8 -11
- package/{src → lib}/Signal/Group/sender-key-state.js +6 -9
- package/lib/Signal/Group/sender-message-key.js +26 -0
- package/{src → lib}/Signal/libsignal.js +131 -155
- package/{src → lib}/Signal/lid-mapping.js +27 -23
- package/lib/Socket/Client/index.js +3 -0
- package/lib/Socket/Client/types.js +11 -0
- package/{src → lib}/Socket/Client/websocket.js +11 -18
- package/{src → lib}/Socket/business.js +35 -67
- package/{src → lib}/Socket/chats.js +294 -550
- package/{src → lib}/Socket/communities.js +82 -114
- package/lib/Socket/graphql.js +716 -0
- package/lib/Socket/groups.js +374 -0
- package/lib/Socket/index.js +18 -0
- package/lib/Socket/interop.js +463 -0
- package/{src → lib}/Socket/luxu.js +120 -82
- package/lib/Socket/messages-recv.js +1916 -0
- package/lib/Socket/messages-send.js +1436 -0
- package/lib/Socket/mex.js +54 -0
- package/lib/Socket/newsletter.js +757 -0
- package/lib/Socket/privacy.js +318 -0
- package/{src → lib}/Socket/socket.js +356 -244
- package/lib/Socket/username.js +236 -0
- package/lib/Store/index.js +10 -0
- package/{src → lib}/Store/keyed-db.js +11 -21
- package/lib/Store/make-cache-manager-store.js +85 -0
- package/lib/Store/make-in-memory-store.js +244 -0
- package/{src → lib}/Store/make-ordered-dictionary.js +19 -25
- package/{src → lib}/Store/object-repository.js +11 -5
- package/lib/Types/Auth.js +2 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Chat.js +8 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/Label.js +25 -0
- package/lib/Types/LabelAssociation.js +7 -0
- package/lib/Types/Message.js +11 -0
- package/lib/Types/Mex.js +111 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Socket.js +3 -0
- package/lib/Types/State.js +56 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.js +26 -0
- package/{src → lib}/Utils/auth-utils.js +91 -43
- package/lib/Utils/browser-utils.js +48 -0
- package/lib/Utils/business.js +231 -0
- package/lib/Utils/chat-utils.js +872 -0
- package/lib/Utils/companion-reg-client-utils.js +35 -0
- package/lib/Utils/crypto.js +118 -0
- package/lib/Utils/decode-wa-message.js +350 -0
- package/{src → lib}/Utils/event-buffer.js +81 -39
- package/lib/Utils/generics.js +403 -0
- package/lib/Utils/history.js +134 -0
- package/{src → lib}/Utils/identity-change-handler.js +9 -11
- package/lib/Utils/index.js +23 -0
- package/lib/Utils/link-preview.js +85 -0
- package/lib/Utils/logger.js +3 -0
- package/lib/Utils/lt-hash.js +8 -0
- package/{src → lib}/Utils/make-mutex.js +7 -10
- package/lib/Utils/message-composer.js +273 -0
- package/{src → lib}/Utils/message-retry-manager.js +76 -28
- package/lib/Utils/messages-media.js +870 -0
- package/lib/Utils/messages.js +1337 -0
- package/lib/Utils/noise-handler.js +201 -0
- package/{src → lib}/Utils/offline-node-processor.js +10 -4
- package/{src → lib}/Utils/pre-key-manager.js +27 -11
- package/lib/Utils/process-message.js +630 -0
- package/{src → lib}/Utils/reporting-utils.js +12 -15
- package/lib/Utils/signal.js +201 -0
- package/{src → lib}/Utils/stanza-ack.js +12 -4
- package/lib/Utils/sticker.js +110 -0
- package/{src → lib}/Utils/sync-action-utils.js +14 -10
- package/{src → lib}/Utils/tc-token-utils.js +48 -43
- package/{src → lib}/Utils/use-multi-file-auth-state.js +35 -25
- package/lib/Utils/validate-connection.js +203 -0
- package/{src → lib}/WABinary/constants.js +9 -12
- package/{src → lib}/WABinary/decode.js +38 -118
- package/{src → lib}/WABinary/encode.js +6 -11
- package/lib/WABinary/generic-utils.js +204 -0
- package/lib/WABinary/index.js +6 -0
- package/lib/WABinary/jid-utils.js +98 -0
- package/lib/WABinary/types.js +2 -0
- package/{src → lib}/WAM/BinaryInfo.js +2 -5
- package/{src → lib}/WAM/constants.js +4 -16635
- package/{src → lib}/WAM/encode.js +18 -17
- package/lib/WAM/index.js +4 -0
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +53 -0
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +54 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +57 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +58 -0
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +30 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +28 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +39 -0
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +27 -0
- package/lib/WAUSync/Protocols/index.js +12 -0
- package/lib/WAUSync/USyncQuery.js +151 -0
- package/lib/WAUSync/USyncUser.js +56 -0
- package/lib/WAUSync/index.js +3 -0
- package/{src → lib}/index.js +16 -51
- package/package.json +129 -99
- package/LICENSE +0 -21
- package/src/Defaults/index.js +0 -186
- package/src/Defaults/phonenumber-mcc.json +0 -223
- package/src/Signal/Group/group-session-builder.js +0 -86
- package/src/Signal/Group/index.js +0 -140
- package/src/Signal/Group/keyhelper.js +0 -77
- package/src/Signal/Group/sender-message-key.js +0 -29
- package/src/Socket/Client/index.js +0 -31
- package/src/Socket/Client/types.js +0 -13
- package/src/Socket/aigroups.js +0 -221
- package/src/Socket/graphql.js +0 -523
- package/src/Socket/groups.js +0 -516
- package/src/Socket/index.js +0 -31
- package/src/Socket/interactive-handler.js +0 -527
- package/src/Socket/interop.js +0 -339
- package/src/Socket/managed-account.js +0 -98
- package/src/Socket/messages-recv.js +0 -2685
- package/src/Socket/messages-send.js +0 -2047
- package/src/Socket/mex.js +0 -57
- package/src/Socket/newsletter.js +0 -455
- package/src/Socket/privacy.js +0 -125
- package/src/Socket/registration.js +0 -236
- package/src/Socket/text-router.js +0 -65
- package/src/Socket/username.js +0 -130
- package/src/Store/index.js +0 -33
- package/src/Store/make-cache-manager-store.js +0 -84
- package/src/Store/make-in-memory-store.js +0 -551
- package/src/Types/Auth.js +0 -31
- package/src/Types/Bussines.js +0 -2
- package/src/Types/Call.js +0 -2
- package/src/Types/Chat.js +0 -4
- package/src/Types/Contact.js +0 -2
- package/src/Types/Events.js +0 -2
- package/src/Types/GroupMetadata.js +0 -2
- package/src/Types/Label.js +0 -26
- package/src/Types/LabelAssociation.js +0 -8
- package/src/Types/Message.js +0 -93
- package/src/Types/Mex.js +0 -112
- package/src/Types/Newsletter.js +0 -109
- package/src/Types/Product.js +0 -2
- package/src/Types/Signal.js +0 -2
- package/src/Types/Socket.js +0 -2
- package/src/Types/State.js +0 -62
- package/src/Types/USync.js +0 -2
- package/src/Types/index.js +0 -56
- package/src/Utils/browser-utils.js +0 -112
- package/src/Utils/business.js +0 -240
- package/src/Utils/chat-utils.js +0 -1230
- package/src/Utils/command-loader.d.ts +0 -27
- package/src/Utils/command-loader.js +0 -89
- package/src/Utils/companion-reg-client-utils.js +0 -40
- package/src/Utils/consumer-application.js +0 -105
- package/src/Utils/crypto.js +0 -118
- package/src/Utils/curve25519-js.js +0 -242
- package/src/Utils/decode-wa-message.js +0 -529
- package/src/Utils/generics.js +0 -483
- package/src/Utils/group-history.js +0 -44
- package/src/Utils/history.js +0 -232
- package/src/Utils/index.js +0 -58
- package/src/Utils/jid-display-normalization.js +0 -195
- package/src/Utils/link-preview.js +0 -135
- package/src/Utils/logger.js +0 -8
- package/src/Utils/lt-hash.js +0 -25
- package/src/Utils/message-composer.js +0 -471
- package/src/Utils/messages-media.js +0 -843
- package/src/Utils/messages.js +0 -2817
- package/src/Utils/meta-ai-msmsg.js +0 -222
- package/src/Utils/native-bridge.js +0 -68
- package/src/Utils/noise-handler.js +0 -169
- package/src/Utils/process-message.js +0 -950
- package/src/Utils/session-pool.d.ts +0 -14
- package/src/Utils/session-pool.js +0 -70
- package/src/Utils/signal.js +0 -217
- package/src/Utils/sticker.d.ts +0 -13
- package/src/Utils/sticker.js +0 -123
- package/src/Utils/validate-connection.js +0 -209
- package/src/Utils/view-once-cache.d.ts +0 -12
- package/src/Utils/view-once-cache.js +0 -63
- package/src/Utils/voip-rekey.js +0 -22
- package/src/WABinary/generic-utils.js +0 -238
- package/src/WABinary/index.js +0 -34
- package/src/WABinary/jid-utils.js +0 -351
- package/src/WABinary/types.js +0 -2
- package/src/WAM/index.js +0 -32
- package/src/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -53
- package/src/WAUSync/Protocols/USyncBusinessProtocol.js +0 -44
- package/src/WAUSync/Protocols/USyncContactProtocol.js +0 -55
- package/src/WAUSync/Protocols/USyncDeviceProtocol.js +0 -55
- package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -31
- package/src/WAUSync/Protocols/USyncFeatureProtocol.js +0 -54
- package/src/WAUSync/Protocols/USyncLIDProtocol.js +0 -32
- package/src/WAUSync/Protocols/USyncNewsletterProtocol.js +0 -473
- package/src/WAUSync/Protocols/USyncPictureProtocol.js +0 -34
- package/src/WAUSync/Protocols/USyncSidelistProtocol.js +0 -29
- package/src/WAUSync/Protocols/USyncStatusProtocol.js +0 -42
- package/src/WAUSync/Protocols/USyncTextStatusProtocol.js +0 -38
- package/src/WAUSync/Protocols/USyncUsernameProtocol.js +0 -28
- package/src/WAUSync/Protocols/index.js +0 -40
- package/src/WAUSync/USyncQuery.js +0 -126
- package/src/WAUSync/USyncUser.js +0 -50
- package/src/WAUSync/index.js +0 -32
- package/src/antiban.js +0 -4152
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LTHashAntiTampering } from 'whatsapp-rust-bridge';
|
|
2
|
+
/**
|
|
3
|
+
* LT Hash is a summation based hash algorithm that maintains the integrity of a piece of data
|
|
4
|
+
* over a series of mutations. You can add/remove mutations and it'll return a hash equal to
|
|
5
|
+
* if the same series of mutations was made sequentially.
|
|
6
|
+
*/
|
|
7
|
+
export const LT_HASH_ANTI_TAMPERING = new LTHashAntiTampering();
|
|
8
|
+
//# sourceMappingURL=lt-hash.js.map
|
|
@@ -1,23 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const async_mutex_1 = require('async-mutex');
|
|
5
|
-
const makeMutex = () => {
|
|
6
|
-
const mutex = new async_mutex_1.Mutex();
|
|
1
|
+
import { Mutex as AsyncMutex } from 'async-mutex';
|
|
2
|
+
export const makeMutex = () => {
|
|
3
|
+
const mutex = new AsyncMutex();
|
|
7
4
|
return {
|
|
8
5
|
mutex(code) {
|
|
9
6
|
return mutex.runExclusive(code);
|
|
10
7
|
}
|
|
11
8
|
};
|
|
12
9
|
};
|
|
13
|
-
|
|
14
|
-
const makeKeyedMutex = () => {
|
|
10
|
+
export const makeKeyedMutex = () => {
|
|
15
11
|
const map = new Map();
|
|
16
12
|
return {
|
|
17
13
|
async mutex(key, task) {
|
|
18
14
|
let entry = map.get(key);
|
|
19
15
|
if (!entry) {
|
|
20
|
-
entry = { mutex: new
|
|
16
|
+
entry = { mutex: new AsyncMutex(), refCount: 0 };
|
|
21
17
|
map.set(key, entry);
|
|
22
18
|
}
|
|
23
19
|
entry.refCount++;
|
|
@@ -26,6 +22,7 @@ const makeKeyedMutex = () => {
|
|
|
26
22
|
}
|
|
27
23
|
finally {
|
|
28
24
|
entry.refCount--;
|
|
25
|
+
// only delete it if this is still the current entry
|
|
29
26
|
if (entry.refCount === 0 && map.get(key) === entry) {
|
|
30
27
|
map.delete(key);
|
|
31
28
|
}
|
|
@@ -33,4 +30,4 @@ const makeKeyedMutex = () => {
|
|
|
33
30
|
}
|
|
34
31
|
};
|
|
35
32
|
};
|
|
36
|
-
|
|
33
|
+
//# sourceMappingURL=make-mutex.js.map
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { proto } from '../../WAProto/index.js'
|
|
2
|
+
import { generateMessageIDV2 } from './generics.js'
|
|
3
|
+
|
|
4
|
+
const JS_KEYWORDS = new Set([
|
|
5
|
+
'import', 'export', 'from', 'default', 'as', 'const', 'let', 'var',
|
|
6
|
+
'function', 'class', 'extends', 'new', 'return', 'if', 'else', 'for',
|
|
7
|
+
'while', 'do', 'switch', 'case', 'break', 'continue', 'try', 'catch',
|
|
8
|
+
'finally', 'throw', 'async', 'await', 'yield', 'typeof', 'instanceof',
|
|
9
|
+
'in', 'of', 'delete', 'void', 'true', 'false', 'null', 'undefined',
|
|
10
|
+
'NaN', 'Infinity', 'this', 'super', 'static', 'get', 'set', 'debugger', 'with'
|
|
11
|
+
])
|
|
12
|
+
|
|
13
|
+
const PYTHON_KEYWORDS = new Set([
|
|
14
|
+
'import', 'from', 'as', 'def', 'class', 'return', 'if', 'elif', 'else',
|
|
15
|
+
'for', 'while', 'break', 'continue', 'try', 'except', 'finally', 'raise',
|
|
16
|
+
'with', 'yield', 'lambda', 'pass', 'del', 'global', 'nonlocal', 'assert',
|
|
17
|
+
'True', 'False', 'None', 'and', 'or', 'not', 'in', 'is', 'async', 'await',
|
|
18
|
+
'self', 'print'
|
|
19
|
+
])
|
|
20
|
+
|
|
21
|
+
const LANGUAGE_KEYWORDS = {
|
|
22
|
+
javascript: JS_KEYWORDS,
|
|
23
|
+
typescript: JS_KEYWORDS,
|
|
24
|
+
js: JS_KEYWORDS,
|
|
25
|
+
ts: JS_KEYWORDS,
|
|
26
|
+
python: PYTHON_KEYWORDS,
|
|
27
|
+
py: PYTHON_KEYWORDS
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export var CodeHighlightType
|
|
31
|
+
;(function (CodeHighlightType) {
|
|
32
|
+
CodeHighlightType[(CodeHighlightType['DEFAULT'] = 0)] = 'DEFAULT'
|
|
33
|
+
CodeHighlightType[(CodeHighlightType['KEYWORD'] = 1)] = 'KEYWORD'
|
|
34
|
+
CodeHighlightType[(CodeHighlightType['METHOD'] = 2)] = 'METHOD'
|
|
35
|
+
CodeHighlightType[(CodeHighlightType['STRING'] = 3)] = 'STRING'
|
|
36
|
+
CodeHighlightType[(CodeHighlightType['NUMBER'] = 4)] = 'NUMBER'
|
|
37
|
+
CodeHighlightType[(CodeHighlightType['COMMENT'] = 5)] = 'COMMENT'
|
|
38
|
+
})(CodeHighlightType || (CodeHighlightType = {}))
|
|
39
|
+
|
|
40
|
+
export var RichSubMessageType
|
|
41
|
+
;(function (RichSubMessageType) {
|
|
42
|
+
RichSubMessageType[(RichSubMessageType['UNKNOWN'] = 0)] = 'UNKNOWN'
|
|
43
|
+
RichSubMessageType[(RichSubMessageType['GRID_IMAGE'] = 1)] = 'GRID_IMAGE'
|
|
44
|
+
RichSubMessageType[(RichSubMessageType['TEXT'] = 2)] = 'TEXT'
|
|
45
|
+
RichSubMessageType[(RichSubMessageType['INLINE_IMAGE'] = 3)] = 'INLINE_IMAGE'
|
|
46
|
+
RichSubMessageType[(RichSubMessageType['TABLE'] = 4)] = 'TABLE'
|
|
47
|
+
RichSubMessageType[(RichSubMessageType['CODE'] = 5)] = 'CODE'
|
|
48
|
+
RichSubMessageType[(RichSubMessageType['DYNAMIC'] = 6)] = 'DYNAMIC'
|
|
49
|
+
RichSubMessageType[(RichSubMessageType['MAP'] = 7)] = 'MAP'
|
|
50
|
+
RichSubMessageType[(RichSubMessageType['LATEX'] = 8)] = 'LATEX'
|
|
51
|
+
RichSubMessageType[(RichSubMessageType['CONTENT_ITEMS'] = 9)] = 'CONTENT_ITEMS'
|
|
52
|
+
})(RichSubMessageType || (RichSubMessageType = {}))
|
|
53
|
+
|
|
54
|
+
export const tokenizeCode = (codeStr, language = 'javascript') => {
|
|
55
|
+
const keywords = LANGUAGE_KEYWORDS[language] || JS_KEYWORDS
|
|
56
|
+
const blocks = []
|
|
57
|
+
const lines = codeStr.split('\n')
|
|
58
|
+
for (let li = 0; li < lines.length; li++) {
|
|
59
|
+
const line = lines[li]
|
|
60
|
+
const isLast = li === lines.length - 1
|
|
61
|
+
const nl = isLast? '' : '\n'
|
|
62
|
+
if (!line.trim()) {
|
|
63
|
+
blocks.push({ highlightType: CodeHighlightType.DEFAULT, codeContent: line + nl })
|
|
64
|
+
continue
|
|
65
|
+
}
|
|
66
|
+
if (line.trim().startsWith('//') || line.trim().startsWith('#')) {
|
|
67
|
+
blocks.push({ highlightType: CodeHighlightType.COMMENT, codeContent: line + nl })
|
|
68
|
+
continue
|
|
69
|
+
}
|
|
70
|
+
const regex = /(\/\/.*$|#.*$)|(["'`](?:[^"'`\\]|\\.)*["'`])|(\b\d+(?:\.\d+)?\b)|(\b[a-zA-Z_$][\w$]*\b)|([^\s\w$"'`]+)|(\s+)/g
|
|
71
|
+
let match
|
|
72
|
+
const tokens = []
|
|
73
|
+
while ((match = regex.exec(line))!== null) {
|
|
74
|
+
const val = match[0]
|
|
75
|
+
if (match[1]) {
|
|
76
|
+
tokens.push({ highlightType: CodeHighlightType.COMMENT, codeContent: val })
|
|
77
|
+
} else if (match[2]) {
|
|
78
|
+
tokens.push({ highlightType: CodeHighlightType.STRING, codeContent: val })
|
|
79
|
+
} else if (match[3]) {
|
|
80
|
+
tokens.push({ highlightType: CodeHighlightType.NUMBER, codeContent: val })
|
|
81
|
+
} else if (match[4]) {
|
|
82
|
+
if (keywords.has(val)) {
|
|
83
|
+
tokens.push({ highlightType: CodeHighlightType.KEYWORD, codeContent: val })
|
|
84
|
+
} else {
|
|
85
|
+
const after = line.slice(regex.lastIndex).trimStart()
|
|
86
|
+
if (after.startsWith('(')) {
|
|
87
|
+
tokens.push({ highlightType: CodeHighlightType.METHOD, codeContent: val })
|
|
88
|
+
} else {
|
|
89
|
+
tokens.push({ highlightType: CodeHighlightType.DEFAULT, codeContent: val })
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
tokens.push({ highlightType: CodeHighlightType.DEFAULT, codeContent: val })
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (tokens.length === 0) {
|
|
97
|
+
blocks.push({ highlightType: CodeHighlightType.DEFAULT, codeContent: line + nl })
|
|
98
|
+
continue
|
|
99
|
+
}
|
|
100
|
+
const merged = []
|
|
101
|
+
for (const t of tokens) {
|
|
102
|
+
const prev = merged.length > 0? merged[merged.length - 1] : undefined
|
|
103
|
+
if (prev && prev.highlightType === t.highlightType) {
|
|
104
|
+
prev.codeContent += t.codeContent
|
|
105
|
+
} else {
|
|
106
|
+
merged.push({...t })
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (merged.length > 0) {
|
|
110
|
+
merged[merged.length - 1].codeContent += nl
|
|
111
|
+
}
|
|
112
|
+
blocks.push(...merged)
|
|
113
|
+
}
|
|
114
|
+
return blocks
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export const buildRichContextInfo = (quoted, options) => {
|
|
118
|
+
const ctxInfo = {
|
|
119
|
+
forwardingScore: 1,
|
|
120
|
+
isForwarded: true,
|
|
121
|
+
forwardedAiBotMessageInfo: { botJid: options?.botJid? options.botJid : '867051314767696@bot' },
|
|
122
|
+
forwardOrigin: 4,
|
|
123
|
+
...(options?.mentions? { mentionedJid: options.mentions } : {})
|
|
124
|
+
}
|
|
125
|
+
if (quoted?.key) {
|
|
126
|
+
ctxInfo.stanzaId = quoted.key.id
|
|
127
|
+
ctxInfo.participant = quoted.key.participant || quoted.sender || quoted.key.remoteJid
|
|
128
|
+
ctxInfo.quotedMessage = quoted.message
|
|
129
|
+
}
|
|
130
|
+
return ctxInfo
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export const buildBotForwardedMessage = (submessages, contextInfo, unifiedResponse) => {
|
|
134
|
+
const richResponse = { messageType: 1, submessages, contextInfo }
|
|
135
|
+
if (unifiedResponse) {
|
|
136
|
+
richResponse.unifiedResponse = unifiedResponse
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
botForwardedMessage: {
|
|
140
|
+
message: { richResponseMessage: richResponse }
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const generateTableContent = (title, headers, rows, quoted, options = {}) => {
|
|
146
|
+
const { footer, headerText } = options
|
|
147
|
+
const tableRows = [{ items: headers, isHeading: true },...rows.map(row => ({ items: row.map(String) }))]
|
|
148
|
+
const submessages = []
|
|
149
|
+
if (headerText) submessages.push({ messageType: 2, messageText: headerText })
|
|
150
|
+
submessages.push({ messageType: 4, tableMetadata: { title, rows: tableRows } })
|
|
151
|
+
if (footer) submessages.push({ messageType: 2, messageText: footer })
|
|
152
|
+
const ctxInfo = buildRichContextInfo(quoted)
|
|
153
|
+
return { message: buildBotForwardedMessage(submessages, ctxInfo), messageId: generateMessageIDV2() }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export const generateListContent = (title, items, quoted, options = {}) => {
|
|
157
|
+
const { footer, headerText } = options
|
|
158
|
+
const tableRows = items.map(item => ({
|
|
159
|
+
items: Array.isArray(item)? item.map(String) : [String(item)]
|
|
160
|
+
}))
|
|
161
|
+
const submessages = []
|
|
162
|
+
if (headerText) submessages.push({ messageType: 2, messageText: headerText })
|
|
163
|
+
submessages.push({ messageType: 4, tableMetadata: { title, rows: tableRows } })
|
|
164
|
+
if (footer) submessages.push({ messageType: 2, messageText: footer })
|
|
165
|
+
const ctxInfo = buildRichContextInfo(quoted)
|
|
166
|
+
return { message: buildBotForwardedMessage(submessages, ctxInfo), messageId: generateMessageIDV2() }
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export const generateCodeBlockContent = (code, quoted, options = {}) => {
|
|
170
|
+
const { title, footer, language = 'javascript' } = options
|
|
171
|
+
const submessages = []
|
|
172
|
+
if (title) submessages.push({ messageType: 2, messageText: title })
|
|
173
|
+
submessages.push({
|
|
174
|
+
messageType: 5,
|
|
175
|
+
codeMetadata: { codeLanguage: language, codeBlocks: tokenizeCode(code, language) }
|
|
176
|
+
})
|
|
177
|
+
if (footer) submessages.push({ messageType: 2, messageText: footer })
|
|
178
|
+
const ctxInfo = buildRichContextInfo(quoted)
|
|
179
|
+
return { message: buildBotForwardedMessage(submessages, ctxInfo), messageId: generateMessageIDV2() }
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export const generateLatexContent = (quoted, options) => {
|
|
183
|
+
const { text, expressions, headerText, footer } = options
|
|
184
|
+
const submessages = []
|
|
185
|
+
if (headerText) submessages.push({ messageType: 2, messageText: headerText })
|
|
186
|
+
const latexExpressions = expressions.map(expr => {
|
|
187
|
+
const entry = {
|
|
188
|
+
latexExpression: expr.latexExpression,
|
|
189
|
+
url: expr.url,
|
|
190
|
+
width: expr.width,
|
|
191
|
+
height: expr.height
|
|
192
|
+
}
|
|
193
|
+
if (expr.fontHeight!== undefined) entry.fontHeight = expr.fontHeight
|
|
194
|
+
if (expr.imageTopPadding!== undefined) entry.imageTopPadding = expr.imageTopPadding
|
|
195
|
+
if (expr.imageLeadingPadding!== undefined) entry.imageLeadingPadding = expr.imageLeadingPadding
|
|
196
|
+
if (expr.imageBottomPadding!== undefined) entry.imageBottomPadding = expr.imageBottomPadding
|
|
197
|
+
if (expr.imageTrailingPadding!== undefined) entry.imageTrailingPadding = expr.imageTrailingPadding
|
|
198
|
+
return entry
|
|
199
|
+
})
|
|
200
|
+
submessages.push({ messageType: 8, latexMetadata: { text: text || '', expressions: latexExpressions } })
|
|
201
|
+
if (footer) submessages.push({ messageType: 2, messageText: footer })
|
|
202
|
+
const ctxInfo = buildRichContextInfo(quoted)
|
|
203
|
+
return { message: buildBotForwardedMessage(submessages, ctxInfo), messageId: generateMessageIDV2() }
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export const generateLatexImageContent = async (quoted, options, uploadFn, renderLatexToPng) => {
|
|
207
|
+
const { text, expressions, headerText, footer } = options
|
|
208
|
+
const submessages = []
|
|
209
|
+
if (headerText) submessages.push({ messageType: 2, messageText: headerText })
|
|
210
|
+
const latexExpressions = await Promise.all(
|
|
211
|
+
expressions.map(async expr => {
|
|
212
|
+
const { buffer, width, height } = await renderLatexToPng(expr.latexExpression)
|
|
213
|
+
const uploadResult = await uploadFn(buffer, 'image')
|
|
214
|
+
const imageUrl = uploadResult.url || uploadResult.directPath
|
|
215
|
+
return { latexExpression: expr.latexExpression, url: imageUrl, width, height }
|
|
216
|
+
})
|
|
217
|
+
)
|
|
218
|
+
submessages.push({ messageType: 8, latexMetadata: { text: text || '', expressions: latexExpressions } })
|
|
219
|
+
if (footer) submessages.push({ messageType: 2, messageText: footer })
|
|
220
|
+
const ctxInfo = buildRichContextInfo(quoted)
|
|
221
|
+
return { message: buildBotForwardedMessage(submessages, ctxInfo), messageId: generateMessageIDV2() }
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export const generateLatexInlineImageContent = async (quoted, options, uploadFn, renderLatexToPng) => {
|
|
225
|
+
const { text, expressions, headerText, footer } = options
|
|
226
|
+
const submessages = []
|
|
227
|
+
if (headerText) submessages.push({ messageType: 2, messageText: headerText })
|
|
228
|
+
if (text) submessages.push({ messageType: 2, messageText: text })
|
|
229
|
+
for (const expr of expressions) {
|
|
230
|
+
const { buffer, width, height } = await renderLatexToPng(expr.latexExpression)
|
|
231
|
+
const uploadResult = await uploadFn(buffer, 'image')
|
|
232
|
+
const imageUrl = uploadResult.url || uploadResult.directPath
|
|
233
|
+
submessages.push({
|
|
234
|
+
messageType: 3,
|
|
235
|
+
imageMetadata: {
|
|
236
|
+
imageUrl: { imagePreviewUrl: imageUrl, imageHighResUrl: imageUrl },
|
|
237
|
+
imageText: expr.latexExpression,
|
|
238
|
+
alignment: 2
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
if (footer) submessages.push({ messageType: 2, messageText: footer })
|
|
243
|
+
const ctxInfo = buildRichContextInfo(quoted)
|
|
244
|
+
return { message: buildBotForwardedMessage(submessages, ctxInfo), messageId: generateMessageIDV2() }
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export const captureUnifiedResponse = msg => {
|
|
248
|
+
const botFwd = msg?.botForwardedMessage?.message
|
|
249
|
+
if (!botFwd) return null
|
|
250
|
+
const rich = botFwd.richResponseMessage
|
|
251
|
+
if (!rich?.unifiedResponse?.data) return null
|
|
252
|
+
return {
|
|
253
|
+
unifiedResponse: { data: rich.unifiedResponse.data },
|
|
254
|
+
submessages: rich.submessages || [],
|
|
255
|
+
contextInfo: rich.contextInfo || {}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export const generateUnifiedResponseContent = (quoted, captured) => {
|
|
260
|
+
const ctxInfo = buildRichContextInfo(quoted)
|
|
261
|
+
return { message: buildBotForwardedMessage(captured.submessages, ctxInfo, captured.unifiedResponse), messageId: generateMessageIDV2() }
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export const generateRichMessageContent = (submessages, quoted, options) => {
|
|
265
|
+
const ctxInfo = buildRichContextInfo(quoted, options)
|
|
266
|
+
return { message: buildBotForwardedMessage(submessages, ctxInfo), messageId: generateMessageIDV2() }
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export {
|
|
270
|
+
JS_KEYWORDS,
|
|
271
|
+
PYTHON_KEYWORDS,
|
|
272
|
+
LANGUAGE_KEYWORDS
|
|
273
|
+
}
|
|
@@ -1,33 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.MessageRetryManager = exports.RetryReason = void 0;
|
|
4
|
-
const lru_cache_1 = require('lru-cache');
|
|
1
|
+
import { LRUCache } from 'lru-cache';
|
|
2
|
+
/** Number of sent messages to cache in memory for handling retry receipts */
|
|
5
3
|
const RECENT_MESSAGES_SIZE = 512;
|
|
6
4
|
const MESSAGE_KEY_SEPARATOR = '\u0000';
|
|
7
|
-
|
|
5
|
+
/** Timeout for session recreation - 1 hour */
|
|
6
|
+
const RECREATE_SESSION_TIMEOUT = 60 * 60 * 1000; // 1 hour in milliseconds
|
|
8
7
|
const PHONE_REQUEST_DELAY = 3000;
|
|
9
|
-
|
|
8
|
+
// Retry reason codes matching WhatsApp Web's Signal error codes.
|
|
9
|
+
export var RetryReason;
|
|
10
10
|
(function (RetryReason) {
|
|
11
|
-
RetryReason[
|
|
12
|
-
RetryReason[
|
|
13
|
-
RetryReason[
|
|
14
|
-
RetryReason[
|
|
15
|
-
|
|
16
|
-
RetryReason[
|
|
17
|
-
RetryReason[
|
|
18
|
-
RetryReason[
|
|
19
|
-
|
|
20
|
-
RetryReason[
|
|
21
|
-
RetryReason[
|
|
22
|
-
RetryReason[
|
|
23
|
-
RetryReason[
|
|
24
|
-
RetryReason[
|
|
25
|
-
|
|
11
|
+
RetryReason[RetryReason["UnknownError"] = 0] = "UnknownError";
|
|
12
|
+
RetryReason[RetryReason["SignalErrorNoSession"] = 1] = "SignalErrorNoSession";
|
|
13
|
+
RetryReason[RetryReason["SignalErrorInvalidKey"] = 2] = "SignalErrorInvalidKey";
|
|
14
|
+
RetryReason[RetryReason["SignalErrorInvalidKeyId"] = 3] = "SignalErrorInvalidKeyId";
|
|
15
|
+
/** MAC verification failed - most common cause of decryption failures */
|
|
16
|
+
RetryReason[RetryReason["SignalErrorInvalidMessage"] = 4] = "SignalErrorInvalidMessage";
|
|
17
|
+
RetryReason[RetryReason["SignalErrorInvalidSignature"] = 5] = "SignalErrorInvalidSignature";
|
|
18
|
+
RetryReason[RetryReason["SignalErrorFutureMessage"] = 6] = "SignalErrorFutureMessage";
|
|
19
|
+
/** Explicit MAC failure - session is definitely out of sync */
|
|
20
|
+
RetryReason[RetryReason["SignalErrorBadMac"] = 7] = "SignalErrorBadMac";
|
|
21
|
+
RetryReason[RetryReason["SignalErrorInvalidSession"] = 8] = "SignalErrorInvalidSession";
|
|
22
|
+
RetryReason[RetryReason["SignalErrorInvalidMsgKey"] = 9] = "SignalErrorInvalidMsgKey";
|
|
23
|
+
RetryReason[RetryReason["BadBroadcastEphemeralSetting"] = 10] = "BadBroadcastEphemeralSetting";
|
|
24
|
+
RetryReason[RetryReason["UnknownCompanionNoPrekey"] = 11] = "UnknownCompanionNoPrekey";
|
|
25
|
+
RetryReason[RetryReason["AdvFailure"] = 12] = "AdvFailure";
|
|
26
|
+
RetryReason[RetryReason["StatusRevokeDelay"] = 13] = "StatusRevokeDelay";
|
|
27
|
+
})(RetryReason || (RetryReason = {}));
|
|
28
|
+
/** Error codes that indicate a MAC failure and require immediate session recreation */
|
|
26
29
|
const MAC_ERROR_CODES = new Set([RetryReason.SignalErrorInvalidMessage, RetryReason.SignalErrorBadMac]);
|
|
27
|
-
class MessageRetryManager {
|
|
30
|
+
export class MessageRetryManager {
|
|
28
31
|
constructor(logger, maxMsgRetryCount) {
|
|
29
32
|
this.logger = logger;
|
|
30
|
-
this.recentMessagesMap = new
|
|
33
|
+
this.recentMessagesMap = new LRUCache({
|
|
31
34
|
max: RECENT_MESSAGES_SIZE,
|
|
32
35
|
ttl: 5 * 60 * 1000,
|
|
33
36
|
ttlAutopurge: true,
|
|
@@ -40,16 +43,16 @@ class MessageRetryManager {
|
|
|
40
43
|
}
|
|
41
44
|
});
|
|
42
45
|
this.messageKeyIndex = new Map();
|
|
43
|
-
this.sessionRecreateHistory = new
|
|
46
|
+
this.sessionRecreateHistory = new LRUCache({
|
|
44
47
|
ttl: RECREATE_SESSION_TIMEOUT * 2,
|
|
45
48
|
ttlAutopurge: true
|
|
46
49
|
});
|
|
47
|
-
this.retryCounters = new
|
|
50
|
+
this.retryCounters = new LRUCache({
|
|
48
51
|
ttl: 15 * 60 * 1000,
|
|
49
52
|
ttlAutopurge: true,
|
|
50
53
|
updateAgeOnGet: true
|
|
51
|
-
});
|
|
52
|
-
this.baseKeys = new
|
|
54
|
+
}); // 15 minutes TTL
|
|
55
|
+
this.baseKeys = new LRUCache({
|
|
53
56
|
max: 1024,
|
|
54
57
|
ttl: 15 * 60 * 1000,
|
|
55
58
|
ttlAutopurge: true
|
|
@@ -66,9 +69,13 @@ class MessageRetryManager {
|
|
|
66
69
|
};
|
|
67
70
|
this.maxMsgRetryCount = maxMsgRetryCount;
|
|
68
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Add a recent message to the cache for retry handling
|
|
74
|
+
*/
|
|
69
75
|
addRecentMessage(to, id, message) {
|
|
70
76
|
const key = { to, id };
|
|
71
77
|
const keyStr = this.keyToString(key);
|
|
78
|
+
// Add new message
|
|
72
79
|
this.recentMessagesMap.set(keyStr, {
|
|
73
80
|
message,
|
|
74
81
|
timestamp: Date.now()
|
|
@@ -76,12 +83,20 @@ class MessageRetryManager {
|
|
|
76
83
|
this.messageKeyIndex.set(id, keyStr);
|
|
77
84
|
this.logger.debug(`Added message to retry cache: ${to}/${id}`);
|
|
78
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Get a recent message from the cache
|
|
88
|
+
*/
|
|
79
89
|
getRecentMessage(to, id) {
|
|
80
90
|
const key = { to, id };
|
|
81
91
|
const keyStr = this.keyToString(key);
|
|
82
92
|
return this.recentMessagesMap.get(keyStr);
|
|
83
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Check if a session should be recreated based on retry count, history, and error code.
|
|
96
|
+
* MAC errors (codes 4 and 7) trigger immediate session recreation regardless of timeout.
|
|
97
|
+
*/
|
|
84
98
|
shouldRecreateSession(jid, hasSession, errorCode) {
|
|
99
|
+
// If we don't have a session, always recreate
|
|
85
100
|
if (!hasSession) {
|
|
86
101
|
this.sessionRecreateHistory.set(jid, Date.now());
|
|
87
102
|
this.statistics.sessionRecreations++;
|
|
@@ -90,6 +105,7 @@ class MessageRetryManager {
|
|
|
90
105
|
recreate: true
|
|
91
106
|
};
|
|
92
107
|
}
|
|
108
|
+
// IMMEDIATE recreation for MAC errors - session is definitely out of sync
|
|
93
109
|
if (errorCode !== undefined && MAC_ERROR_CODES.has(errorCode)) {
|
|
94
110
|
this.sessionRecreateHistory.set(jid, Date.now());
|
|
95
111
|
this.statistics.sessionRecreations++;
|
|
@@ -101,6 +117,7 @@ class MessageRetryManager {
|
|
|
101
117
|
}
|
|
102
118
|
const now = Date.now();
|
|
103
119
|
const prevTime = this.sessionRecreateHistory.get(jid);
|
|
120
|
+
// If no previous recreation or it's been more than an hour
|
|
104
121
|
if (!prevTime || now - prevTime > RECREATE_SESSION_TIMEOUT) {
|
|
105
122
|
this.sessionRecreateHistory.set(jid, now);
|
|
106
123
|
this.statistics.sessionRecreations++;
|
|
@@ -111,6 +128,10 @@ class MessageRetryManager {
|
|
|
111
128
|
}
|
|
112
129
|
return { reason: '', recreate: false };
|
|
113
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Parse error code from retry receipt's retry node.
|
|
133
|
+
* Returns undefined if no error code is present.
|
|
134
|
+
*/
|
|
114
135
|
parseRetryErrorCode(errorAttr) {
|
|
115
136
|
if (errorAttr === undefined || errorAttr === '') {
|
|
116
137
|
return undefined;
|
|
@@ -119,38 +140,62 @@ class MessageRetryManager {
|
|
|
119
140
|
if (Number.isNaN(code)) {
|
|
120
141
|
return undefined;
|
|
121
142
|
}
|
|
143
|
+
// Validate it's a known RetryReason
|
|
122
144
|
if (code >= RetryReason.UnknownError && code <= RetryReason.StatusRevokeDelay) {
|
|
123
145
|
return code;
|
|
124
146
|
}
|
|
125
147
|
return RetryReason.UnknownError;
|
|
126
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Check if an error code indicates a MAC failure
|
|
151
|
+
*/
|
|
127
152
|
isMacError(errorCode) {
|
|
128
153
|
return errorCode !== undefined && MAC_ERROR_CODES.has(errorCode);
|
|
129
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Increment retry counter for a message
|
|
157
|
+
*/
|
|
130
158
|
incrementRetryCount(messageId) {
|
|
131
159
|
this.retryCounters.set(messageId, (this.retryCounters.get(messageId) || 0) + 1);
|
|
132
160
|
this.statistics.totalRetries++;
|
|
133
161
|
return this.retryCounters.get(messageId);
|
|
134
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Get retry count for a message
|
|
165
|
+
*/
|
|
135
166
|
getRetryCount(messageId) {
|
|
136
167
|
return this.retryCounters.get(messageId) || 0;
|
|
137
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if message has exceeded maximum retry attempts
|
|
171
|
+
*/
|
|
138
172
|
hasExceededMaxRetries(messageId) {
|
|
139
173
|
return this.getRetryCount(messageId) >= this.maxMsgRetryCount;
|
|
140
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Mark retry as successful
|
|
177
|
+
*/
|
|
141
178
|
markRetrySuccess(messageId) {
|
|
142
179
|
this.statistics.successfulRetries++;
|
|
180
|
+
// Clean up retry counter for successful message
|
|
143
181
|
this.retryCounters.delete(messageId);
|
|
144
182
|
this.cancelPendingPhoneRequest(messageId);
|
|
145
183
|
this.removeRecentMessage(messageId);
|
|
146
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Mark retry as failed
|
|
187
|
+
*/
|
|
147
188
|
markRetryFailed(messageId) {
|
|
148
189
|
this.statistics.failedRetries++;
|
|
149
190
|
this.retryCounters.delete(messageId);
|
|
150
191
|
this.cancelPendingPhoneRequest(messageId);
|
|
151
192
|
this.removeRecentMessage(messageId);
|
|
152
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Schedule a phone request with delay
|
|
196
|
+
*/
|
|
153
197
|
schedulePhoneRequest(messageId, callback, delay = PHONE_REQUEST_DELAY) {
|
|
198
|
+
// Cancel any existing request for this message
|
|
154
199
|
this.cancelPendingPhoneRequest(messageId);
|
|
155
200
|
this.pendingPhoneRequests[messageId] = setTimeout(() => {
|
|
156
201
|
delete this.pendingPhoneRequests[messageId];
|
|
@@ -159,6 +204,9 @@ class MessageRetryManager {
|
|
|
159
204
|
}, delay);
|
|
160
205
|
this.logger.debug(`Scheduled phone request for message ${messageId} with ${delay}ms delay`);
|
|
161
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* Cancel pending phone request
|
|
209
|
+
*/
|
|
162
210
|
cancelPendingPhoneRequest(messageId) {
|
|
163
211
|
const timeout = this.pendingPhoneRequests[messageId];
|
|
164
212
|
if (timeout) {
|
|
@@ -214,4 +262,4 @@ class MessageRetryManager {
|
|
|
214
262
|
this.messageKeyIndex.delete(messageId);
|
|
215
263
|
}
|
|
216
264
|
}
|
|
217
|
-
|
|
265
|
+
//# sourceMappingURL=message-retry-manager.js.map
|