kage-baileys 3.0.6 → 3.2.3
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/Example/connection.cjs +4 -0
- package/README.MD +4726 -48
- package/WAProto/WAProto.proto +3395 -415
- package/WAProto/compat.cjs +12 -0
- package/WAProto/index.d.ts +47104 -19888
- package/WAProto/index.js +131979 -57361
- package/lib/Addon/http-error.js +43 -0
- package/lib/Addon/index.js +32 -0
- package/lib/Addon/keyed-db.js +250 -0
- package/lib/Addon/link-preview.js +82 -0
- package/lib/Defaults/baileys-version.json +3 -0
- package/lib/Defaults/connection.js +110 -0
- package/lib/Defaults/constants.js +156 -0
- package/lib/Defaults/history.js +46 -0
- package/lib/Defaults/index.js +230 -0
- package/lib/Defaults/media.js +104 -0
- package/lib/Defaults/phonenumber-mcc.json +223 -0
- package/lib/Defaults/prefix.js +44 -0
- package/lib/Extensions/business-advanced.js +382 -0
- package/lib/Extensions/business.js +159 -0
- package/lib/Extensions/chats-advanced.js +1106 -0
- package/lib/Extensions/chats.js +349 -0
- package/lib/Extensions/communities-advanced.js +430 -0
- package/lib/Extensions/community.js +94 -0
- package/lib/Extensions/groups-advanced.js +343 -0
- package/lib/Extensions/index.js +30 -0
- package/lib/Extensions/messages-recv-advanced.js +1690 -0
- package/lib/Extensions/messages-send-advanced.js +622 -0
- package/lib/Extensions/messages-send.js +1380 -0
- package/lib/Extensions/newsletter-advanced.js +228 -0
- package/lib/Extensions/newsletter.js +72 -0
- package/lib/Extensions/socket.js +389 -0
- package/lib/Modded/message_builder.js +2084 -4
- package/lib/Signal/Group/ciphertext-message.js +54 -0
- package/lib/Signal/Group/group-session-builder.js +124 -0
- package/lib/Signal/Group/group_cipher.js +216 -0
- package/lib/Signal/Group/index.js +124 -0
- package/lib/Signal/Group/keyhelper.js +108 -0
- package/lib/Signal/Group/sender-chain-key.js +83 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +157 -0
- package/lib/Signal/Group/sender-key-message.js +166 -0
- package/lib/Signal/Group/sender-key-name.js +130 -0
- package/lib/Signal/Group/sender-key-record.js +113 -0
- package/lib/Signal/Group/sender-key-state.js +208 -0
- package/lib/Signal/Group/sender-message-key.js +82 -0
- package/lib/Signal/libsignal.js +935 -0
- package/lib/Signal/lid-mapping.js +545 -1
- package/lib/Socket/Client/index.js +60 -0
- package/lib/Socket/Client/types.js +51 -0
- package/lib/Socket/Client/websocket.js +152 -0
- package/lib/Socket/business.js +831 -0
- package/lib/Socket/chats.js +2535 -49
- package/lib/Socket/communities.js +450 -1
- package/lib/Socket/community.js +1022 -0
- package/lib/Socket/dugong.js +1 -1
- package/lib/Socket/groups.js +747 -0
- package/lib/Socket/index.js +60 -2
- package/lib/Socket/messages-recv.js +3450 -5
- package/lib/Socket/messages-send.js +3123 -0
- package/lib/Socket/mex.js +126 -1
- package/lib/Socket/newsletter.js +465 -0
- package/lib/Socket/socket.js +2217 -1
- package/lib/Store/index.js +79 -0
- package/lib/Store/make-cache-manager-store.js +186 -0
- package/lib/Store/make-in-memory-store.js +878 -0
- package/lib/Store/make-ordered-dictionary.js +187 -0
- package/lib/Store/object-repository.js +78 -0
- package/lib/Types/Auth.js +25 -0
- package/lib/Types/Bussines.js +25 -1
- package/lib/Types/Call.js +25 -0
- package/lib/Types/Chat.js +39 -0
- package/lib/Types/Contact.js +25 -0
- package/lib/Types/Events.js +25 -0
- package/lib/Types/GroupMetadata.js +25 -0
- package/lib/Types/Label.js +76 -0
- package/lib/Types/LabelAssociation.js +40 -0
- package/lib/Types/Message.js +57 -0
- package/lib/Types/Mex.js +56 -1
- package/lib/Types/MexUpdates.js +46 -0
- package/lib/Types/Newsletter.js +56 -0
- package/lib/Types/Product.js +25 -0
- package/lib/Types/RichType.js +23 -0
- package/lib/Types/Signal.js +25 -0
- package/lib/Types/Socket.js +25 -0
- package/lib/Types/State.js +92 -0
- package/lib/Types/USync.js +25 -0
- package/lib/Types/index.js +133 -0
- package/lib/Utils/auth-utils.js +703 -0
- package/lib/Utils/automation-tools.js +51 -16
- package/lib/Utils/baileys-event-stream.js +146 -0
- package/lib/Utils/browser-utils.js +95 -0
- package/lib/Utils/business.js +525 -0
- package/lib/Utils/chat-utils.js +1861 -0
- package/lib/Utils/companion-reg-client-utils.js +55 -1
- package/lib/Utils/crypto.js +355 -0
- package/lib/Utils/decode-wa-message.js +709 -0
- package/lib/Utils/event-buffer.js +1323 -8
- package/lib/Utils/generics.js +945 -1
- package/lib/Utils/history.js +266 -0
- package/lib/Utils/identity-change-handler.js +62 -1
- package/lib/Utils/index.js +114 -0
- package/lib/Utils/link-preview.js +179 -0
- package/lib/Utils/logger.js +42 -0
- package/lib/Utils/lt-hash.js +73 -0
- package/lib/Utils/make-mutex.js +104 -0
- package/lib/Utils/message-inspector.js +110 -0
- package/lib/Utils/message-retry-manager.js +507 -2
- package/lib/Utils/messages-media.js +1931 -1
- package/lib/Utils/messages.js +3748 -0
- package/lib/Utils/noise-handler.js +423 -0
- package/lib/Utils/offline-node-processor.js +53 -1
- package/lib/Utils/pre-key-manager.js +255 -1
- package/lib/Utils/process-message.js +1592 -0
- package/lib/Utils/reporting-utils.js +272 -1
- package/lib/Utils/rich-message-utils.js +377 -0
- package/lib/Utils/rich-messages.js +1 -1
- package/lib/Utils/signal.js +437 -0
- package/lib/Utils/stanza-ack.js +51 -1
- package/lib/Utils/status-refresh.js +37 -0
- package/lib/Utils/status-tools.js +4 -2
- package/lib/Utils/sync-action-utils.js +63 -1
- package/lib/Utils/tc-token-utils.js +185 -1
- package/lib/Utils/terminal-banner.js +31 -0
- package/lib/Utils/use-multi-file-auth-state.js +271 -0
- package/lib/Utils/use-single-file-auth-state.js +108 -0
- package/lib/Utils/use-sqlite-auth-state.js +142 -0
- package/lib/Utils/validate-connection.js +497 -1
- package/lib/Utils/view-once-compat.js +13 -5
- package/lib/VoIP/audio-feeder.js +150 -0
- package/lib/VoIP/index.js +289 -0
- package/lib/VoIP/relay-transport.js +608 -0
- package/lib/VoIP/signaling.js +583 -0
- package/lib/VoIP/types.js +30 -0
- package/lib/VoIP/wasm-engine.js +1261 -2
- package/lib/VoIP/worker-bootstrap.js +1090 -2
- package/lib/WABinary/constants.js +2805 -0
- package/lib/WABinary/decode.js +649 -2
- package/lib/WABinary/encode.js +564 -2
- package/lib/WABinary/generic-utils.js +401 -0
- package/lib/WABinary/index.js +82 -0
- package/lib/WABinary/jid-utils.js +290 -0
- package/lib/WABinary/types.js +25 -0
- package/lib/WAM/BinaryInfo.js +50 -0
- package/lib/WAM/constants.js +45747 -0
- package/lib/WAM/encode.js +393 -0
- package/lib/WAM/index.js +78 -0
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +135 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +110 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +142 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +85 -0
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +69 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +107 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +38 -1
- package/lib/WAUSync/Protocols/index.js +83 -0
- package/lib/WAUSync/USyncQuery.js +241 -2
- package/lib/WAUSync/USyncUser.js +86 -0
- package/lib/WAUSync/index.js +78 -0
- package/lib/assets/wasm/loader.js +1875 -1
- package/lib/assets/wasm/worker-modules.js +11047 -1
- package/lib/index.d.ts +126 -0
- package/lib/index.js +53 -21
- package/lib/index.mjs +437 -0
- package/licenses/upstream-MIT.txt +22 -0
- package/maintenance/api-coverage.json +1642 -0
- package/maintenance/archivos-sha256.json +207 -0
- package/maintenance/consumer-validation.log +3 -0
- package/maintenance/dependency-audit.json +4 -4
- package/maintenance/extension-inventory.json +57 -0
- package/maintenance/protocol-update.json +1101 -0
- package/maintenance/protocol-wire-audit.json +4 -0
- package/maintenance/reference-socket-surface.json +209 -0
- package/maintenance/resumen-validacion.json +50 -0
- package/maintenance/validation.log +2725 -0
- package/maintenance/verification.json +566 -0
- package/package.json +107 -9
- package/scripts/check-imports.cjs +10 -0
- package/scripts/check-package.cjs +40 -0
- package/scripts/check-syntax.cjs +1 -1
- package/scripts/generate-protobuf.cjs +6 -1
- package/scripts/generate-public-types.cjs +9 -0
- package/scripts/kage-base64-fix.cjs +45 -0
- package/scripts/maintenance.cjs +10 -0
- package/test/advanced.test.cjs +24 -0
- package/test/base64-fix.test.cjs +49 -0
- package/test/maintenance.test.cjs +1 -1
- package/test/npm-publication.test.cjs +141 -0
- package/test/recepcion-reparada.test.cjs +98 -0
- package/test/resilience-binary.test.cjs +69 -0
- package/test/resilience-transport.test.cjs +34 -0
- package/test/types.test.ts +5 -0
- package/test/upgrade.test.cjs +104 -0
- package/tsconfig.json +20 -0
- package/WAProto/p.html +0 -1
- package/lib/KageExtra/Modded/message_builder.js +0 -2330
- package/lib/KageExtra/VoIP/audio-feeder.js +0 -136
- package/lib/KageExtra/VoIP/index.js +0 -282
- package/lib/KageExtra/VoIP/relay-transport.js +0 -559
- package/lib/KageExtra/VoIP/signaling.js +0 -603
- package/lib/KageExtra/VoIP/types.js +0 -17
- package/lib/KageExtra/VoIP/wasm-engine.js +0 -1214
- package/lib/KageExtra/VoIP/worker-bootstrap.js +0 -1042
- package/lib/KageExtra/assets/wasm/loader.js +0 -5
- package/lib/KageExtra/assets/wasm/whatsapp.wasm +0 -0
- package/lib/KageExtra/assets/wasm/worker-modules.js +0 -273
- package/lib/KageExtra/index.js +0 -3
- package/lib/KageExtra/package.json +0 -1
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -53
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -24
- package/maintenance/revision-full-check.txt +0 -1097
- package/maintenance/revision-library-tests.tap +0 -1088
- package/maintenance/revision-protobuf.txt +0 -5
- package/maintenance/revision-syntax.txt +0 -5
- package/maintenance/schema-coverage.json +0 -23
- package/maintenance/schema-merge.json +0 -30
- package/maintenance/validation-node20.txt +0 -191
- package/maintenance/validation-node22.txt +0 -237
package/lib/Utils/lt-hash.js
CHANGED
|
@@ -49,3 +49,76 @@ class d {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
exports.LT_HASH_ANTI_TAMPERING = new d('WhatsApp Patch Integrity');
|
|
52
|
+
|
|
53
|
+
// Kage: compatibilidad de API.
|
|
54
|
+
const __kageModule70 = (() => {
|
|
55
|
+
const module = { exports: {} }; const exports = module.exports;
|
|
56
|
+
"use strict"
|
|
57
|
+
|
|
58
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
59
|
+
|
|
60
|
+
const { hkdf } = require("./crypto")
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* LT Hash is a summation based hash algorithm that maintains the integrity of a piece of data
|
|
64
|
+
* over a series of mutations. You can add/remove mutations and it'll return a hash equal to
|
|
65
|
+
* if the same series of mutations was made sequentially.
|
|
66
|
+
*/
|
|
67
|
+
const o = 128
|
|
68
|
+
|
|
69
|
+
class LTHash {
|
|
70
|
+
constructor(e) {
|
|
71
|
+
this.salt = e
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async add(e, t) {
|
|
75
|
+
for (const item of t) {
|
|
76
|
+
e = await this._addSingle(e, item)
|
|
77
|
+
}
|
|
78
|
+
return e
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async subtract(e, t) {
|
|
82
|
+
for (const item of t) {
|
|
83
|
+
e = await this._subtractSingle(e, item)
|
|
84
|
+
}
|
|
85
|
+
return e
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async subtractThenAdd(e, addList, subtractList) {
|
|
89
|
+
const subtracted = await this.subtract(e, subtractList)
|
|
90
|
+
return this.add(subtracted, addList)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async _addSingle(e, t) {
|
|
94
|
+
const derived = new Uint8Array(await hkdf(Buffer.from(t), o, { info: this.salt })).buffer
|
|
95
|
+
return this.performPointwiseWithOverflow(e, derived, (a, b) => a + b)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async _subtractSingle(e, t) {
|
|
99
|
+
const derived = new Uint8Array(await hkdf(Buffer.from(t), o, { info: this.salt })).buffer
|
|
100
|
+
return this.performPointwiseWithOverflow(e, derived, (a, b) => a - b)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
performPointwiseWithOverflow(e, t, op) {
|
|
104
|
+
const n = new DataView(e)
|
|
105
|
+
const i = new DataView(t)
|
|
106
|
+
const out = new ArrayBuffer(n.byteLength)
|
|
107
|
+
const s = new DataView(out)
|
|
108
|
+
for (let offset = 0; offset < n.byteLength; offset += 2) {
|
|
109
|
+
s.setUint16(offset, op(n.getUint16(offset, true), i.getUint16(offset, true)), true)
|
|
110
|
+
}
|
|
111
|
+
return out
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const LT_HASH_ANTI_TAMPERING = new LTHash('WhatsApp Patch Integrity')
|
|
116
|
+
|
|
117
|
+
module.exports = {
|
|
118
|
+
LT_HASH_ANTI_TAMPERING
|
|
119
|
+
}
|
|
120
|
+
return module.exports;
|
|
121
|
+
})();
|
|
122
|
+
for (const key of Object.keys(__kageModule70)) {
|
|
123
|
+
if (key !== '__esModule' && !Object.prototype.hasOwnProperty.call(exports,key)) Object.defineProperty(exports,key,{enumerable:true,configurable:true,get:()=>__kageModule70[key]});
|
|
124
|
+
}
|
package/lib/Utils/make-mutex.js
CHANGED
|
@@ -41,3 +41,107 @@ const makeKeyedMutex = () => {
|
|
|
41
41
|
};
|
|
42
42
|
};
|
|
43
43
|
exports.makeKeyedMutex = makeKeyedMutex;
|
|
44
|
+
|
|
45
|
+
// Kage: compatibilidad de API.
|
|
46
|
+
const __kageModule71 = (() => {
|
|
47
|
+
const module = { exports: {} }; const exports = module.exports;
|
|
48
|
+
"use strict"
|
|
49
|
+
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true })
|
|
51
|
+
|
|
52
|
+
const { Mutex: AsyncMutex } = require("async-mutex")
|
|
53
|
+
|
|
54
|
+
const makeMutex = () => {
|
|
55
|
+
const mutex = new AsyncMutex()
|
|
56
|
+
return {
|
|
57
|
+
mutex(code) {
|
|
58
|
+
return mutex.runExclusive(code)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const makeKeyedMutex = () => {
|
|
64
|
+
const map = new Map()
|
|
65
|
+
return {
|
|
66
|
+
async mutex(key, task) {
|
|
67
|
+
let entry = map.get(key)
|
|
68
|
+
|
|
69
|
+
if (!entry) {
|
|
70
|
+
entry = { mutex: new AsyncMutex(), refCount: 0 }
|
|
71
|
+
map.set(key, entry)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
entry.refCount++
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
return await entry.mutex.runExclusive(task)
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
entry.refCount--
|
|
81
|
+
|
|
82
|
+
// only delete it if this is still the current entry
|
|
83
|
+
if (entry.refCount === 0 && map.get(key) === entry) {
|
|
84
|
+
map.delete(key)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = {
|
|
92
|
+
makeMutex,
|
|
93
|
+
makeKeyedMutex
|
|
94
|
+
}
|
|
95
|
+
return module.exports;
|
|
96
|
+
})();
|
|
97
|
+
for (const key of Object.keys(__kageModule71)) {
|
|
98
|
+
if (key !== '__esModule' && !Object.prototype.hasOwnProperty.call(exports,key)) Object.defineProperty(exports,key,{enumerable:true,configurable:true,get:()=>__kageModule71[key]});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Kage: funciones avanzadas.
|
|
102
|
+
const __kageModule175 = (() => {
|
|
103
|
+
const module = { exports: {} }; const exports = module.exports;
|
|
104
|
+
"use strict";
|
|
105
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
106
|
+
exports.makeKeyedMutex = exports.makeMutex = void 0;
|
|
107
|
+
const index_js_1 = require("../Addon/index.js");
|
|
108
|
+
const makeMutex = () => {
|
|
109
|
+
const mutex = (0, index_js_1.createMutex)();
|
|
110
|
+
return {
|
|
111
|
+
mutex(code) {
|
|
112
|
+
return mutex.runExclusive(code);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
exports.makeMutex = makeMutex;
|
|
117
|
+
const makeKeyedMutex = () => {
|
|
118
|
+
const map = new Map();
|
|
119
|
+
return {
|
|
120
|
+
async mutex(key, task) {
|
|
121
|
+
let entry = map.get(key);
|
|
122
|
+
if (!entry) {
|
|
123
|
+
entry = { mutex: (0, index_js_1.createMutex)(), refCount: 0 };
|
|
124
|
+
map.set(key, entry);
|
|
125
|
+
}
|
|
126
|
+
entry.refCount++;
|
|
127
|
+
try {
|
|
128
|
+
return await entry.mutex.runExclusive(task);
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
entry.refCount--;
|
|
132
|
+
// only delete it if this is still the current entry
|
|
133
|
+
if (entry.refCount === 0 && map.get(key) === entry) {
|
|
134
|
+
map.delete(key);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
};
|
|
140
|
+
exports.makeKeyedMutex = makeKeyedMutex;
|
|
141
|
+
|
|
142
|
+
return module.exports;
|
|
143
|
+
})();
|
|
144
|
+
for (const key of Object.keys(__kageModule175)) {
|
|
145
|
+
if (key !== '__esModule' && !Object.prototype.hasOwnProperty.call(exports,key)) Object.defineProperty(exports,key,{enumerable:true,configurable:true,get:()=>__kageModule175[key]});
|
|
146
|
+
}
|
|
147
|
+
Object.defineProperty(exports, Symbol.for('kage.advanced'), {value:__kageModule175, configurable:true});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const states = new WeakMap();
|
|
3
|
+
const wrappers = ['deviceSentMessage', 'ephemeralMessage', 'viewOnceMessage', 'viewOnceMessageV2', 'viewOnceMessageV2Extension', 'documentWithCaptionMessage', 'editedMessage', 'statusMentionMessage', 'groupStatusMentionMessage', 'groupStatusMessage', 'groupStatusMessageV2'];
|
|
4
|
+
const labels = { conversation:'Texto', extendedTextMessage:'Texto', imageMessage:'Imagen', videoMessage:'Video', audioMessage:'Audio', documentMessage:'Documento', stickerMessage:'Sticker', reactionMessage:'Reacción', encReactionMessage:'Reacción cifrada', contactMessage:'Contacto', contactsArrayMessage:'Contactos', locationMessage:'Ubicación', liveLocationMessage:'Ubicación en vivo', pollCreationMessage:'Encuesta', pollCreationMessageV2:'Encuesta', pollCreationMessageV3:'Encuesta', pollUpdateMessage:'Voto de encuesta', protocolMessage:'Protocolo', interactiveMessage:'Interactivo', interactiveResponseMessage:'Respuesta interactiva', buttonsResponseMessage:'Respuesta de botón', listResponseMessage:'Respuesta de lista', eventMessage:'Evento programado', call:'Llamada', scheduledCallCreationMessage:'Llamada programada' };
|
|
5
|
+
const clean = jid => (typeof jid === 'string' ? jid.slice(0,256) : '').replace(/:\d+@/, '@');
|
|
6
|
+
const numeric = n => { try { const value = Number(n?.toNumber?.() ?? n ?? 0); return Number.isFinite(value) ? value : 0; } catch { return 0; } };
|
|
7
|
+
function inspectMessage(raw = {}) {
|
|
8
|
+
raw = raw && typeof raw === 'object' ? raw : {};
|
|
9
|
+
let message = raw.message || raw.fakeObj?.message || {};
|
|
10
|
+
if (!message || typeof message !== 'object' || ArrayBuffer.isView(message)) message = {};
|
|
11
|
+
const visited = new WeakSet();
|
|
12
|
+
const layers = [];
|
|
13
|
+
for (let i=0; i<16; i++) {
|
|
14
|
+
if (!message || typeof message !== 'object' || visited.has(message)) { message = {}; break; }
|
|
15
|
+
visited.add(message);
|
|
16
|
+
const wrapper = wrappers.find(k => message[k]?.message);
|
|
17
|
+
if (!wrapper) break;
|
|
18
|
+
layers.push(wrapper); message = message[wrapper].message;
|
|
19
|
+
}
|
|
20
|
+
const keys = Object.keys(message).filter(k => message[k] != null && !['messageContextInfo','senderKeyDistributionMessage','fastRatchetKeySenderKeyDistributionMessage'].includes(k));
|
|
21
|
+
const type = keys.find(k => labels[k]) || keys[0] || '';
|
|
22
|
+
const value = typeof message[type] === 'object' ? message[type] : {};
|
|
23
|
+
const context = value?.contextInfo || {};
|
|
24
|
+
const key = raw.key || raw.fakeObj?.key || {};
|
|
25
|
+
const chat = clean(key.remoteJid || raw.chat);
|
|
26
|
+
const group = chat.endsWith('@g.us');
|
|
27
|
+
const stubType = numeric(raw.messageStubType);
|
|
28
|
+
const encrypted = stubType === 2 && !type;
|
|
29
|
+
const viewOnce = layers.some(k=>k.startsWith('viewOnce')) || value?.viewOnce === true;
|
|
30
|
+
const text = typeof message[type] === 'string' ? message[type] : value?.text || value?.caption || '';
|
|
31
|
+
return {
|
|
32
|
+
id: typeof (key.id || raw.id) === 'string' ? (key.id || raw.id).slice(0,256) : null, chat, chatAlt: clean(key.remoteJidAlt) || null,
|
|
33
|
+
sender: clean(key.participant || raw.participant || raw.sender || (!key.fromMe && !group && chat !== 'status@broadcast' ? chat : '')) || null,
|
|
34
|
+
senderAlt: clean(key.participantAlt) || null, fromMe: !!key.fromMe,
|
|
35
|
+
route: chat === 'status@broadcast' ? 'estado' : group ? 'grupo' : chat.endsWith('@newsletter') ? 'canal' : /@(s\.whatsapp\.net|lid)$/.test(chat) ? 'privado' : 'sistema',
|
|
36
|
+
type: type || (encrypted ? 'ciphertext' : stubType ? 'stub' : 'unknown'),
|
|
37
|
+
label: encrypted ? 'Mensaje cifrado pendiente de descifrar' : labels[type] || (stubType ? 'Aviso del sistema' : type || 'Sin contenido'),
|
|
38
|
+
wrappers: layers, viewOnce, ephemeral: layers.includes('ephemeralMessage') || numeric(context.expiration)>0,
|
|
39
|
+
ptt: !!value?.ptt, gif: !!value?.gifPlayback, mime: typeof value?.mimetype === 'string' ? value.mimetype.slice(0,256) : null,
|
|
40
|
+
bytes: numeric(value?.fileLength) || (typeof text === 'string' ? Buffer.byteLength(text) : 0),
|
|
41
|
+
width: numeric(value?.width), height: numeric(value?.height), seconds: numeric(value?.seconds),
|
|
42
|
+
timestamp: numeric(raw.messageTimestamp), stubType: stubType || null,
|
|
43
|
+
quotedId: typeof context.stanzaId === 'string' ? context.stanzaId.slice(0,256) : null, mentions: (Array.isArray(context.mentionedJid) ? context.mentionedJid : []).slice(0,100).filter(j => typeof j === 'string'),
|
|
44
|
+
forwarded: !!context.isForwarded, forwardingScore: numeric(context.forwardingScore),
|
|
45
|
+
downloadable: !!(value?.mediaKey && (value?.directPath || value?.url)), encrypted,
|
|
46
|
+
receivedAt: Date.now()
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function stateFor(conn) {
|
|
50
|
+
let state=states.get(conn);
|
|
51
|
+
if(!state){state={events:[],messages:new Map(),counts:{},listeners:[],stopped:false};states.set(conn,state);}
|
|
52
|
+
return state;
|
|
53
|
+
}
|
|
54
|
+
function rememberMessage(conn, raw) {
|
|
55
|
+
const info=inspectMessage(raw); const state=stateFor(conn);
|
|
56
|
+
if(info.id){
|
|
57
|
+
const key=JSON.stringify([info.chat,info.sender,info.id,info.fromMe]);
|
|
58
|
+
const previous=state.messages.get(key) || [...state.messages.values()].find(item=>item.chat===info.chat&&item.id===info.id&&item.fromMe===info.fromMe);
|
|
59
|
+
if (!info.timestamp && previous) info.timestamp=previous.timestamp;
|
|
60
|
+
if (!info.sender && previous) info.sender=previous.sender;
|
|
61
|
+
state.messages.set(key,info);
|
|
62
|
+
}
|
|
63
|
+
for(const [key,info] of state.messages) if(Date.now()-info.receivedAt>86400000) state.messages.delete(key);
|
|
64
|
+
while(state.messages.size>1000) state.messages.delete(state.messages.keys().next().value);
|
|
65
|
+
return info;
|
|
66
|
+
}
|
|
67
|
+
function installMessageInspector(conn, options={}) {
|
|
68
|
+
const state=stateFor(conn);
|
|
69
|
+
if(state.stop && !state.stopped) return state.stop;
|
|
70
|
+
state.stopped=false;
|
|
71
|
+
const record=(kind,detail)=>{
|
|
72
|
+
const event={kind,time:Date.now(),...detail};
|
|
73
|
+
state.events.push(event); while(state.events.length>100) state.events.shift();
|
|
74
|
+
state.counts[kind]=(state.counts[kind]||0)+1;
|
|
75
|
+
conn.ev.emit('kage.event',event);
|
|
76
|
+
if(typeof options.onEvent==='function') { try{options.onEvent(event);}catch(error){conn.logger?.warn?.({error:error.message},'event monitor callback');} }
|
|
77
|
+
};
|
|
78
|
+
const bind=(name,callback)=>{conn.ev.on(name,callback);state.listeners.push([name,callback]);};
|
|
79
|
+
bind('messages.upsert',data=>{for(const raw of data?.messages||[]) record('message',rememberMessage(conn,raw));});
|
|
80
|
+
bind('messaging-history.set',data=>{for(const raw of data?.messages||[]) rememberMessage(conn,raw);record('history',{count:data?.messages?.length||0});});
|
|
81
|
+
bind('messages.update',items=>{for(const item of items||[]) {
|
|
82
|
+
if(item.update?.message) record('message.updated',rememberMessage(conn,{...item.update,key:item.key}));
|
|
83
|
+
else record('message.receipt',{id:item.key?.id,chat:clean(item.key?.remoteJid),status:item.update?.status ?? null,deleted:item.update?.message===null});
|
|
84
|
+
}});
|
|
85
|
+
bind('messages.delete',data=>record('message.deleted',{keys:(data?.keys||[]).slice(0,100).map(k=>({id:k.id,chat:clean(k.remoteJid)})),all:!!data?.all}));
|
|
86
|
+
bind('messages.reaction',items=>{for(const item of items||[]) record('reaction',{id:item.key?.id,chat:clean(item.key?.remoteJid),emoji:item.reaction?.text||''});});
|
|
87
|
+
bind('message-receipt.update',items=>{for(const item of items||[]) record('receipt',{id:item.key?.id,chat:clean(item.key?.remoteJid),user:clean(item.receipt?.userJid)});});
|
|
88
|
+
bind('call',calls=>{for(const call of calls||[]) record('call',{id:call.id,chat:clean(call.chatId||call.from),from:clean(call.from),status:call.status,isVideo:!!call.isVideo,isGroup:!!call.isGroup});});
|
|
89
|
+
bind('presence.update',data=>record('presence',{chat:clean(data?.id),users:Object.entries(data?.presences||{}).slice(0,30).map(([jid,p])=>({jid:clean(jid),state:p?.lastKnownPresence}))}));
|
|
90
|
+
bind('group-participants.update',data=>record('group.participants',{chat:clean(data?.id),action:data?.action,participants:(data?.participants||[]).slice(0,100).map(p=>typeof p==='string'?p:p.id)}));
|
|
91
|
+
bind('groups.update',items=>{for(const item of items||[])record('group.updated',{chat:clean(item.id),fields:Object.keys(item).filter(k=>k!=='id')});});
|
|
92
|
+
bind('chats.upsert',items=>record('chats.upsert',{chats:(items||[]).map(item=>clean(item.id)).slice(0,100)}));
|
|
93
|
+
bind('chats.update',items=>record('chats.update',{chats:(items||[]).map(item=>clean(item.id)).slice(0,100)}));
|
|
94
|
+
bind('contacts.upsert',items=>record('contacts.upsert',{count:items?.length||0}));
|
|
95
|
+
bind('contacts.update',items=>record('contacts.update',{count:items?.length||0}));
|
|
96
|
+
bind('kage.automation',data=>record('automation.'+String(data.kind||'media'),{id:data.id,chat:clean(data.chat),outcome:data.outcome,error:data.error||null}));
|
|
97
|
+
bind('kage.unsupported-message',data=>record('unsupported',{id:data?.id,chat:clean(data?.chat),encryption:data?.encryption,reason:data?.reason}));
|
|
98
|
+
bind('connection.update',data=>{record('connection',{connection:data.connection||null,receivedPendingNotifications:data.receivedPendingNotifications??null});if(data.connection==='close')state.stop();});
|
|
99
|
+
state.stop=()=>{if(state.stopped)return;state.stopped=true;for(const [name,fn]of state.listeners)conn.ev.off(name,fn);state.listeners=[];};
|
|
100
|
+
return state.stop;
|
|
101
|
+
}
|
|
102
|
+
function getMessageDiagnostics(conn) {
|
|
103
|
+
const state=stateFor(conn);
|
|
104
|
+
// Never expose references to internal mutable buffers or credentials.
|
|
105
|
+
return JSON.parse(JSON.stringify({active:!!state.stop&&!state.stopped,counts:state.counts,recent:state.events, messages:[...state.messages.values()]}));
|
|
106
|
+
}
|
|
107
|
+
exports.inspectMessage=inspectMessage;
|
|
108
|
+
exports.rememberMessage=rememberMessage;
|
|
109
|
+
exports.installMessageInspector=installMessageInspector;
|
|
110
|
+
exports.getMessageDiagnostics=getMessageDiagnostics;
|