kage-baileys 1.1.1 → 1.1.5
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 +100 -0
- package/Example/event.cjs +20 -0
- package/MANTENIMIENTO.txt +54 -0
- package/WAProto/GenerateStatics.sh +4 -4
- package/WAProto/WAProto.proto +33 -0
- package/WAProto/compat.cjs +16 -0
- package/WAProto/fix-imports.js +3 -81
- package/WAProto/index.d.ts +82078 -0
- package/WAProto/index.js +104267 -69387
- package/engine-requirements.js +5 -8
- package/lib/Defaults/index.js +2 -0
- package/lib/Socket/chats.js +4 -2
- package/lib/Socket/messages-send.js +6 -1
- package/lib/Store/make-in-memory-store.js +29 -13
- package/lib/Utils/browser-utils.js +7 -1
- package/lib/Utils/event-buffer.js +3 -1
- package/lib/Utils/event-message.js +77 -0
- package/lib/Utils/generics.js +2 -2
- package/lib/Utils/history.js +9 -6
- package/lib/Utils/index.js +2 -1
- package/lib/Utils/link-preview.js +4 -4
- package/lib/Utils/messages-media.js +13 -18
- package/lib/Utils/messages.js +5 -5
- package/lib/Utils/use-multi-file-auth-state.js +14 -4
- package/lib/index.d.ts +317 -12
- package/lib/index.js +1 -1
- package/maintenance/dependency-audit.json +22 -0
- package/maintenance/schema-coverage.json +23 -0
- package/maintenance/schema-merge.json +30 -0
- package/maintenance/validation-node20.txt +191 -0
- package/maintenance/validation-node22.txt +237 -0
- package/package.json +34 -55
- package/scripts/check-syntax.cjs +19 -0
- package/scripts/generate-protobuf.cjs +26 -0
- package/scripts/generate-public-types.cjs +52 -0
- package/test/buffering.test.cjs +24 -0
- package/test/maintenance.test.cjs +223 -0
- package/lib/Defaults/index.d.ts +0 -74
- package/lib/KageExtra/VoIP/audio-feeder.d.ts +0 -15
- package/lib/KageExtra/VoIP/relay-transport.d.ts +0 -43
- package/lib/KageExtra/VoIP/types.d.ts +0 -69
- package/lib/KageExtra/VoIP/wasm-engine.d.ts +0 -103
- package/lib/Signal/Group/ciphertext-message.d.ts +0 -10
- package/lib/Signal/Group/group-session-builder.d.ts +0 -15
- package/lib/Signal/Group/group_cipher.d.ts +0 -17
- package/lib/Signal/Group/index.d.ts +0 -12
- package/lib/Signal/Group/keyhelper.d.ts +0 -11
- package/lib/Signal/Group/sender-chain-key.d.ts +0 -14
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +0 -17
- package/lib/Signal/Group/sender-key-message.d.ts +0 -19
- package/lib/Signal/Group/sender-key-name.d.ts +0 -18
- package/lib/Signal/Group/sender-key-record.d.ts +0 -31
- package/lib/Signal/Group/sender-key-state.d.ts +0 -39
- package/lib/Signal/Group/sender-message-key.d.ts +0 -12
- package/lib/Signal/libsignal.d.ts +0 -5
- package/lib/Signal/lid-mapping.d.ts +0 -19
- package/lib/Socket/Client/index.d.ts +0 -3
- package/lib/Socket/Client/types.d.ts +0 -16
- package/lib/Socket/Client/websocket.d.ts +0 -13
- package/lib/Socket/business.d.ts +0 -536
- package/lib/Socket/chats.d.ts +0 -111
- package/lib/Socket/communities.d.ts +0 -645
- package/lib/Socket/dugong.d.ts +0 -130
- package/lib/Socket/groups.d.ts +0 -150
- package/lib/Socket/index.d.ts +0 -636
- package/lib/Socket/messages-recv.d.ts +0 -238
- package/lib/Socket/messages-send.d.ts +0 -579
- package/lib/Socket/mex.d.ts +0 -3
- package/lib/Socket/newsletter.d.ts +0 -177
- package/lib/Socket/socket.d.ts +0 -55
- package/lib/Types/Auth.d.ts +0 -116
- package/lib/Types/Bussines.d.ts +0 -37
- package/lib/Types/Call.d.ts +0 -15
- package/lib/Types/Chat.d.ts +0 -123
- package/lib/Types/Contact.d.ts +0 -24
- package/lib/Types/Events.d.ts +0 -237
- package/lib/Types/GroupMetadata.d.ts +0 -68
- package/lib/Types/Label.d.ts +0 -47
- package/lib/Types/LabelAssociation.d.ts +0 -30
- package/lib/Types/Message.d.ts +0 -428
- package/lib/Types/Mex.d.ts +0 -141
- package/lib/Types/Newsletter.d.ts +0 -135
- package/lib/Types/Product.d.ts +0 -79
- package/lib/Types/Signal.d.ts +0 -76
- package/lib/Types/Socket.d.ts +0 -158
- package/lib/Types/State.d.ts +0 -39
- package/lib/Types/USync.d.ts +0 -26
- package/lib/Types/index.d.ts +0 -66
- package/lib/Utils/auth-utils.d.ts +0 -19
- package/lib/Utils/browser-utils.d.ts +0 -4
- package/lib/Utils/business.d.ts +0 -23
- package/lib/Utils/chat-utils.d.ts +0 -70
- package/lib/Utils/companion-reg-client-utils.d.ts +0 -17
- package/lib/Utils/crypto.d.ts +0 -37
- package/lib/Utils/decode-wa-message.d.ts +0 -48
- package/lib/Utils/event-buffer.d.ts +0 -34
- package/lib/Utils/generics.d.ts +0 -91
- package/lib/Utils/history.d.ts +0 -22
- package/lib/Utils/identity-change-handler.d.ts +0 -37
- package/lib/Utils/index.d.ts +0 -23
- package/lib/Utils/link-preview.d.ts +0 -21
- package/lib/Utils/logger.d.ts +0 -13
- package/lib/Utils/lt-hash.d.ts +0 -8
- package/lib/Utils/make-mutex.d.ts +0 -9
- package/lib/Utils/message-retry-manager.d.ts +0 -110
- package/lib/Utils/messages-media.d.ts +0 -130
- package/lib/Utils/messages.d.ts +0 -91
- package/lib/Utils/noise-handler.d.ts +0 -20
- package/lib/Utils/offline-node-processor.d.ts +0 -17
- package/lib/Utils/pre-key-manager.d.ts +0 -28
- package/lib/Utils/process-message.d.ts +0 -60
- package/lib/Utils/reporting-utils.d.ts +0 -11
- package/lib/Utils/rich-messages.d.ts +0 -277
- package/lib/Utils/signal.d.ts +0 -34
- package/lib/Utils/stanza-ack.d.ts +0 -11
- package/lib/Utils/sticker-pack.d.ts +0 -10
- package/lib/Utils/sync-action-utils.d.ts +0 -19
- package/lib/Utils/tc-token-utils.d.ts +0 -12
- package/lib/Utils/use-multi-file-auth-state.d.ts +0 -13
- package/lib/Utils/validate-connection.d.ts +0 -11
- package/lib/VoIP/audio-feeder.d.ts +0 -15
- package/lib/VoIP/relay-transport.d.ts +0 -43
- package/lib/VoIP/types.d.ts +0 -69
- package/lib/VoIP/wasm-engine.d.ts +0 -103
- package/lib/WABinary/constants.d.ts +0 -28
- package/lib/WABinary/decode.d.ts +0 -7
- package/lib/WABinary/encode.d.ts +0 -3
- package/lib/WABinary/generic-utils.d.ts +0 -17
- package/lib/WABinary/index.d.ts +0 -6
- package/lib/WABinary/jid-utils.d.ts +0 -48
- package/lib/WABinary/types.d.ts +0 -19
- package/lib/WAM/BinaryInfo.d.ts +0 -9
- package/lib/WAM/constants.d.ts +0 -40
- package/lib/WAM/encode.d.ts +0 -3
- package/lib/WAM/index.d.ts +0 -4
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +0 -23
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +0 -13
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +0 -13
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +0 -26
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +0 -10
- package/lib/WAUSync/Protocols/index.d.ts +0 -5
- package/lib/WAUSync/USyncQuery.d.ts +0 -29
- package/lib/WAUSync/USyncUser.d.ts +0 -13
- package/lib/WAUSync/index.d.ts +0 -4
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Node.js >=20.18.1 (recommended: Node.js 22 LTS).
|
|
3
|
+
// Run from the project directory with: npm run example
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const pino = require('pino');
|
|
7
|
+
const qrcode = require('qrcode-terminal');
|
|
8
|
+
const { default: makeWASocket, useMultiFileAuthState, makeCacheableSignalKeyStore, makeInMemoryStore, Browsers } = require('../lib');
|
|
9
|
+
const logger = pino({ level: process.env.LOG_LEVEL || 'info' });
|
|
10
|
+
const dataDir = path.resolve(process.env.KAGE_DATA_DIR || './data');
|
|
11
|
+
fs.mkdirSync(dataDir, { recursive: true, mode: 0o700 });
|
|
12
|
+
const storeFile = path.join(dataDir, 'store.json');
|
|
13
|
+
const store = makeInMemoryStore({ logger });
|
|
14
|
+
// Restore local chats and messages immediately, before waiting for network history.
|
|
15
|
+
store.readFromFile(storeFile);
|
|
16
|
+
let sock, auth, attempts = 0, reconnectTimer, saveTimer, shuttingDown = false;
|
|
17
|
+
let credsWrite = Promise.resolve();
|
|
18
|
+
const terminalCodes = new Set([401, 403, 411, 419, 440, 500]);
|
|
19
|
+
function persistSoon() {
|
|
20
|
+
if (saveTimer || shuttingDown) return;
|
|
21
|
+
saveTimer = setTimeout(() => {
|
|
22
|
+
saveTimer = undefined;
|
|
23
|
+
store.writeToFileAsync(storeFile).catch(error => logger.error({ error }, 'No se pudo guardar el historial'));
|
|
24
|
+
}, 2000);
|
|
25
|
+
saveTimer.unref();
|
|
26
|
+
}
|
|
27
|
+
async function connect() {
|
|
28
|
+
if (shuttingDown) return;
|
|
29
|
+
auth ||= await useMultiFileAuthState(path.join(dataDir, 'auth'));
|
|
30
|
+
sock = makeWASocket({
|
|
31
|
+
logger,
|
|
32
|
+
auth: { creds: auth.state.creds, keys: makeCacheableSignalKeyStore(auth.state.keys, logger) },
|
|
33
|
+
browser: Browsers.macOS('Desktop'),
|
|
34
|
+
syncFullHistory: process.env.KAGE_FULL_HISTORY !== '0',
|
|
35
|
+
shouldSyncHistoryMessage: () => true,
|
|
36
|
+
markOnlineOnConnect: false,
|
|
37
|
+
// Releases the initial wait sooner if the server sends no history notification.
|
|
38
|
+
// This does not accelerate server downloads and does not disable app-state sync.
|
|
39
|
+
initialSyncTimeoutMs: 5000,
|
|
40
|
+
getMessage: async key => (await store.loadMessage(key.remoteJid, key.id))?.message
|
|
41
|
+
});
|
|
42
|
+
store.bind(sock.ev);
|
|
43
|
+
sock.ev.on('creds.update', () => {
|
|
44
|
+
credsWrite = credsWrite.then(() => auth.saveCreds()).catch(error => {
|
|
45
|
+
logger.error({ error }, 'Error de escritura de credenciales; se detiene para no perder la sesión');
|
|
46
|
+
shutdown(1).catch(fatal => { logger.error({ fatal }); process.exitCode = 1; });
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
sock.ev.on('messaging-history.set', ({ chats, contacts, messages, progress }) => {
|
|
50
|
+
logger.info({ chats: chats.length, contacts: contacts.length, messages: messages.length, progress }, 'Historial recibido');
|
|
51
|
+
persistSoon();
|
|
52
|
+
});
|
|
53
|
+
sock.ev.on('messages.upsert', ({ messages, type }) => {
|
|
54
|
+
// Never wait for all history to process incoming live messages.
|
|
55
|
+
for (const message of messages) logger.debug({ key: message.key, type }, 'Mensaje recibido');
|
|
56
|
+
persistSoon();
|
|
57
|
+
});
|
|
58
|
+
for (const event of ['messages.update', 'messages.delete', 'chats.update', 'chats.upsert', 'chats.delete', 'contacts.update', 'contacts.upsert']) {
|
|
59
|
+
sock.ev.on(event, persistSoon);
|
|
60
|
+
}
|
|
61
|
+
sock.ev.on('connection.update', ({ connection, qr, lastDisconnect }) => {
|
|
62
|
+
if (qr) qrcode.generate(qr, { small: true });
|
|
63
|
+
if (connection === 'open') {
|
|
64
|
+
logger.info('Conectado. Los datos locales ya están disponibles; el historial remoto llega de forma asíncrona.');
|
|
65
|
+
// Reset backoff only after a stable connection to prevent rapid open/close loops.
|
|
66
|
+
const currentSocket = sock;
|
|
67
|
+
const stable = setTimeout(() => { if (sock === currentSocket && !shuttingDown) attempts = 0; }, 60000);
|
|
68
|
+
stable.unref();
|
|
69
|
+
}
|
|
70
|
+
if (connection !== 'close' || shuttingDown) return;
|
|
71
|
+
const error = lastDisconnect?.error;
|
|
72
|
+
const code = error?.output?.statusCode ?? error?.statusCode;
|
|
73
|
+
if (terminalCodes.has(code) || attempts >= 8) {
|
|
74
|
+
logger.error({ code, attempts }, 'Reconexión detenida. Revisa la cuenta o sesión manualmente; no se borran credenciales.');
|
|
75
|
+
shutdown(1).catch(fatal => { logger.error({ fatal }); process.exitCode = 1; });
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const delay = code === 515 ? 1000 : Math.min(60000, 2000 * 2 ** attempts) + Math.floor(Math.random() * 1000);
|
|
79
|
+
attempts++;
|
|
80
|
+
clearTimeout(reconnectTimer);
|
|
81
|
+
logger.warn({ code, delay, attempts }, 'Reconexión limitada con espera progresiva');
|
|
82
|
+
reconnectTimer = setTimeout(() => connect().catch(fatal => {
|
|
83
|
+
logger.error({ fatal }, 'No se pudo reconectar');
|
|
84
|
+
shutdown(1).catch(error => { logger.error({ error }); process.exitCode = 1; });
|
|
85
|
+
}), delay);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async function shutdown(code = 0) {
|
|
89
|
+
if (shuttingDown) return;
|
|
90
|
+
shuttingDown = true;
|
|
91
|
+
clearTimeout(reconnectTimer); clearTimeout(saveTimer);
|
|
92
|
+
sock?.end(new Error('Cierre solicitado'));
|
|
93
|
+
await store.writeToFileAsync(storeFile);
|
|
94
|
+
// No logout(): closing the example must not unlink the device.
|
|
95
|
+
process.exitCode = code;
|
|
96
|
+
}
|
|
97
|
+
for (const signal of ['SIGINT', 'SIGTERM']) process.once(signal, () => {
|
|
98
|
+
shutdown().catch(error => { logger.error({ error }); process.exitCode = 1; });
|
|
99
|
+
});
|
|
100
|
+
connect().catch(error => { logger.error({ error }, 'Error de arranque; conserva tu carpeta de sesión y revisa el problema'); process.exitCode = 1; });
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Import this helper in your bot; it does not connect or send by itself.
|
|
3
|
+
async function sendEvent(conn, jid, options = {}) {
|
|
4
|
+
const startTime = options.startTime ?? String(Math.floor(Date.now() / 1000) + 86400);
|
|
5
|
+
const eventMessage = {
|
|
6
|
+
contextInfo: {},
|
|
7
|
+
isCanceled: false,
|
|
8
|
+
name: options.name || 'Texto',
|
|
9
|
+
location: options.location || { degreesLatitude: 0, degreesLongitude: 0 },
|
|
10
|
+
startTime,
|
|
11
|
+
extraGuestsAllowed: false,
|
|
12
|
+
isScheduleCall: false,
|
|
13
|
+
hasReminder: true,
|
|
14
|
+
reminderOffsetSec: '3600'
|
|
15
|
+
};
|
|
16
|
+
// The library prepares the missing MessageContextInfo.messageSecret.
|
|
17
|
+
// For local persistence / reply-to events, prefer conn.sendMessage(jid, { event: eventMessage }).
|
|
18
|
+
return conn.relayMessage(jid, { eventMessage }, {});
|
|
19
|
+
}
|
|
20
|
+
module.exports = { sendEvent };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
KAGE BAILEYS 1.1.4 — MANTENIMIENTO
|
|
2
|
+
Fecha de validación: 2026-10-21
|
|
3
|
+
|
|
4
|
+
ALCANCE REAL
|
|
5
|
+
Proyecto completo, no un parche aislado. Se conservan los módulos originales de botones, álbumes, newsletters, Meta AI, comunidades y VoIP. Conservarlos no significa que se hayan verificado contra WhatsApp. Las pruebas incluidas son locales y no utilizan una cuenta real. No se garantiza funcionamiento perpetuo, compatibilidad con cualquier dependencia ni ausencia de restricciones de cuenta.
|
|
6
|
+
|
|
7
|
+
INSTALACIÓN
|
|
8
|
+
Se requiere Node.js >=20.18.1. Recomendado Node.js 22 LTS.
|
|
9
|
+
Dentro de la carpeta kage-baileys:
|
|
10
|
+
npm ci --omit=optional
|
|
11
|
+
npm run check
|
|
12
|
+
npm run example
|
|
13
|
+
No se incluyen node_modules ni credenciales. package-lock.json fija las versiones resueltas. Para uso como dependencia local: npm install /ruta/a/kage-baileys
|
|
14
|
+
Para instalar solo el núcleo: npm ci --omit=optional --omit=dev
|
|
15
|
+
Opcionales nativos: sharp, audio-decode, @roamhq/wrtc y whatsapp-rust-bridge pueden requerir instalación específica para la plataforma. FFmpeg debe estar instalado para las funciones que ejecutan el binario. No se han probado llamadas reales ni todos los módulos opcionales.
|
|
16
|
+
|
|
17
|
+
ESQUEMA ÚNICO
|
|
18
|
+
WAProto/WAProto.proto es la única fuente. Se eliminaron WAProto.kage-original.proto e index.kage-original.js para evitar divergencias. Se regeneraron index.js e index.d.ts con protobufjs 8.8.1 y protobufjs-cli 2.7.1.
|
|
19
|
+
Se restauraron campos de avatar de bot, dominios de clave multimedia, parámetros de pago y asociaciones de difusión.
|
|
20
|
+
El tag 114 antiguo de pollResultSnapshotMessageV3 se conserva como pollResultSnapshotMessageV3Legacy; el tag 115 sigue siendo el nombre canónico. No se inventan ni duplican tags. Para enviar al protocolo actual, utiliza el nombre canónico.
|
|
21
|
+
oldestMessageTimestamp conserva compatibilidad JavaScript con oldestMessageTimestampInWindow (tag 2). Los nombres de enum antiguos también se conservan.
|
|
22
|
+
maintenance/schema-coverage.json verifica todos los tipos, campos, números y valores enum de ambos esquemas fuente, con estas dos excepciones explícitas y sin errores de cobertura.
|
|
23
|
+
Regeneración reproducible: npm run gen:protobuf. Tipos públicos: npm run gen:types. Los extras JavaScript mantienen tipos any; no se presenta esto como tipado estricto de todos los módulos.
|
|
24
|
+
|
|
25
|
+
EVENTOS
|
|
26
|
+
relayMessage(jid, { eventMessage: {...} }, {}) y sendMessage(jid, { event: {...} }) preparan MessageContextInfo.messageSecret de 32 bytes. Se preservan secretos aportados y se validan nombre, timestamps, booleanos, coordenadas y recordatorio. No se regeneran claves existentes.
|
|
27
|
+
Se conservan hasReminder y reminderOffsetSec, además de los valores false. Un recordatorio activado sin offset utiliza 3600 segundos. El cliente receptor y el servidor deciden el soporte y la visualización final.
|
|
28
|
+
El valor 1792544400 corresponde a 2026-10-21T01:00:00.000Z; es una fecha fija, no la hora actual. Para nuevos eventos usa un timestamp futuro en segundos. No se rechazan eventos pasados válidos, para permitir historial y ediciones.
|
|
29
|
+
Example/event.cjs contiene un helper que usa relayMessage. Example/connection.cjs restaura el almacén y proporciona getMessage para reintentos. Para conservar eventos propios automáticamente, se recomienda sendMessage({ event }).
|
|
30
|
+
Se corrigen menciones y mezcla de contextInfo sin copiar el mensaje completo dentro de contextInfo.
|
|
31
|
+
|
|
32
|
+
HISTORIAL Y LATENCIA
|
|
33
|
+
El store ya no descarta ON_DEMAND. Los fragmentos históricos se fusionan por defecto para no borrar mensajes recibidos en vivo. Para recuperar el borrado antiguo: makeInMemoryStore({ resetOnHistorySync: true }).
|
|
34
|
+
El procesamiento no muta las conversaciones recibidas, evita filas malformadas y selecciona el mensaje más reciente por timestamp.
|
|
35
|
+
Las escrituras del store preservan buffers y son atómicas. Nuevo writeToFileAsync serializa escrituras a disco. El ejemplo carga los datos guardados antes de esperar al servidor y guarda con debounce.
|
|
36
|
+
Se corrige flush(true) para no dejar el contador de eventos atascado. initialSyncTimeoutMs es configurable; por defecto conserva 20000 ms, el ejemplo utiliza 5000 ms. No se fuerzan flush automáticos que rompan la sincronización de claves.
|
|
37
|
+
No se puede obtener historial remoto instantáneo: depende de WhatsApp, la conexión, la cuenta y el volumen. Si no existe caché local, la primera descarga necesita tiempo.
|
|
38
|
+
|
|
39
|
+
SESIÓN Y RECONEXIÓN
|
|
40
|
+
Los archivos de autenticación se guardan con temporal + rename y permisos restrictivos en archivos nuevos. Una sesión corrupta ahora produce un error explícito; no se genera silenciosamente una identidad nueva. Conserva una copia de seguridad cifrada de tu carpeta de sesión.
|
|
41
|
+
El ejemplo limita reconexiones a ocho intentos, usa espera exponencial y se detiene ante cierre de sesión, prohibición, sesión reemplazada o sesión inválida. No borra credenciales ni ejecuta logout al cerrar. Esto reduce bucles accidentales, no evita medidas de WhatsApp. No hagas spam ni contactes personas sin consentimiento.
|
|
42
|
+
|
|
43
|
+
DEPENDENCIAS
|
|
44
|
+
Se corrigió la dependencia ESM p-queue mediante la versión CommonJS 6.6.2 y lru-cache 10.4.3. Se actualizaron protobufjs, file-type, Jimp, music-metadata, link-preview-js y uuid; se adaptaron sus rutas y APIs. Jimp funciona como alternativa sin sharp.
|
|
45
|
+
maintenance/dependency-audit.json recoge npm audit --omit=dev --omit=optional. Su alcance es el núcleo instalado, no módulos nativos no instalados; cero avisos conocidos no significa ausencia de toda vulnerabilidad.
|
|
46
|
+
No se ejecuta npm audit fix --force ni se promete compatibilidad con versiones arbitrarias de dependencias. Para reproducibilidad utiliza npm ci y el lockfile.
|
|
47
|
+
|
|
48
|
+
PRUEBAS Y LÍMITES
|
|
49
|
+
Las pruebas cubren esquema único, campos restaurados, dos tags históricos de encuestas, fechas int64, ejemplo de evento completo, secretos, menciones, otros tipos básicos de mensaje, historia, persistencia, sesión, imágenes, audio, buffering y relay con cifrado simulado.
|
|
50
|
+
No se ha verificado una entrega real, la interfaz de Android/iOS/Web ni los recordatorios programados por WhatsApp. No se conoce el comportamiento de tu cuenta ni las restricciones del servidor.
|
|
51
|
+
|
|
52
|
+
REFERENCIAS
|
|
53
|
+
https://baileys.wiki/advanced/history-sync
|
|
54
|
+
https://github.com/WhiskeySockets/Baileys/issues/2468
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
cd "$(dirname "$0")/.."
|
|
4
|
+
node scripts/generate-protobuf.cjs
|
package/WAProto/WAProto.proto
CHANGED
|
@@ -621,6 +621,8 @@ message BotMessageSharingInfo {
|
|
|
621
621
|
}
|
|
622
622
|
|
|
623
623
|
message BotMetadata {
|
|
624
|
+
optional BotAvatarMetadata avatarMetadata = 1;
|
|
625
|
+
|
|
624
626
|
optional string personaId = 2;
|
|
625
627
|
optional BotPluginMetadata pluginMetadata = 3;
|
|
626
628
|
optional BotSuggestedPromptMetadata suggestedPromptMetadata = 4;
|
|
@@ -729,6 +731,10 @@ message BotModeSelectionMetadata {
|
|
|
729
731
|
repeated BotUserSelectionMode mode = 1;
|
|
730
732
|
repeated uint32 overrideMode = 2;
|
|
731
733
|
enum BotUserSelectionMode {
|
|
734
|
+
option allow_alias = true;
|
|
735
|
+
UNKNOWN_MODE = 0;
|
|
736
|
+
REASONING_MODE = 1;
|
|
737
|
+
|
|
732
738
|
DEFAULT_MODE = 0;
|
|
733
739
|
THINK_HARD_MODE = 1;
|
|
734
740
|
}
|
|
@@ -2245,6 +2251,17 @@ message MemberLabel {
|
|
|
2245
2251
|
}
|
|
2246
2252
|
|
|
2247
2253
|
message Message {
|
|
2254
|
+
enum MediaKeyDomain {
|
|
2255
|
+
UNSET = 0;
|
|
2256
|
+
E2EE_CHAT = 1;
|
|
2257
|
+
STATUS = 2;
|
|
2258
|
+
CAPI = 3;
|
|
2259
|
+
BOT = 4;
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
// Historical wire tag retained separately; never encode both versions together.
|
|
2263
|
+
optional PollResultSnapshotMessage pollResultSnapshotMessageV3Legacy = 114;
|
|
2264
|
+
|
|
2248
2265
|
optional string conversation = 1;
|
|
2249
2266
|
optional SenderKeyDistributionMessage senderKeyDistributionMessage = 2;
|
|
2250
2267
|
optional ImageMessage imageMessage = 3;
|
|
@@ -2389,6 +2406,8 @@ message Message {
|
|
|
2389
2406
|
}
|
|
2390
2407
|
|
|
2391
2408
|
message AudioMessage {
|
|
2409
|
+
optional Message.MediaKeyDomain mediaKeyDomain = 23;
|
|
2410
|
+
|
|
2392
2411
|
optional string url = 1;
|
|
2393
2412
|
optional string mimetype = 2;
|
|
2394
2413
|
optional bytes fileSha256 = 3;
|
|
@@ -2588,6 +2607,8 @@ message Message {
|
|
|
2588
2607
|
}
|
|
2589
2608
|
|
|
2590
2609
|
message DocumentMessage {
|
|
2610
|
+
optional Message.MediaKeyDomain mediaKeyDomain = 22;
|
|
2611
|
+
|
|
2591
2612
|
optional string url = 1;
|
|
2592
2613
|
optional string mimetype = 2;
|
|
2593
2614
|
optional string title = 3;
|
|
@@ -2848,6 +2869,8 @@ message Message {
|
|
|
2848
2869
|
MESSAGE_ACCESS_STATUS = 8;
|
|
2849
2870
|
}
|
|
2850
2871
|
message ImageMessage {
|
|
2872
|
+
optional Message.MediaKeyDomain mediaKeyDomain = 33;
|
|
2873
|
+
|
|
2851
2874
|
optional string url = 1;
|
|
2852
2875
|
optional string mimetype = 2;
|
|
2853
2876
|
optional string caption = 3;
|
|
@@ -3143,6 +3166,8 @@ message Message {
|
|
|
3143
3166
|
}
|
|
3144
3167
|
|
|
3145
3168
|
message MMSThumbnailMetadata {
|
|
3169
|
+
optional Message.MediaKeyDomain mediaKeyDomain = 8;
|
|
3170
|
+
|
|
3146
3171
|
optional string thumbnailDirectPath = 1;
|
|
3147
3172
|
optional bytes thumbnailSha256 = 2;
|
|
3148
3173
|
optional bytes thumbnailEncSha256 = 3;
|
|
@@ -3220,6 +3245,8 @@ message Message {
|
|
|
3220
3245
|
}
|
|
3221
3246
|
|
|
3222
3247
|
message PaymentExtendedMetadata {
|
|
3248
|
+
optional string messageParamsJson = 3;
|
|
3249
|
+
|
|
3223
3250
|
optional uint32 type = 1;
|
|
3224
3251
|
optional string platform = 2;
|
|
3225
3252
|
}
|
|
@@ -3786,6 +3813,8 @@ message Message {
|
|
|
3786
3813
|
}
|
|
3787
3814
|
|
|
3788
3815
|
message StickerMessage {
|
|
3816
|
+
optional Message.MediaKeyDomain mediaKeyDomain = 23;
|
|
3817
|
+
|
|
3789
3818
|
optional string url = 1;
|
|
3790
3819
|
optional bytes fileSha256 = 2;
|
|
3791
3820
|
optional bytes fileEncSha256 = 3;
|
|
@@ -3915,6 +3944,8 @@ message Message {
|
|
|
3915
3944
|
}
|
|
3916
3945
|
|
|
3917
3946
|
message VideoMessage {
|
|
3947
|
+
optional Message.MediaKeyDomain mediaKeyDomain = 32;
|
|
3948
|
+
|
|
3918
3949
|
optional string url = 1;
|
|
3919
3950
|
optional string mimetype = 2;
|
|
3920
3951
|
optional bytes fileSha256 = 3;
|
|
@@ -4792,6 +4823,8 @@ message SyncActionData {
|
|
|
4792
4823
|
}
|
|
4793
4824
|
|
|
4794
4825
|
message SyncActionValue {
|
|
4826
|
+
optional BusinessBroadcastAssociationAction businessBroadcastAssociationAction = 65;
|
|
4827
|
+
|
|
4795
4828
|
optional int64 timestamp = 1;
|
|
4796
4829
|
optional StarAction starAction = 2;
|
|
4797
4830
|
optional ContactAction contactAction = 3;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
module.exports = function applyCompatibility(proto) {
|
|
3
|
+
const Type = proto.Message.MessageHistoryMetadata;
|
|
4
|
+
Object.defineProperty(Type.prototype, 'oldestMessageTimestamp', {
|
|
5
|
+
configurable: true,
|
|
6
|
+
get() { return this.oldestMessageTimestampInWindow; },
|
|
7
|
+
set(value) { this.oldestMessageTimestampInWindow = value; }
|
|
8
|
+
});
|
|
9
|
+
const fromObject = Type.fromObject;
|
|
10
|
+
Type.fromObject = function (object) {
|
|
11
|
+
if (object && object.oldestMessageTimestampInWindow == null && object.oldestMessageTimestamp != null) {
|
|
12
|
+
object = { ...object, oldestMessageTimestampInWindow: object.oldestMessageTimestamp };
|
|
13
|
+
}
|
|
14
|
+
return fromObject.call(this, object);
|
|
15
|
+
};
|
|
16
|
+
};
|
package/WAProto/fix-imports.js
CHANGED
|
@@ -1,81 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const filePath = './index.js'
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
let content = readFileSync(filePath, 'utf8')
|
|
8
|
-
|
|
9
|
-
content = content.replace(/import \* as (\$protobuf) from/g, 'import $1 from')
|
|
10
|
-
content = content.replace(/(['"])protobufjs\/minimal(['"])/g, '$1protobufjs/minimal.js$2')
|
|
11
|
-
|
|
12
|
-
const marker = 'const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});\n\n'
|
|
13
|
-
const longToStringHelper =
|
|
14
|
-
'function longToString(value, unsigned) {\n' +
|
|
15
|
-
'\tif (typeof value === "string") {\n' +
|
|
16
|
-
'\t\treturn value;\n' +
|
|
17
|
-
'\t}\n' +
|
|
18
|
-
'\tif (typeof value === "number") {\n' +
|
|
19
|
-
'\t\treturn String(value);\n' +
|
|
20
|
-
'\t}\n' +
|
|
21
|
-
'\tif (!$util.Long) {\n' +
|
|
22
|
-
'\t\treturn String(value);\n' +
|
|
23
|
-
'\t}\n' +
|
|
24
|
-
'\tconst normalized = $util.Long.fromValue(value);\n' +
|
|
25
|
-
'\tconst prepared = unsigned && normalized && typeof normalized.toUnsigned === "function"\n' +
|
|
26
|
-
'\t\t? normalized.toUnsigned()\n' +
|
|
27
|
-
'\t\t: normalized;\n' +
|
|
28
|
-
'\treturn prepared.toString();\n' +
|
|
29
|
-
'}\n\n'
|
|
30
|
-
const longToNumberHelper =
|
|
31
|
-
'function longToNumber(value, unsigned) {\n' +
|
|
32
|
-
'\tif (typeof value === "number") {\n' +
|
|
33
|
-
'\t\treturn value;\n' +
|
|
34
|
-
'\t}\n' +
|
|
35
|
-
'\tif (typeof value === "string") {\n' +
|
|
36
|
-
'\t\tconst numeric = Number(value);\n' +
|
|
37
|
-
'\t\treturn numeric;\n' +
|
|
38
|
-
'\t}\n' +
|
|
39
|
-
'\tif (!$util.Long) {\n' +
|
|
40
|
-
'\t\treturn Number(value);\n' +
|
|
41
|
-
'\t}\n' +
|
|
42
|
-
'\tconst normalized = $util.Long.fromValue(value);\n' +
|
|
43
|
-
'\tconst prepared = unsigned && normalized && typeof normalized.toUnsigned === "function"\n' +
|
|
44
|
-
'\t\t? normalized.toUnsigned()\n' +
|
|
45
|
-
'\t\t: typeof normalized.toSigned === "function"\n' +
|
|
46
|
-
'\t\t\t? normalized.toSigned()\n' +
|
|
47
|
-
'\t\t\t: normalized;\n' +
|
|
48
|
-
'\treturn prepared.toNumber();\n' +
|
|
49
|
-
'}\n\n'
|
|
50
|
-
|
|
51
|
-
if (!content.includes('function longToString(')) {
|
|
52
|
-
const markerIndex = content.indexOf(marker)
|
|
53
|
-
if (markerIndex === -1) {
|
|
54
|
-
throw new Error('Unable to inject Long helpers: marker not found in WAProto index output')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
content = content.replace(marker, `${marker}${longToStringHelper}${longToNumberHelper}`)
|
|
58
|
-
} else {
|
|
59
|
-
const longToStringRegex = /function longToString\(value, unsigned\) {\n[\s\S]*?\n}\n\n/
|
|
60
|
-
const longToNumberRegex = /function longToNumber\(value, unsigned\) {\n[\s\S]*?\n}\n\n/
|
|
61
|
-
|
|
62
|
-
if (!longToStringRegex.test(content) || !longToNumberRegex.test(content)) {
|
|
63
|
-
throw new Error('Unable to update Long helpers: existing definitions not found')
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
content = content.replace(longToStringRegex, longToStringHelper)
|
|
67
|
-
content = content.replace(longToNumberRegex, longToNumberHelper)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const longPattern = /([ \t]+d\.(\w+) = )o\.longs === String \? \$util\.Long\.prototype\.toString\.call\(m\.\2\) : o\.longs === Number \? new \$util\.LongBits\(m\.\2\.low >>> 0, m\.\2\.high >>> 0\)\.toNumber\((true)?\) : m\.\2;/g
|
|
71
|
-
content = content.replace(longPattern, (_match, prefix, field, unsignedFlag) => {
|
|
72
|
-
const unsignedArg = unsignedFlag ? ', true' : ''
|
|
73
|
-
return `${prefix}o.longs === String ? longToString(m.${field}${unsignedArg}) : o.longs === Number ? longToNumber(m.${field}${unsignedArg}) : m.${field};`
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
writeFileSync(filePath, content, 'utf8')
|
|
77
|
-
console.log(`✅ Fixed imports in ${filePath}`)
|
|
78
|
-
} catch (error) {
|
|
79
|
-
console.error(`❌ Error fixing imports: ${error.message}`)
|
|
80
|
-
exit(1)
|
|
81
|
-
}
|
|
1
|
+
'use strict';
|
|
2
|
+
// CommonJS is generated directly; retained as a backwards-compatible command.
|
|
3
|
+
require('../scripts/generate-protobuf.cjs');
|