arregladas incompatibilidades despues del merge, y ahora ya funciona bien esta vaina

This commit is contained in:
2025-06-06 14:55:08 -06:00
parent 54ef965009
commit 3bd2922e9d
8 changed files with 10451 additions and 142 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -9,12 +9,17 @@
"start": "node dist/index.js"
},
"dependencies": {
"@google/genai": "^1.4.0",
"@open-wa/wa-automate": "^4.76.0",
"axios": "^1.5.0",
"dotenv": "^16.5.0",
"express": "^4.18.2"
"express": "^4.18.2",
"ffmpeg-static": "^5.2.0",
"fluent-ffmpeg": "^2.1.3"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/fluent-ffmpeg": "^2.1.27",
"@types/node": "^20.11.19",
"nodemon": "^3.1.10",
"ts-node": "^10.9.2",

View File

@@ -79,11 +79,11 @@ export async function buildConversation(chatId: string, openWaUrl: string): Prom
const conversation: Conversation = {
chatId,
title: chat?.formattedTitle ?? chat?.name ?? chatId,
isGroup: Boolean(chat?.isGroup),
unreadCount: chat?.unreadCount ?? 0,
participants: buildParticipants(raw, chat),
messages: raw.slice(-20).map(toMsg).sort((a, b) => a.ts - b.ts),
title,
isGroup,
unreadCount,
participants: Array.from(participantsMap.values()),
messages,
createdAt: conversations.get(chatId)?.createdAt || now,
};
@@ -124,5 +124,6 @@ export async function addMessageToConversation(
isMe: Boolean(s.isMe),
});
}
return conv;
}

View File

@@ -0,0 +1,55 @@
// transcribeAudioMessage.ts
import { WhatsAppMessage } from './types';
import { decryptMedia } from '@open-wa/wa-automate';
import axios from 'axios';
import { GoogleGenAI, createUserContent } from '@google/genai';
/**
* Transcribe un mensaje de audio de WhatsApp usando Gemini.
* @param message - Mensaje recibido desde OpenWA.
* @returns Texto transcrito o null si no era un audio válido.
*/
export async function transcribeAudioMessage(message: WhatsAppMessage): Promise<string | null> {
if (
message.type !== 'ptt' &&
message.type !== 'audio' &&
message.mimetype !== 'audio/ogg; codecs=opus'
) {
return null;
}
const audioUrl = message.clientUrl || message.deprecatedMms3Url;
if (!audioUrl) throw new Error('El mensaje no tiene URL de audio');
const raw = await axios.get(audioUrl, { responseType: 'arraybuffer' });
const enrichedMessage = {
...message,
_data: {
...message,
_raw: raw.data
}
};
const decryptedBuffer = await decryptMedia(enrichedMessage as any);
const base64Audio = decryptedBuffer.toString('base64');
const apiKey = process.env.GOOGLE_API_KEY;
if (!apiKey) throw new Error('Falta GOOGLE_API_KEY');
const genAI = new GoogleGenAI({ apiKey });
const result = await genAI.models.generateContent({
model: 'gemini-2.0-flash',
contents: createUserContent([
{
inlineData: {
mimeType: 'audio/ogg',
data: base64Audio
}
},
'Transcribí este audio porfa. te estaran hablando en español honduras.'
])
});
return result.text?.trim() || null;
}

View File

@@ -191,6 +191,9 @@ export interface WhatsAppMessage {
chatId: string;
mediaData: Record<string, unknown>;
text: string;
clientUrl?: string;
deprecatedMms3Url?: string;
mimetype?: string;
}
export interface Participant {

View File

@@ -1,8 +1,10 @@
import express, { Application } from 'express';
import axios from 'axios';
import { GoogleGenAI } from '@google/genai';
import { getHandler } from './chatHandlers';
import { addMessageToConversation } from './store/conversation';
import { WhatsAppMessage, Conversation } from './types';
import { transcribeAudioMessage } from './transcribeAudioMessage';
export interface WebhookConfig {
API_URL: string;
@@ -31,6 +33,12 @@ export function registerWebhookRoutes(
if (message) {
const origen = from || message.chatId || 'desconocido';
if(origen == '50493849962@c.us') //si el mensajes es de un agente, no lo proceses
{
return res.sendStatus(200);
}
console.log(`📩 Mensaje recibido (${message.text}) de ${origen}`);
}
@@ -38,6 +46,39 @@ export function registerWebhookRoutes(
if (!message) return res.sendStatus(200);
if (!openWaUrl) throw new Error('Service URLs not configured');
const chatId = message.chatId || from;
// Audio message handling
// console.log(message);
if (
message.type === 'ptt' &&
message.mimetype === 'audio/ogg; codecs=opus'
) {
const audioUrl = message.clientUrl || message.deprecatedMms3Url;
if (!audioUrl) {
console.error('No audio URL found for PTT message');
// Potentially send a message to user or just skip? For now, skip.
return res.sendStatus(200);
}
console.log('🎤 Mensaje de audio detectado', audioUrl);
try {
const transcript = await transcribeAudioMessage(message);
console.log('📝 Transcripción:', transcript);
message.body = transcript || '';
message.text = transcript || '';
} catch (transcriptionError: any) {
console.error('Error en la transcripción:', transcriptionError.message);
const reply =
"I received an audio message, but I couldn't transcribe it. Please send the transcript manually.";
await axios.post(`${openWaUrl}/sendText`, { args: { to: from, content: reply } });
// Stop processing this message as transcription failed and user has been notified.
return res.sendStatus(200);
}
}
console.log(message);
let conv: Conversation | undefined;
if (chatId) {
try {