import { env } from '@/lib/env'; export class N8nService { private webhookUrl: string; private rollbackWebhookUrl: string; private apiKey: string; constructor() { // Use consistent webhook URLs without -test suffix this.webhookUrl = process.env.N8N_WEBHOOK_URL || 'https://brain.slm-lab.net/webhook/mission-created'; this.rollbackWebhookUrl = process.env.N8N_ROLLBACK_WEBHOOK_URL || 'https://brain.slm-lab.net/webhook/mission-rollback'; this.apiKey = process.env.N8N_API_KEY || ''; if (!this.apiKey) { console.error('N8N_API_KEY is not set in environment variables'); } } async triggerMissionCreation(data: any): Promise { try { // Add API key and default values to the data const dataWithDefaults = { ...data, oddScope: data.oddScope || 'default', participation: data.participation || 'default', config: { ...data.config, N8N_API_KEY: this.apiKey } }; console.log('Triggering n8n workflow with data:', JSON.stringify(dataWithDefaults, null, 2)); console.log('Using webhook URL:', this.webhookUrl); console.log('API key present:', !!this.apiKey); // Log the full request details const requestDetails = { url: this.webhookUrl, method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey }, body: dataWithDefaults }; console.log('Full request details:', JSON.stringify(requestDetails, null, 2)); const response = await fetch(this.webhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey }, body: JSON.stringify(dataWithDefaults), }); console.log('Webhook response status:', response.status); console.log('Webhook response headers:', Object.fromEntries(response.headers.entries())); if (!response.ok) { const errorText = await response.text(); console.error('Webhook error response:', errorText); throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`); } const responseText = await response.text(); console.log('Raw response from n8n:', responseText); // Try to parse the response as JSON try { const result = JSON.parse(responseText); console.log('Parsed workflow result:', JSON.stringify(result, null, 2)); return { success: true, results: result }; } catch (parseError) { console.log('Response is not JSON, treating as workflow trigger confirmation'); return { success: true, results: { leantimeProjectId: null, outlineCollectionId: null, rocketChatChannelId: null, giteaRepositoryUrl: null } }; } } catch (error) { console.error('Error triggering n8n workflow:', error); return { success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } } async triggerMissionRollback(data: any): Promise { try { console.log('Triggering n8n rollback workflow with data:', JSON.stringify(data, null, 2)); console.log('Using rollback webhook URL:', this.rollbackWebhookUrl); console.log('API key present:', !!this.apiKey); const response = await fetch(this.rollbackWebhookUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': this.apiKey }, body: JSON.stringify(data), }); if (!response.ok) { const errorText = await response.text(); console.error('Rollback webhook error response:', errorText); throw new Error(`HTTP error! status: ${response.status}, body: ${errorText}`); } const result = await response.json(); console.log('Received response from n8n rollback:', JSON.stringify(result, null, 2)); return { success: true, results: result }; } catch (error) { console.error('Error triggering n8n rollback workflow:', error); return { success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } } }