Revert "separacion de respuesta para mejor handeleo"
Some checks failed
build-and-push / build (push) Has been cancelled
Some checks failed
build-and-push / build (push) Has been cancelled
This reverts commit 50aee19c85.
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
/*───────────────────────────────────────────────────────────────*/
|
||||
|
||||
export const config = {
|
||||
VERSION : '0.6.12',
|
||||
VERSION : '0.6.02',
|
||||
API_URL : process.env.BOT_API_URL ?? 'http://whatsapp-bot:8002',
|
||||
GROUP_ID : process.env.GROUP_ID ?? '120363203056794284@g.us',
|
||||
REPLY_MSG : process.env.REPLY_MSG ?? 'que pedos',
|
||||
|
||||
@@ -1,37 +1,83 @@
|
||||
// handlers.js
|
||||
import fs from 'fs/promises';
|
||||
import { log } from './logger.js';
|
||||
// Ya no se necesitan: sendText, fetchChatMessages, setTypingStatus, askGemini aquí
|
||||
import {
|
||||
sendText,
|
||||
fetchChatMessages,
|
||||
setTypingStatus
|
||||
} from './whatsapp.js';
|
||||
import { askGemini } from './gemini.js';
|
||||
import { processMessage } from './utils/processMessage.js';
|
||||
import { saveMedia } from './utils/saveMedia.js';
|
||||
import { respuestaNormal } from './respuesta/respuestaNormal.js'; // <- NUEVA IMPORTACIÓN
|
||||
import { saveMedia } from './utils/saveMedia.js'; // ← NUEVO
|
||||
|
||||
/* carpeta raíz donde saveMedia deja todo */
|
||||
const MEDIA_DIR = '/media';
|
||||
await fs.mkdir(MEDIA_DIR, { recursive: true });
|
||||
|
||||
// La función cleanForGemini se movió a respuestaNormal.js
|
||||
/* Quita campos pesados antes de mandar a Gemini */
|
||||
const cleanForGemini = ({ media, reactions, preview, ...rest }) => rest;
|
||||
|
||||
export async function processIncoming(raw) {
|
||||
// Guarda media si no es un mensaje de texto plano
|
||||
if (raw.type !== 'chat') {
|
||||
try {
|
||||
// Nota: saveMedia podría necesitar acceso a MEDIA_DIR si no está codificado internamente
|
||||
await saveMedia(raw /*, MEDIA_DIR */); // Podrías necesitar pasar MEDIA_DIR si saveMedia lo requiere
|
||||
} catch (error) {
|
||||
log('error', 'Error guardando media:', error);
|
||||
}
|
||||
}
|
||||
if (raw.type !== 'chat') await saveMedia(raw);
|
||||
|
||||
const msg = processMessage(raw);
|
||||
const text = msg.text || '';
|
||||
|
||||
/* ----- comando @nucleo ----- */
|
||||
if (/^@nucleo(\s|$)/i.test(text)) {
|
||||
// Llama a la función importada
|
||||
await respuestaNormal(msg); // <- LLAMADA A LA FUNCIÓN EXTERNA
|
||||
} else {
|
||||
// Lógica para otros mensajes (si aplica)
|
||||
// log('debug', 'Mensaje recibido no es comando @nucleo:', text);
|
||||
setTypingStatus(msg.chatId, true);
|
||||
log('info', '🧠 Generando respuesta…');
|
||||
|
||||
/* 1) historial completo del chat */
|
||||
const allraw = await fetchChatMessages(msg.chatId);
|
||||
const allMsgs = allraw.map(processMessage);
|
||||
|
||||
/* 2) recorta contexto a ≤100 kB */
|
||||
const context = allMsgs.map(cleanForGemini);
|
||||
let json = JSON.stringify(context);
|
||||
while (json.length > 100_000 && context.length) {
|
||||
context.shift();
|
||||
json = JSON.stringify(context);
|
||||
}
|
||||
|
||||
/* 3) prompt */
|
||||
const prompt = [
|
||||
`Eres el asistente del grupo "${context[0]?.chatName ?? 'chat'}".`,
|
||||
`Pregunta del usuario: ${text}`
|
||||
, ...context];
|
||||
|
||||
/* 4) procesa medias y respeta el límite de 20 MB */
|
||||
const medias = allraw.filter(m => m.type !== 'chat');
|
||||
const settled = await Promise.allSettled(medias.map(saveMedia));
|
||||
|
||||
const MAX = 20 * 1024 * 1024; // 20 MB
|
||||
let total = 0;
|
||||
const files = {};
|
||||
|
||||
for (const r of settled) {
|
||||
if (r.status !== 'fulfilled' || !r.value) continue;
|
||||
|
||||
const [msgId, obj] = Object.entries(r.value)[0];
|
||||
let size = Number(obj.sizeBytes || 0);
|
||||
|
||||
if (!size && obj.filePath) {
|
||||
try { size = (await fs.stat(obj.filePath)).size; }
|
||||
catch { size = 0; }
|
||||
}
|
||||
|
||||
if (total + size > MAX && total > 0) break;
|
||||
|
||||
total += size;
|
||||
files[msgId] = { uri: obj.uri || obj.filePath, mimeType: obj.mimeType };
|
||||
}
|
||||
|
||||
// log('info', '🧠 Enviando a Gemini...', { files });
|
||||
|
||||
/* 5) llama a Gemini y responde */
|
||||
const respuesta = await askGemini(prompt, files );
|
||||
await sendText(msg.chatId, respuesta);
|
||||
|
||||
setTypingStatus(msg.chatId, false);
|
||||
log('info', '🧠 Respuesta enviada');
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
// /respuesta/respuestaNormal.js
|
||||
import fs from 'fs/promises';
|
||||
import { log } from '../logger.js'; // <- Nota el '../'
|
||||
import {
|
||||
sendText,
|
||||
fetchChatMessages,
|
||||
setTypingStatus
|
||||
} from '../whatsapp.js'; // <- Nota el '../'
|
||||
import { askGemini } from '../gemini.js'; // <- Nota el '../'
|
||||
import { processMessage } from '../utils/processMessage.js'; // <- Nota el '../'
|
||||
import { saveMedia } from '../utils/saveMedia.js'; // <- Nota el '../'
|
||||
|
||||
/* Quita campos pesados antes de mandar a Gemini */
|
||||
const cleanForGemini = ({ media, reactions, preview, ...rest }) => rest;
|
||||
|
||||
/**
|
||||
* Procesa la lógica específica para el comando @nucleo.
|
||||
* Obtiene el historial, prepara el contexto, procesa media,
|
||||
* llama a Gemini y envía la respuesta.
|
||||
* @param {object} msg - El objeto de mensaje procesado.
|
||||
*/
|
||||
export async function respuestaNormal(msg) {
|
||||
const text = msg.text || ''; // Necesitamos el texto original aquí también
|
||||
|
||||
setTypingStatus(msg.chatId, true);
|
||||
log('info', '🧠 Generando respuesta para @nucleo…');
|
||||
|
||||
try {
|
||||
/* 1) historial completo del chat */
|
||||
const allraw = await fetchChatMessages(msg.chatId);
|
||||
const allMsgs = allraw.map(processMessage);
|
||||
|
||||
/* 2) recorta contexto a ≤100 kB */
|
||||
const context = allMsgs.map(cleanForGemini);
|
||||
let json = JSON.stringify(context);
|
||||
while (json.length > 100_000 && context.length) {
|
||||
context.shift();
|
||||
json = JSON.stringify(context);
|
||||
}
|
||||
|
||||
// Asegurarse de que el contexto no esté vacío antes de acceder a context[0]
|
||||
const chatName = context.length > 0 ? context[0]?.chatName : 'chat';
|
||||
|
||||
/* 3) prompt */
|
||||
const prompt = [
|
||||
`Eres el asistente del grupo "${chatName}".`,
|
||||
`Pregunta del usuario: ${text}` // Usamos el 'text' del mensaje original que activó el comando
|
||||
, ...context];
|
||||
|
||||
/* 4) procesa medias y respeta el límite de 20 MB */
|
||||
// Filtrar solo los mensajes que no son de tipo 'chat' del historial obtenido
|
||||
const medias = allraw.filter(m => m.type !== 'chat');
|
||||
const settled = await Promise.allSettled(medias.map(saveMedia));
|
||||
|
||||
const MAX = 20 * 1024 * 1024; // 20 MB
|
||||
let total = 0;
|
||||
const files = {};
|
||||
|
||||
for (const r of settled) {
|
||||
if (r.status !== 'fulfilled' || !r.value) continue;
|
||||
|
||||
if (typeof r.value !== 'object' || r.value === null) continue;
|
||||
const entries = Object.entries(r.value);
|
||||
if (entries.length === 0) continue;
|
||||
const [msgId, obj] = entries[0];
|
||||
if (typeof obj !== 'object' || obj === null) continue;
|
||||
|
||||
let size = Number(obj.sizeBytes || 0);
|
||||
|
||||
if (!size && obj.filePath) {
|
||||
try { size = (await fs.stat(obj.filePath)).size; }
|
||||
catch { size = 0; }
|
||||
}
|
||||
|
||||
// Comprobar si añadir este archivo excede el límite MÁXIMO TOTAL
|
||||
// y si ya tenemos *algo* (total > 0) para evitar empezar con un archivo demasiado grande
|
||||
if (total + size > MAX && total > 0) break;
|
||||
// Si este archivo *por sí solo* excede el límite, saltarlo
|
||||
if (size > MAX) continue;
|
||||
|
||||
total += size;
|
||||
files[msgId] = { uri: obj.uri || obj.filePath, mimeType: obj.mimeType };
|
||||
}
|
||||
|
||||
// log('info', '🧠 Enviando a Gemini...', { files });
|
||||
|
||||
/* 5) llama a Gemini y responde */
|
||||
const respuesta = await askGemini(prompt, files);
|
||||
await sendText(msg.chatId, respuesta);
|
||||
|
||||
log('info', '🧠 Respuesta enviada');
|
||||
|
||||
} catch (error) {
|
||||
log('error', 'Error en respuestaNormal:', error);
|
||||
await sendText(msg.chatId, 'Hubo un error al procesar tu solicitud.');
|
||||
} finally {
|
||||
setTypingStatus(msg.chatId, false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user