import fetch from 'node-fetch';
import type {
SaveDataArgs,
WebhookPayload,
WebhookResponse
} from '../types/webhook.js';
// Configuración del webhook desde variables de entorno
const WEBHOOK_URL = process.env.N8N_WEBHOOK_URL || 'https://grec0-n8n.sytes.net/webhook-test';
const WEBHOOK_ID = process.env.N8N_WEBHOOK_ID || 'f9c6e821-b9d5-4f80-9d82-bdca6255e48d';
const API_KEY = process.env.N8N_API_KEY || 'lkmQ3Ppasi7oe7r8V66mks7K8uYL';
/**
* Genera un timestamp ISO 8601 actual
*/
function generateTimestamp(): string {
return new Date().toISOString();
}
/**
* Genera un ID único para el proyecto si no se proporciona
*/
function generateProjectId(projectName: string): string {
const timestamp = Date.now();
const sanitized = projectName.toLowerCase().replace(/[^a-z0-9]/g, '_');
return `proj_${sanitized}_${timestamp}`;
}
/**
* Construye el payload completo para el webhook
*/
function buildWebhookPayload(args: SaveDataArgs): WebhookPayload {
const timestamp = generateTimestamp();
return {
metadata: {
timestamp,
source: 'mcp_assistant',
version: '1.0'
},
project: {
id: generateProjectId(args.projectName),
name: args.projectName
},
content: {
title: args.title,
text: args.text
}
};
}
/**
* Envía datos al webhook de n8n
*/
export async function saveDataToWebhook(args: SaveDataArgs): Promise<WebhookResponse> {
try {
console.error(`📤 Enviando datos al webhook n8n...`);
console.error(`URL: ${WEBHOOK_URL}/${WEBHOOK_ID}`);
const payload = buildWebhookPayload(args);
console.error(`📋 Payload generado:`, JSON.stringify(payload, null, 2));
const response = await fetch(`${WEBHOOK_URL}/${WEBHOOK_ID}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization-n8n-api-key': API_KEY,
'User-Agent': 'MCP-N8N-Webhook/1.0'
},
body: JSON.stringify(payload)
});
console.error(`📡 Respuesta HTTP: ${response.status} ${response.statusText}`);
if (!response.ok) {
const errorText = await response.text();
console.error(`❌ Error en respuesta:`, errorText);
return {
success: false,
message: `Error HTTP ${response.status}: ${response.statusText}. ${errorText}`,
timestamp: generateTimestamp()
};
}
let responseData: any;
try {
responseData = await response.json();
} catch (parseError) {
// Si no es JSON válido, usar el texto de respuesta
const textResponse = await response.text();
responseData = { message: textResponse };
}
console.error(`✅ Datos enviados exitosamente:`, responseData);
return {
success: true,
message: 'Datos guardados exitosamente en n8n',
id: responseData.id || payload.project.id,
timestamp: generateTimestamp()
};
} catch (error) {
console.error(`❌ Error enviando datos al webhook:`, error);
return {
success: false,
message: `Error de conexión: ${(error as Error).message}`,
timestamp: generateTimestamp()
};
}
}
/**
* Verifica la conectividad con el webhook
*/
export async function healthCheckWebhook(): Promise<WebhookResponse> {
try {
console.error(`🔍 Verificando conectividad del webhook...`);
// Intento básico de conectividad (sin enviar datos reales)
const testPayload = {
metadata: {
timestamp: generateTimestamp(),
source: 'health_check',
version: '1.0'
},
project: {
id: 'health_check',
name: 'Health Check'
},
content: {
title: 'Verificación de conectividad',
text: 'Este es un mensaje de prueba para verificar la conectividad'
}
};
const response = await fetch(`${WEBHOOK_URL}/${WEBHOOK_ID}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization-n8n-api-key': API_KEY,
'User-Agent': 'MCP-N8N-Webhook/1.0'
},
body: JSON.stringify(testPayload)
});
if (!response.ok) {
return {
success: false,
message: `Webhook no disponible: HTTP ${response.status}`,
timestamp: generateTimestamp()
};
}
return {
success: true,
message: 'Webhook disponible y funcionando correctamente',
timestamp: generateTimestamp()
};
} catch (error) {
return {
success: false,
message: `Error de conectividad: ${(error as Error).message}`,
timestamp: generateTimestamp()
};
}
}