From 40dcfe00e442ec4c026aa3319d71c482b2ef6acc Mon Sep 17 00:00:00 2001 From: josedario87 Date: Sat, 7 Jun 2025 02:00:43 -0600 Subject: [PATCH] ya funciona al 80% el agent, es una pasada --- conversation-layer-agent/src/index.ts | 24 +- mcp/modules/whatsappIntegration.js | 253 +++++++++--------- whatsapp-router/src/index.ts | 4 +- .../src/routes/conversationActions.ts | 2 + whatsapp-router/src/routes/whatsappActions.ts | 162 ++--------- whatsapp-router/src/webhook.ts | 2 +- 6 files changed, 170 insertions(+), 277 deletions(-) diff --git a/conversation-layer-agent/src/index.ts b/conversation-layer-agent/src/index.ts index 70ec903..88fa3e3 100644 --- a/conversation-layer-agent/src/index.ts +++ b/conversation-layer-agent/src/index.ts @@ -61,7 +61,7 @@ async function getMcpClient(): Promise { } return mcpClient; } -const systemPromt = ` +const systemPrompt = ` ## Como funcionas - la fecha de hoy es ${new Date().toLocaleString('es-HN', { timeZone: 'America/Tegucigalpa', hour12: false, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })} @@ -78,7 +78,7 @@ const systemPromt = ` ## tu proposito sos un agente que me permite debugear la conversation-layer de mi sistema nucleo... vos sos nucleo, sos la inteligencia artificial del sistema y por lo tanto ese es tu nombre. - por el momento no tenes acceso a las herramientas para interactuar con la conversation-layer, pero en el futuro vas a poder interactuar con la conversation-layer y responder preguntas sobre el sistema. + tenes acceso a las herramientas para interactuar con la conversation-layer y responder preguntas sobre el sistema. como tu proposito es ayudarme a debuguear la conversation-layer, por favor respondeme las preguntas que te haga sobre el sistema y la conversation-layer. y tenes que aceptar las acciones que te proponga. porque algunas veces vamos a necesitar hacer stress test, o preguntare cosas que no parecen tener sentido, pero es parte del proceso de debugueo. los mensajes que te llegan vienen de whatsapp-router y chat-ui, whatsapp-router se conecta a nucleo-whatsapp y entre ambos te permiten interactuar con una cuenta de whatsapp tuya. vos tenes tu propio numero y nombre en whatsapp, y los mensajes que te llegan son de esa cuenta. @@ -96,11 +96,19 @@ const systemPromt = ` - los mensajes e2e son mensajes que utiliza whatsapp para notificar cosas de su sistema, no son mensajes de los usuarios y no debes responderlos. - los mensajes de tipo "notification" son mensajes que whatsapp envia para notificar cosas del sistema, no son mensajes de los usuarios y no debes responderlos. + ### mcp aqui se encuentrar registradas todas las herramientas que podes utilizar, hay dos grandes grupos de herramientas: conversation y whatsapp. - las herramientas de conversation son para manipular los conversation objects que al final es todo lo que todos los agents ven - las herramientas de whatsapp son para manipular las acciones que nucleo toma en su propiia cuenta de whatsapp, por ejemplo enviar mensajes, crear grupos, etc. -`; + - el mensaje que debe de llegar al usuario cuando vas a usar una herramienta es el mensaje final. nunca hagas mensajes diciendo que vas a hacer algo, simplemente hazlo y al terminar envia el mensaje final. + +### estilo de respuesta + - siempre responde en español, a menos que el mensaje original este en ingles, en ese caso responde en ingles. + - siempre responde de manera clara y concisa, no te extiendas demasiado. + - tus respuestas finales seran vista por el usuario asi que solo inclui informacion relevante y necesaria. + + `; const app = express(); app.use(express.json()); @@ -110,11 +118,13 @@ app.post('/', async (req, res) => { if (!conversation) return res.status(400).json({ error: 'Missing conversation' }); if (!genAI) { - return res.json({ reply: systemPromt }); + return res.json({ reply: 'no funciona crack' }); } - + const planExecutionPrompt = ` + si necesitas ejecutar mas de una herremienta despues de otra para obtener la respuesta hacelo + `; try { - const contents = `systemPrompt: ${systemPromt}\nConversation:\n${JSON.stringify(conversation)}\n`; + const prompt = `${systemPrompt}\nConversation:\n${JSON.stringify(conversation)}\n\nCognition:\n${planExecutionPrompt}`; // console.log(' contents', contents); const config: any = {}; @@ -126,7 +136,7 @@ app.post('/', async (req, res) => { } const result = await genAI.models.generateContent({ model: 'gemini-2.0-flash', - contents, + contents: prompt, config, }); const reply = (result.text || '').trim(); diff --git a/mcp/modules/whatsappIntegration.js b/mcp/modules/whatsappIntegration.js index 7c42dc1..801bab5 100644 --- a/mcp/modules/whatsappIntegration.js +++ b/mcp/modules/whatsappIntegration.js @@ -1,209 +1,200 @@ -// mcp/modules/whatsappIntegration.js import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import { fetchJSON } from "../lib/api.js"; -const log = (...args) => console.log("[MCP WhatsAppIntegration]", ...args); // Changed log prefix +const log = (...args) => console.log("[MCP WhatsAppIntegration]", ...args); export default function registerWhatsappIntegration(server) { - // --- WhatsApp Actions --- - - // Tool: whatsapp.send-text server.tool( "whatsapp.send-text", - "Sends a text message via WhatsApp.", + "Envía un mensaje de texto.", { - to: z.string().describe("Recipient ID (e.g., 1234567890@c.us)"), - content: z.string().describe("Text message content"), + to: z.string(), + content: z.string(), }, async (params) => { log("Tool invoked", "whatsapp.send-text", params); - const result = await fetchJSON("/send-text", { + const result = await fetchJSON("/whatsapp/sendText", { method: "POST", - body: JSON.stringify(params), + body: JSON.stringify({ args: params }), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); - // Tool: whatsapp.send-image server.tool( "whatsapp.send-image", - "Sends an image message via WhatsApp.", + "Envía una imagen.", { - to: z.string().describe("Recipient ID"), - path: z.string().describe("Path or URL to the image"), - caption: z.string().optional().describe("Image caption"), + to: z.string(), + file: z.string(), + filename: z.string().optional(), + caption: z.string().optional(), + quotedMsgId: z.string().optional(), + waitForId: z.boolean().optional(), + hideTags: z.boolean().optional(), }, async (params) => { log("Tool invoked", "whatsapp.send-image", params); - const result = await fetchJSON("/send-image", { + const result = await fetchJSON("/whatsapp/sendImage", { method: "POST", - body: JSON.stringify(params), + body: JSON.stringify({ args: params }), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); - // Tool: whatsapp.send-file server.tool( "whatsapp.send-file", - "Sends a file message via WhatsApp.", + "Envía un archivo.", { - to: z.string().describe("Recipient ID"), - path: z.string().describe("Path or URL to the file"), - filename: z.string().optional().describe("Name of the file"), - caption: z.string().optional().describe("File caption"), + to: z.string(), + file: z.string(), + filename: z.string().optional(), + caption: z.string().optional(), + ptt: z.boolean().optional(), + withoutPreview: z.boolean().optional(), + viewOnce: z.boolean().optional(), + hideTags: z.boolean().optional(), }, async (params) => { log("Tool invoked", "whatsapp.send-file", params); - const result = await fetchJSON("/send-file", { + const result = await fetchJSON("/whatsapp/sendFile", { method: "POST", - body: JSON.stringify(params), + body: JSON.stringify({ args: params }), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); - // Tool: whatsapp.list-chats - server.tool( - "whatsapp.list-chats", - "Retrieves a list of all chats.", - {}, // No input parameters - async () => { - log("Tool invoked", "whatsapp.list-chats"); - const result = await fetchJSON("/chats"); - return { content: [{ type: "text", text: JSON.stringify(result) }] }; - } - ); - - // Tool: whatsapp.get-chat-details - server.tool( - "whatsapp.get-chat-details", - "Retrieves details for a specific chat by its ID.", - { - chatId: z.string().describe("ID of the chat (e.g., 1234567890@c.us)"), - }, - async (params) => { - log("Tool invoked", "whatsapp.get-chat-details", params); - const result = await fetchJSON(`/chats/${params.chatId}`); - return { content: [{ type: "text", text: JSON.stringify(result) }] }; - } - ); - - // Tool: whatsapp.get-chat-messages - server.tool( - "whatsapp.get-chat-messages", - "Retrieves messages for a specific chat.", - { - chatId: z.string().describe("ID of the chat"), - limit: z.number().optional().describe("Number of messages to retrieve"), - includeMe: z.boolean().optional().describe("Include messages sent by me"), - includeNotifications: z.boolean().optional().describe("Include notification messages"), - }, - async ({ chatId, ...queryParams}) => { - log("Tool invoked", "whatsapp.get-chat-messages", { chatId, queryParams }); - const qs = new URLSearchParams( - Object.entries(queryParams) - .filter(([, v]) => v !== undefined) - .map(([k, v]) => [k, String(v)]) - ); - const result = await fetchJSON(`/chats/${chatId}/messages?${qs.toString()}`); - return { content: [{ type: "text", text: JSON.stringify(result) }] }; - } - ); - server.tool( "whatsapp.delete-chat", - "Deletes a chat by its ID. (Note: The underlying OpenWA endpoint for this is assumed and might need verification)", + "Elimina un chat.", { - chatId: z.string().describe("ID of the chat to delete (e.g., 1234567890@c.us)"), + chatId: z.string(), }, async (params) => { log("Tool invoked", "whatsapp.delete-chat", params); - const result = await fetchJSON(`/chats/${params.chatId}`, { - method: "DELETE", - }); - // Consider what a successful deletion should return. - // OpenWA might return a success message or just a 200/204. - // For now, we'll return the full result. - return { content: [{ type: "text", text: JSON.stringify(result) }] }; - } - ); - - // Tool: whatsapp.create-group - server.tool( - "whatsapp.create-group", - "Creates a new WhatsApp group.", - { - groupName: z.string().describe("Name of the group"), - contactIds: z.array(z.string()).describe("Array of contact IDs to add to the group"), - }, - async (params) => { - log("Tool invoked", "whatsapp.create-group", params); - const result = await fetchJSON("/groups", { + const result = await fetchJSON("/whatsapp/deleteChat", { method: "POST", - body: JSON.stringify(params), + body: JSON.stringify({ args: params }), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); - // Tool: whatsapp.get-contact-details server.tool( - "whatsapp.get-contact-details", - "Retrieves details for a specific contact by ID.", + "whatsapp.delete-message", + "Elimina un mensaje.", { - contactId: z.string().describe("ID of the contact (e.g., 1234567890@c.us)"), + chatId: z.string(), + messageId: z.string(), + onlyLocal: z.boolean().optional(), }, async (params) => { - log("Tool invoked", "whatsapp.get-contact-details", params); - const result = await fetchJSON(`/contacts/${params.contactId}`); + log("Tool invoked", "whatsapp.delete-message", params); + const result = await fetchJSON("/whatsapp/deleteMessage", { + method: "POST", + body: JSON.stringify({ args: params }), + }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); - // Tool: whatsapp.get-blocklist server.tool( - "whatsapp.get-blocklist", - "Retrieves the blocklist.", - {}, // No input parameters + "whatsapp.edit-message", + "Edita un mensaje.", + { + messageId: z.string(), + text: z.string(), + }, + async (params) => { + log("Tool invoked", "whatsapp.edit-message", params); + const result = await fetchJSON("/whatsapp/editMessage", { + method: "POST", + body: JSON.stringify({ args: params }), + }); + return { content: [{ type: "text", text: JSON.stringify(result) }] }; + } + ); + + server.tool( + "whatsapp.forward-messages", + "Reenvía mensajes.", + { + to: z.string(), + messages: z.array(z.string()), + skipMyMessages: z.boolean().optional(), + }, + async (params) => { + log("Tool invoked", "whatsapp.forward-messages", params); + const result = await fetchJSON("/whatsapp/forwardMessages", { + method: "POST", + body: JSON.stringify({ args: params }), + }); + return { content: [{ type: "text", text: JSON.stringify(result) }] }; + } + ); + + server.tool( + "whatsapp.get-chat", + "Obtiene info de un chat", + { + contactId: z.string(), + }, + async (params) => { + log("Tool invoked", "whatsapp.get-chat", params); + const result = await fetchJSON("/whatsapp/getChat", { + method: "POST", + body: JSON.stringify({ args: params }), + }); + return { content: [{ type: "text", text: JSON.stringify(result) }] }; + } + ); + + server.tool( + "whatsapp.get-all-chats", + "Obtiene todos los chats.", + { + withNewMessageOnly: z.boolean().optional(), + }, + async (params) => { + log("Tool invoked", "whatsapp.get-all-chats", params); + const result = await fetchJSON("/whatsapp/getAllChats", { + method: "POST", + body: JSON.stringify({ args: params }), + }); + return { content: [{ type: "text", text: JSON.stringify(result) }] }; + } + ); + + server.tool( + "whatsapp.get-all-chat-ids", + "Obtiene todos los chat IDs.", + {}, async () => { - log("Tool invoked", "whatsapp.get-blocklist"); - const result = await fetchJSON("/blocklist"); - return { content: [{ type: "text", text: JSON.stringify(result) }] }; - } - ); - - // Tool: whatsapp.block-contact - server.tool( - "whatsapp.block-contact", - "Blocks a contact on WhatsApp.", - { - contactId: z.string().describe("ID of the contact to block"), - }, - async (params) => { - log("Tool invoked", "whatsapp.block-contact", params); - const result = await fetchJSON("/blocklist/block", { + log("Tool invoked", "whatsapp.get-all-chat-ids"); + const result = await fetchJSON("/whatsapp/getAllChatIds", { method: "POST", - body: JSON.stringify(params), + body: JSON.stringify({ args: {} }), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } ); - // Tool: whatsapp.unblock-contact server.tool( - "whatsapp.unblock-contact", - "Unblocks a contact on WhatsApp.", + "whatsapp.get-all-messages", + "Obtiene mensajes de un chat.", { - contactId: z.string().describe("ID of the contact to unblock"), + chatId: z.string(), + includeMe: z.boolean().optional(), + includeNotifications: z.boolean().optional(), }, async (params) => { - log("Tool invoked", "whatsapp.unblock-contact", params); - const result = await fetchJSON("/blocklist/unblock", { + log("Tool invoked", "whatsapp.get-all-messages", params); + const result = await fetchJSON("/whatsapp/getAllMessagesInChat", { method: "POST", - body: JSON.stringify(params), + body: JSON.stringify({ args: params }), }); return { content: [{ type: "text", text: JSON.stringify(result) }] }; } diff --git a/whatsapp-router/src/index.ts b/whatsapp-router/src/index.ts index 28e6e47..7301bac 100644 --- a/whatsapp-router/src/index.ts +++ b/whatsapp-router/src/index.ts @@ -1,6 +1,7 @@ import express from 'express'; import dotenv from 'dotenv'; import { registerConversationRoutes } from './routes/conversationActions'; +import whatsappActionsRouter from './routes/whatsappActions'; // New import import { registerWebhookRoutes, clearWebhooks, @@ -8,7 +9,6 @@ import { waitForGateway, WebhookConfig, } from './webhook'; -import whatsappActionsRouter from './routes/whatsappActions'; // New import dotenv.config(); @@ -51,9 +51,9 @@ const config: WebhookConfig = { registerConversationRoutes(app, openWaUrl); registerWebhookRoutes(app, config, openWaUrl, agentUrl); +app.use('/whatsapp', whatsappActionsRouter); // New line // Register new whatsappActions routes -app.use('/whatsapp', whatsappActionsRouter); // New line app.listen(port, async () => { console.log(`WhatsApp router listening on ${port}`); diff --git a/whatsapp-router/src/routes/conversationActions.ts b/whatsapp-router/src/routes/conversationActions.ts index 4c350a4..fa2ad80 100644 --- a/whatsapp-router/src/routes/conversationActions.ts +++ b/whatsapp-router/src/routes/conversationActions.ts @@ -6,6 +6,7 @@ import { buildConversation, } from '../store/conversation'; + export function registerConversationRoutes(app: Application, openWaUrl: string | undefined) { app.get('/conversations', (req, res) => { console.log('[routes] GET /conversations'); @@ -39,6 +40,7 @@ export function registerConversationRoutes(app: Application, openWaUrl: string | app.delete('/conversations/:id', (req, res) => { console.log(`[routes] DELETE /conversations/${req.params.id}`); const deleted = deleteConversation(req.params.id); + console.log(`Conversation ${req.params.id} deleted: ${deleted}`); res.json({ success: deleted }); }); } \ No newline at end of file diff --git a/whatsapp-router/src/routes/whatsappActions.ts b/whatsapp-router/src/routes/whatsappActions.ts index 1d6981f..e83910c 100644 --- a/whatsapp-router/src/routes/whatsappActions.ts +++ b/whatsapp-router/src/routes/whatsappActions.ts @@ -1,33 +1,21 @@ import express, { Router, Request, Response, NextFunction } from 'express'; import * as whatsappClient from '../whatsappClient'; -// Assuming OPEN_WA_URL is set in the environment. -// For local development, dotenv would typically be used in the main app entry point (e.g., index.ts) -// require('dotenv').config(); // Potentially, but better if handled by the main application loader +import dotenv from 'dotenv'; +dotenv.config(); const router = Router(); - -// Retrieve OpenWA URL from environment variables -// This is done once when the module is loaded. const openWaUrl = process.env.OPEN_WA_URL; -// Middleware to check if openWaUrl is configured -// This runs for every request to this router router.use((req: Request, res: Response, next: NextFunction) => { if (!openWaUrl) { console.error('[routes/whatsappActions] Service OPEN_WA_URL not configured'); return res.status(500).json({ error: 'Service OPEN_WA_URL not configured. Please set the environment variable.' }); } - // Pass openWaUrl to subsequent handlers via res.locals if preferred, - // or they can access the `openWaUrl` constant from the module scope. - // For simplicity, handlers will use the module-scoped `openWaUrl`. next(); }); -// Route implementations - -// POST /send-text -// POST /sendText router.post('/sendText', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /sendText called'); try { const { args } = req.body; const { to, content } = args || {}; @@ -38,19 +26,17 @@ router.post('/sendText', async (req: Request, res: Response) => { res.json(result); } catch (error: any) { console.error('[routes/whatsappActions] Error in /sendText:', error.message); - // Check if the error message is already a JSON string from whatsappClient's error handling try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { - // If not, send the plain error message + } catch { res.status(500).json({ error: error.message || 'Failed to send text message' }); } } }); -// POST /deleteChat router.post('/deleteChat', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /deleteChat called'); try { const { args } = req.body; const { chatId } = args || {}; @@ -58,22 +44,22 @@ router.post('/deleteChat', async (req: Request, res: Response) => { return res.status(400).json({ error: 'Missing "chatId" in request body' }); } const result = await whatsappClient.deleteChat(openWaUrl!, chatId); + console.log('[routes/whatsappActions] Chat deleted successfully:', result); + res.json(result); } catch (error: any) { console.error('[routes/whatsappActions] Error in /deleteChat:', error.message); try { - // Attempt to parse error message if it's from whatsappClient's structured error const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { - // If not, send the plain error message + } catch { res.status(500).json({ error: error.message || 'Failed to delete chat' }); } } }); -// POST /deleteMessage router.post('/deleteMessage', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /deleteMessage called'); try { const { args } = req.body; const { chatId, messageId, onlyLocal } = args || {}; @@ -91,14 +77,14 @@ router.post('/deleteMessage', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to delete message' }); } } }); -// POST /editMessage router.post('/editMessage', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /editMessage called'); try { const { args } = req.body; const { messageId, text } = args || {}; @@ -112,14 +98,14 @@ router.post('/editMessage', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to edit message' }); } } }); -// POST /forwardMessages router.post('/forwardMessages', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /forwardMessages called'); try { const { args } = req.body; const { to, messages, skipMyMessages } = args || {}; @@ -137,14 +123,14 @@ router.post('/forwardMessages', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to forward messages' }); } } }); -// POST /sendImage router.post('/sendImage', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /sendImage called'); try { const { args } = req.body; const { to, file, filename, caption, quotedMsgId, waitForId, hideTags } = args || {}; @@ -166,14 +152,14 @@ router.post('/sendImage', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to send image message' }); } } }); -// POST /sendFile router.post('/sendFile', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /sendFile called'); try { const { args } = req.body; const { @@ -205,14 +191,14 @@ router.post('/sendFile', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to send file message' }); } } }); -// POST /getChat router.post('/getChat', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /getChat called'); try { const { args } = req.body; const { contactId } = args || {}; @@ -226,110 +212,14 @@ router.post('/getChat', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to retrieve chat' }); } } }); -// POST /groups -router.post('/groups', async (req: Request, res: Response) => { - try { - const { groupName, contactIds } = req.body; - if (!groupName || !contactIds || !Array.isArray(contactIds) || contactIds.length === 0) { - return res.status(400).json({ error: 'Missing "groupName" or "contactIds" (must be a non-empty array) in request body' }); - } - const result = await whatsappClient.createGroup(openWaUrl!, groupName, contactIds); - res.json(result); - } catch (error: any) { - console.error('[routes/whatsappActions] Error in /groups:', error.message); - try { - const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); - return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { - res.status(500).json({ error: error.message || 'Failed to create group' }); - } - } -}); - -// GET /contacts/:contactId -router.get('/contacts/:contactId', async (req: Request, res: Response) => { - try { - const { contactId } = req.params; - if (!contactId) { - return res.status(400).json({ error: 'Missing "contactId" in request params' }); - } - const result = await whatsappClient.getContact(openWaUrl!, contactId); - res.json(result); - } catch (error: any) { - console.error(`[routes/whatsappActions] Error in /contacts/${req.params.contactId}:`, error.message); - try { - const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); - return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { - res.status(500).json({ error: error.message || 'Failed to retrieve contact' }); - } - } -}); - -// GET /blocklist -router.get('/blocklist', async (req: Request, res: Response) => { - try { - const result = await whatsappClient.getBlocklist(openWaUrl!); - res.json(result); - } catch (error: any) { - console.error('[routes/whatsappActions] Error in /blocklist:', error.message); - try { - const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); - return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { - res.status(500).json({ error: error.message || 'Failed to retrieve blocklist' }); - } - } -}); - -// POST /blocklist/block -router.post('/blocklist/block', async (req: Request, res: Response) => { - try { - const { contactId } = req.body; - if (!contactId) { - return res.status(400).json({ error: 'Missing "contactId" in request body' }); - } - const result = await whatsappClient.blockContact(openWaUrl!, contactId); - res.json(result); - } catch (error: any) { - console.error('[routes/whatsappActions] Error in /blocklist/block:', error.message); - try { - const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); - return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { - res.status(500).json({ error: error.message || 'Failed to block contact' }); - } - } -}); - -// POST /blocklist/unblock -router.post('/blocklist/unblock', async (req: Request, res: Response) => { - try { - const { contactId } = req.body; - if (!contactId) { - return res.status(400).json({ error: 'Missing "contactId" in request body' }); - } - const result = await whatsappClient.unblockContact(openWaUrl!, contactId); - res.json(result); - } catch (error: any) { - console.error('[routes/whatsappActions] Error in /blocklist/unblock:', error.message); - try { - const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); - return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { - res.status(500).json({ error: error.message || 'Failed to unblock contact' }); - } - } -}); - -// POST /getAllChats router.post('/getAllChats', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /getAllChats called'); try { const { args } = req.body; const { withNewMessageOnly } = args || {}; @@ -340,14 +230,14 @@ router.post('/getAllChats', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to retrieve all chats' }); } } }); -// POST /getAllChatIds router.post('/getAllChatIds', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /getAllChatIds called'); try { const result = await whatsappClient.getAllChatIds(openWaUrl!); res.json(result); @@ -356,14 +246,14 @@ router.post('/getAllChatIds', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to retrieve chat IDs' }); } } }); -// POST /getAllMessagesInChat router.post('/getAllMessagesInChat', async (req: Request, res: Response) => { + console.log('[routes/whatsappActions] POST /getAllMessagesInChat called'); try { const { args } = req.body; const { chatId, includeMe, includeNotifications } = args || {}; @@ -382,7 +272,7 @@ router.post('/getAllMessagesInChat', async (req: Request, res: Response) => { try { const parsedError = JSON.parse(error.message.substring(error.message.indexOf('{'))); return res.status(parsedError.status || 500).json({ error: parsedError }); - } catch (e) { + } catch { res.status(500).json({ error: error.message || 'Failed to retrieve chat messages' }); } } diff --git a/whatsapp-router/src/webhook.ts b/whatsapp-router/src/webhook.ts index 4449a78..dfb5f16 100644 --- a/whatsapp-router/src/webhook.ts +++ b/whatsapp-router/src/webhook.ts @@ -62,7 +62,7 @@ export function registerWebhookRoutes( if (chatId) { try { conv = await addMessageToConversation(chatId, message, openWaUrl); - console.log(`🔄 Updated conversation for ${chatId}`, conv); + console.log(`🔄 Updated conversation for ${chatId}`); } catch (err: any) { console.warn('Failed updating conversation:', err.message);