Refactor MCP resources to tools, add chat deletion
This commit implements two main changes based on your feedback:
1. Refactors all Model Context Protocol (MCP) resources into tools:
- In `whatsappIntegration.js`:
- `whatsapp.chat` (resource) -> `whatsapp.list-chats` (tool) & `whatsapp.get-chat-details` (tool)
- `whatsapp.contact` (resource) -> `whatsapp.get-contact-details` (tool)
- `whatsapp.blocklist` (resource) -> `whatsapp.get-blocklist` (tool)
- In `conversationIntegration.js`:
- `conversation` (resource) -> `conversation.list-conversations` (tool) & `conversation.get-conversation-details` (tool)
This change aligns with current Gemini SDK capabilities for MCP.
2. Implements chat deletion functionality:
- In `whatsapp-router`:
- Added `deleteChat` function to `whatsappClient.ts`. This function calls an assumed OpenWA endpoint (`POST /deleteChat`) and will require verification against the actual OpenWA API.
- Added a `DELETE /chats/:chatId` route to `whatsappActions.ts` that utilizes the new `deleteChat` client function.
- In `conversation-layer-mcp`:
- Added a new `whatsapp.delete-chat` tool to `whatsappIntegration.js`. This tool calls the new `DELETE /chats/:chatId` endpoint in `whatsapp-router`.
Additionally, the existing `conversation.delete` MCP tool was verified to be correctly implemented.
This commit is contained in:
@@ -45,12 +45,24 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- PORT=8001
|
- PORT=8001
|
||||||
- GEMINI_API_KEY= AIzaSyA9fI1mron-NVgghygu7B4sco7t6raXB8M
|
- GEMINI_API_KEY= AIzaSyA9fI1mron-NVgghygu7B4sco7t6raXB8M
|
||||||
- MCP_URL= http:planilla-mcp:5000/mcp
|
- MCP_URL=http://conversation-layer-mcp:5000/mcp
|
||||||
ports:
|
ports:
|
||||||
- "8001:8001"
|
- "8001:8001"
|
||||||
networks:
|
networks:
|
||||||
- principal
|
- principal
|
||||||
|
|
||||||
|
conversation-layer-mcp:
|
||||||
|
build: ./mcp
|
||||||
|
image: gitea.interno.com/nucleo000/conversation-layer-mcp:latest
|
||||||
|
container_name: conversation-layer-mcp
|
||||||
|
environment:
|
||||||
|
- PORT=5000
|
||||||
|
- WHATSAPP_ROUTER_URL=http://whatsapp-router:3001
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
networks:
|
||||||
|
- principal
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
nucleo_whatsapp_sessions:
|
nucleo_whatsapp_sessions:
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||||
|
import registerWhatsappIntegration from "./modules/whatsappIntegration.js";
|
||||||
import registerTareas from "./modules/tareas.js";
|
import registerConversationIntegration from "./modules/conversationIntegration.js";
|
||||||
|
|
||||||
export function createServer() {
|
export function createServer() {
|
||||||
const server = new McpServer({ name: "planilla-mcp", version: "0.1.0" });
|
const server = new McpServer({ name: "conversation-layer-mcp", version: "0.1.0" });
|
||||||
|
|
||||||
registerTareas(server);
|
registerWhatsappIntegration(server);
|
||||||
|
registerConversationIntegration(server);
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
export const API_BASE_URL = process.env.PLANILLA_API_URL || "http://localhost:4000";
|
export const API_BASE_URL = process.env.WHATSAPP_ROUTER_URL;
|
||||||
|
|
||||||
|
if (!API_BASE_URL) {
|
||||||
|
console.error("FATAL: WHATSAPP_ROUTER_URL environment variable is not set.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
export async function fetchJSON(path, options = {}) {
|
export async function fetchJSON(path, options = {}) {
|
||||||
const method = options.method || "GET";
|
const method = options.method || "GET";
|
||||||
|
|||||||
69
mcp/modules/conversationIntegration.js
Normal file
69
mcp/modules/conversationIntegration.js
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// mcp/modules/conversationIntegration.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 ConversationIntegration]", ...args); // Changed log prefix
|
||||||
|
|
||||||
|
export default function registerConversationIntegration(server) {
|
||||||
|
// --- Conversation Actions ---
|
||||||
|
|
||||||
|
// Tool: conversation.list-conversations
|
||||||
|
server.tool(
|
||||||
|
"conversation.list-conversations",
|
||||||
|
"Retrieves a list of all conversations.",
|
||||||
|
{}, // No input parameters
|
||||||
|
async () => {
|
||||||
|
log("Tool invoked", "conversation.list-conversations");
|
||||||
|
const result = await fetchJSON("/conversations");
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tool: conversation.get-conversation-details
|
||||||
|
server.tool(
|
||||||
|
"conversation.get-conversation-details",
|
||||||
|
"Retrieves details for a specific conversation by its ID.",
|
||||||
|
{
|
||||||
|
id: z.string().describe("ID of the conversation"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "conversation.get-conversation-details", params);
|
||||||
|
const result = await fetchJSON(`/conversations/${params.id}`);
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tool: conversation.update
|
||||||
|
server.tool(
|
||||||
|
"conversation.update",
|
||||||
|
"Updates/rebuilds a conversation by its ID.",
|
||||||
|
{
|
||||||
|
id: z.string().describe("ID of the conversation to update"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "conversation.update", params);
|
||||||
|
const result = await fetchJSON(`/conversations/${params.id}/update`, {
|
||||||
|
method: "POST",
|
||||||
|
// No body needed for this specific route as per analysis
|
||||||
|
});
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tool: conversation.delete
|
||||||
|
server.tool(
|
||||||
|
"conversation.delete",
|
||||||
|
"Deletes a conversation by its ID.",
|
||||||
|
{
|
||||||
|
id: z.string().describe("ID of the conversation to delete"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "conversation.delete", params);
|
||||||
|
const result = await fetchJSON(`/conversations/${params.id}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
});
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
||||||
import { z } from "zod";
|
|
||||||
import { fetchJSON } from "../lib/api.js";
|
|
||||||
|
|
||||||
const log = (...args) => console.log("[MCP]", ...args);
|
|
||||||
|
|
||||||
export default function registerTareas(server) {
|
|
||||||
server.resource("tarea-list", "tarea://list", async (uri) => {
|
|
||||||
log("Recurso solicitado", "tarea-list");
|
|
||||||
const tareas = await fetchJSON("/api/tareas");
|
|
||||||
return { contents: [{ uri: uri.href, text: JSON.stringify(tareas) }] };
|
|
||||||
});
|
|
||||||
|
|
||||||
server.resource(
|
|
||||||
"tarea",
|
|
||||||
new ResourceTemplate("tarea://{id}", { list: undefined }),
|
|
||||||
async (uri, { id }) => {
|
|
||||||
log("Recurso solicitado", `tarea ${id}`);
|
|
||||||
const tarea = await fetchJSON(`/api/tareas/${id}`);
|
|
||||||
return { contents: [{ uri: uri.href, text: JSON.stringify(tarea) }] };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
server.tool(
|
|
||||||
"create-tarea",
|
|
||||||
"Crea una tarea",
|
|
||||||
{
|
|
||||||
empleado_id: z.number(),
|
|
||||||
planilla_id: z.number().optional(),
|
|
||||||
titulo: z.string(),
|
|
||||||
precio: z.number().optional(),
|
|
||||||
estado: z.string().optional(),
|
|
||||||
observacion: z.string().optional(),
|
|
||||||
fecha: z.string(),
|
|
||||||
tipo: z.string().optional(),
|
|
||||||
fecha_anulado: z.string().optional(),
|
|
||||||
creador_id: z.number().optional(),
|
|
||||||
anulador_id: z.number().optional(),
|
|
||||||
},
|
|
||||||
async (params) => {
|
|
||||||
log("Tool invocada", "create-tarea", params);
|
|
||||||
const tarea = await fetchJSON("/api/tareas", {
|
|
||||||
method: "POST",
|
|
||||||
body: JSON.stringify(params),
|
|
||||||
});
|
|
||||||
return { content: [{ type: "text", text: JSON.stringify(tarea) }] };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
server.tool(
|
|
||||||
"update-tarea",
|
|
||||||
"Actualiza una tarea",
|
|
||||||
{
|
|
||||||
id: z.number(),
|
|
||||||
empleado_id: z.number().optional(),
|
|
||||||
planilla_id: z.number().optional(),
|
|
||||||
titulo: z.string().optional(),
|
|
||||||
precio: z.number().optional(),
|
|
||||||
estado: z.string().optional(),
|
|
||||||
observacion: z.string().optional(),
|
|
||||||
fecha: z.string().optional(),
|
|
||||||
tipo: z.string().optional(),
|
|
||||||
fecha_anulado: z.string().optional(),
|
|
||||||
anulador_id: z.number().optional(),
|
|
||||||
},
|
|
||||||
async ({ id, ...updates }) => {
|
|
||||||
log("Tool invocada", "update-tarea", { id, ...updates });
|
|
||||||
const tarea = await fetchJSON(`/api/tareas/${id}`, {
|
|
||||||
method: "PUT",
|
|
||||||
body: JSON.stringify(updates),
|
|
||||||
});
|
|
||||||
return { content: [{ type: "text", text: JSON.stringify(tarea) }] };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
server.tool(
|
|
||||||
"delete-tarea",
|
|
||||||
"Elimina una tarea",
|
|
||||||
{ id: z.number() },
|
|
||||||
async ({ id }) => {
|
|
||||||
log("Tool invocada", "delete-tarea", { id });
|
|
||||||
await fetchJSON(`/api/tareas/${id}`, { method: "DELETE" });
|
|
||||||
return { content: [{ type: "text", text: `Tarea ${id} eliminada` }] };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
server.tool(
|
|
||||||
"search-tareas",
|
|
||||||
"Busca tareas. `q` matchea id, empleado_id, planilla_id o título. Si no mandas filtros devuelve los primeros 100 registros.",
|
|
||||||
{
|
|
||||||
q: z.string().optional(),
|
|
||||||
empleado_id: z.number().optional(),
|
|
||||||
planilla_id: z.number().optional(),
|
|
||||||
estado: z.string().optional(),
|
|
||||||
titulo: z.string().optional(),
|
|
||||||
fecha_desde: z.string().optional(),
|
|
||||||
fecha_hasta: z.string().optional(),
|
|
||||||
},
|
|
||||||
async (params) => {
|
|
||||||
log("Tool invocada", "search-tareas", params);
|
|
||||||
const qs = new URLSearchParams(
|
|
||||||
Object.entries(params)
|
|
||||||
.filter(([, v]) => v !== undefined)
|
|
||||||
.map(([k, v]) => [k, String(v)])
|
|
||||||
);
|
|
||||||
if (qs.toString() === "") qs.append("limit", "100");
|
|
||||||
const tareas = await fetchJSON(`/api/tareas/search?${qs.toString()}`);
|
|
||||||
return { content: [{ type: "text", text: JSON.stringify(tareas) }] };
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
211
mcp/modules/whatsappIntegration.js
Normal file
211
mcp/modules/whatsappIntegration.js
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
export default function registerWhatsappIntegration(server) {
|
||||||
|
// --- WhatsApp Actions ---
|
||||||
|
|
||||||
|
// Tool: whatsapp.send-text
|
||||||
|
server.tool(
|
||||||
|
"whatsapp.send-text",
|
||||||
|
"Sends a text message via WhatsApp.",
|
||||||
|
{
|
||||||
|
to: z.string().describe("Recipient ID (e.g., 1234567890@c.us)"),
|
||||||
|
content: z.string().describe("Text message content"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "whatsapp.send-text", params);
|
||||||
|
const result = await fetchJSON("/send-text", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tool: whatsapp.send-image
|
||||||
|
server.tool(
|
||||||
|
"whatsapp.send-image",
|
||||||
|
"Sends an image message via WhatsApp.",
|
||||||
|
{
|
||||||
|
to: z.string().describe("Recipient ID"),
|
||||||
|
path: z.string().describe("Path or URL to the image"),
|
||||||
|
caption: z.string().optional().describe("Image caption"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "whatsapp.send-image", params);
|
||||||
|
const result = await fetchJSON("/send-image", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tool: whatsapp.send-file
|
||||||
|
server.tool(
|
||||||
|
"whatsapp.send-file",
|
||||||
|
"Sends a file message via WhatsApp.",
|
||||||
|
{
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "whatsapp.send-file", params);
|
||||||
|
const result = await fetchJSON("/send-file", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(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)",
|
||||||
|
{
|
||||||
|
chatId: z.string().describe("ID of the chat to delete (e.g., 1234567890@c.us)"),
|
||||||
|
},
|
||||||
|
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", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(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.",
|
||||||
|
{
|
||||||
|
contactId: z.string().describe("ID of the contact (e.g., 1234567890@c.us)"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "whatsapp.get-contact-details", params);
|
||||||
|
const result = await fetchJSON(`/contacts/${params.contactId}`);
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tool: whatsapp.get-blocklist
|
||||||
|
server.tool(
|
||||||
|
"whatsapp.get-blocklist",
|
||||||
|
"Retrieves the blocklist.",
|
||||||
|
{}, // No input parameters
|
||||||
|
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", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Tool: whatsapp.unblock-contact
|
||||||
|
server.tool(
|
||||||
|
"whatsapp.unblock-contact",
|
||||||
|
"Unblocks a contact on WhatsApp.",
|
||||||
|
{
|
||||||
|
contactId: z.string().describe("ID of the contact to unblock"),
|
||||||
|
},
|
||||||
|
async (params) => {
|
||||||
|
log("Tool invoked", "whatsapp.unblock-contact", params);
|
||||||
|
const result = await fetchJSON("/blocklist/unblock", {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
});
|
||||||
|
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -48,6 +48,29 @@ router.post('/send-text', async (req: Request, res: Response) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// DELETE /chats/:chatId
|
||||||
|
router.delete('/chats/:chatId', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const { chatId } = req.params;
|
||||||
|
if (!chatId) {
|
||||||
|
return res.status(400).json({ error: 'Missing "chatId" in request params' });
|
||||||
|
}
|
||||||
|
// openWaUrl is checked by middleware and available in module scope
|
||||||
|
const result = await whatsappClient.deleteChat(openWaUrl!, chatId);
|
||||||
|
res.json(result);
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(`[routes/whatsappActions] Error in DELETE /chats/${req.params.chatId}:`, 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
|
||||||
|
res.status(500).json({ error: error.message || 'Failed to delete chat' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// POST /send-image
|
// POST /send-image
|
||||||
router.post('/send-image', async (req: Request, res: Response) => {
|
router.post('/send-image', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -42,6 +42,34 @@ export async function sendTextMessage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a chat by its ID via OpenWA.
|
||||||
|
* (Assumes OpenWA supports a /deleteChat endpoint or similar via POST)
|
||||||
|
* @param openWaUrl The base URL of the OpenWA instance.
|
||||||
|
* @param chatId The ID of the chat to delete.
|
||||||
|
* @returns A promise that resolves to the API response.
|
||||||
|
*/
|
||||||
|
export async function deleteChat(
|
||||||
|
openWaUrl: string,
|
||||||
|
chatId: string
|
||||||
|
): Promise<OpenWAResponse> { // Using OpenWAResponse<any> for now
|
||||||
|
try {
|
||||||
|
// Assuming OpenWA uses a POST request for actions like deleteChat
|
||||||
|
// The actual endpoint name ('/deleteChat') is a guess and might need adjustment.
|
||||||
|
const response = await axios.post(`${openWaUrl}/deleteChat`, {
|
||||||
|
args: { chatId },
|
||||||
|
});
|
||||||
|
return response.data?.response || response.data;
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error(`[whatsappClient] Error deleting chat ${chatId}:`, error.message);
|
||||||
|
if (axios.isAxiosError(error) && error.response) {
|
||||||
|
console.error('[whatsappClient] Axios error details:', error.response.data);
|
||||||
|
throw new Error(`whatsappClient API error (${openWaUrl}/deleteChat): ${error.response.status} - ${JSON.stringify(error.response.data)}`);
|
||||||
|
}
|
||||||
|
throw new Error(`whatsappClient error (${openWaUrl}/deleteChat): ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an image message via OpenWA.
|
* Sends an image message via OpenWA.
|
||||||
* @param openWaUrl The base URL of the OpenWA instance.
|
* @param openWaUrl The base URL of the OpenWA instance.
|
||||||
|
|||||||
Reference in New Issue
Block a user