UNPKG

@ai-growth/n8n-nodes-wordpress

Version:

n8n node for WordPress integration with AI GROWTH - SEO WP plugin

373 lines 21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WordPressNode = exports.WordPress = void 0; const n8n_workflow_1 = require("n8n-workflow"); const NodeFields_1 = require("./NodeFields"); const NodeService_1 = require("./NodeService"); const WordPressValidator_1 = require("./WordPressValidator"); class WordPress { constructor() { this.description = { displayName: 'WordPress', name: 'wordpress', icon: 'file:wordpress.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Create, read, update and delete WordPress content with AI GROWTH - SEO WP plugin support', defaults: { name: 'WordPress', color: '#21759b', }, inputs: ['main'], outputs: ['main'], credentials: [ { name: 'wordpressApi', required: true, testedBy: 'wordpressApiTest', }, ], properties: (0, NodeFields_1.getAllNodeFields)(), }; this.methods = { credentialTest: { wordpressApiTest: async function (credential) { var _a, _b, _c; const startTime = Date.now(); console.log('[WordPress Node] 🔍 Starting API credentials test...'); const credentials = credential.data; const { url, username, password } = credentials; console.log(`[WordPress Node] 📋 Test Configuration: - URL: ${url} - API Version: v2 - Username: ${username} - Password Length: ${password ? password.toString().length : 0} chars`); // Validação básica if (!url) { console.error('[WordPress Node] ❌ Error: Website URL is required'); return { status: 'Error', message: 'Website URL is required', }; } if (!username || !password) { console.error('[WordPress Node] ❌ Error: Username and password are required'); return { status: 'Error', message: 'Username and password are required', }; } const baseUrl = url.toString().replace(/\/$/, ''); console.log(`[WordPress Node] 🔧 Normalized URL: ${baseUrl}`); try { const testUrl = `${baseUrl}/wp-json/wp/v2`; console.log(`[WordPress Node] 🌐 Testing connection to: ${testUrl}`); // Primeiro, testar conectividade básica console.log('[WordPress Node] 🔍 Step 1: Testing basic connectivity...'); try { const basicOptions = { method: 'GET', url: baseUrl, timeout: 10000, headers: { 'User-Agent': 'n8n-wordpress-node/1.0', }, }; const basicResponse = await this.helpers.request(basicOptions); console.log(`[WordPress Node] ✅ Basic connectivity successful (${basicResponse ? 'response received' : 'no response'})`); } catch (basicError) { console.error(`[WordPress Node] ❌ Basic connectivity failed: ${basicError.message}`); if (basicError.code === 'ENOTFOUND') { return { status: 'Error', message: 'Domain not found. Please check the URL.', }; } else if (basicError.code === 'ECONNREFUSED') { return { status: 'Error', message: 'Connection refused. The server may be down.', }; } } // Testar se wp-json está disponível console.log('[WordPress Node] 🔍 Step 2: Testing wp-json availability...'); try { const wpJsonOptions = { method: 'GET', url: `${baseUrl}/wp-json`, timeout: 10000, headers: { 'User-Agent': 'n8n-wordpress-node/1.0', 'Accept': 'application/json', }, }; const wpJsonResponse = await this.helpers.request(wpJsonOptions); console.log(`[WordPress Node] ✅ wp-json endpoint available`); console.log(`[WordPress Node] 📊 wp-json response keys: ${Object.keys(wpJsonResponse || {}).join(', ')}`); } catch (wpJsonError) { console.warn(`[WordPress Node] ⚠️ wp-json test failed: ${wpJsonError.message}`); if (wpJsonError.statusCode === 404) { return { status: 'Error', message: 'WordPress REST API not found. Please ensure the REST API is enabled.', }; } } // Testar autenticação na API console.log('[WordPress Node] 🔍 Step 3: Testing API authentication...'); const options = { method: 'GET', url: testUrl, headers: { Authorization: `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`, 'User-Agent': 'n8n-wordpress-node/1.0', 'Accept': 'application/json', }, timeout: 15000, json: true, }; console.log(`[WordPress Node] 📤 Making authenticated request: - Method: ${options.method} - URL: ${options.url} - Headers: Authorization: Basic *****, User-Agent: ${options.headers['User-Agent']}`); try { const response = await this.helpers.request(options); const duration = Date.now() - startTime; console.log(`[WordPress Node] 📥 Response received in ${duration}ms`); console.log(`[WordPress Node] 📊 Response analysis: - Type: ${typeof response} - Is Object: ${typeof response === 'object'} - Keys: ${response && typeof response === 'object' ? Object.keys(response).join(', ') : 'N/A'}`); if (!response) { console.error('[WordPress Node] ❌ Error: Empty response from WordPress API'); return { status: 'Error', message: 'Invalid response from WordPress API - empty response', }; } // Análise detalhada da resposta if (typeof response === 'object') { console.log(`[WordPress Node] 🔍 Response details: - Name: ${response.name || 'Not provided'} - Description: ${response.description || 'Not provided'} - URL: ${response.url || 'Not provided'} - Home: ${response.home || 'Not provided'} - Routes: ${response.routes ? Object.keys(response.routes).length : 0} endpoints`); // Verificar se a resposta contém os campos esperados da API REST if (response.name && response.description) { console.log(`[WordPress Node] ✅ Successfully connected to "${response.name}"`); return { status: 'OK', message: `Successfully connected to ${response.name}`, }; } else if (response.routes) { console.log(`[WordPress Node] ✅ WordPress REST API detected (${Object.keys(response.routes).length} routes)`); return { status: 'OK', message: 'WordPress REST API connection successful', }; } } console.log(`[WordPress Node] ✅ Connection successful (unexpected format but valid response)`); return { status: 'OK', message: 'Connection successful!', }; } catch (requestError) { console.error(`[WordPress Node] ❌ Authenticated request failed: ${requestError.message || 'Unknown error'}`); if (requestError.response) { console.error(`[WordPress Node] 📊 Error response details: - Status: ${requestError.response.status} - Status Text: ${requestError.response.statusText} - Headers: ${JSON.stringify(requestError.response.headers, null, 2)} - Data: ${JSON.stringify(requestError.response.data, null, 2)}`); } else if (requestError.request) { console.error(`[WordPress Node] 📊 Request error details: - No response received - Request config: ${JSON.stringify({ method: (_a = requestError.config) === null || _a === void 0 ? void 0 : _a.method, url: (_b = requestError.config) === null || _b === void 0 ? void 0 : _b.url, timeout: (_c = requestError.config) === null || _c === void 0 ? void 0 : _c.timeout, }, null, 2)}`); } throw requestError; } } catch (error) { const duration = Date.now() - startTime; console.error(`[WordPress Node] ❌ Credentials test failed after ${duration}ms:`, error); let errorMessage = 'Could not connect to WordPress API'; let detailedMessage = ''; if (error.statusCode === 401) { console.error(`[WordPress Node] 🚫 Authentication failed (401 Unauthorized)`); errorMessage = 'Authentication failed. Please check your username and application password.'; detailedMessage = 'The server rejected the credentials. Make sure you are using an Application Password, not your regular WordPress password.'; } else if (error.statusCode === 403) { console.error(`[WordPress Node] 🚫 Access forbidden (403 Forbidden)`); errorMessage = 'Access forbidden. The user may not have sufficient permissions.'; detailedMessage = 'The credentials are valid but the user lacks permissions to access the REST API.'; } else if (error.statusCode === 404) { console.error(`[WordPress Node] 🚫 API not found (404 Not Found)`); errorMessage = 'WordPress REST API not found.'; detailedMessage = 'The REST API endpoint was not found. Please ensure the REST API is enabled and the URL is correct.'; } else if (error.code === 'ENOTFOUND') { console.error(`[WordPress Node] 🌐 Domain not found`); errorMessage = 'Domain not found. Please check the URL.'; detailedMessage = 'The domain could not be resolved. Check if the URL is correct and the site is online.'; } else if (error.code === 'ECONNREFUSED') { console.error(`[WordPress Node] 🌐 Connection refused`); errorMessage = 'Connection refused. The server may be down.'; detailedMessage = 'The server actively refused the connection. The site may be down or blocking requests.'; } else if (error.code === 'ECONNABORTED') { console.error(`[WordPress Node] ⏱️ Connection timeout`); errorMessage = 'Connection timeout. The server is taking too long to respond.'; detailedMessage = 'The request timed out. The server may be slow or overloaded.'; } else if (error.message) { console.error(`[WordPress Node] ❌ Connection error: ${error.message}`); errorMessage = `Connection error: ${error.message}`; detailedMessage = error.message; } const errorDetails = { statusCode: error.statusCode, code: error.code, message: error.message, response: error.response ? { status: error.response.status, statusText: error.response.statusText, data: error.response.data, } : null, duration: `${duration}ms`, }; console.error(`[WordPress Node] 📊 Complete error details: ${JSON.stringify(errorDetails, null, 2)}`); return { status: 'Error', message: detailedMessage ? `${errorMessage}\n\nDetails: ${detailedMessage}` : errorMessage, }; } }, }, }; } async execute() { const items = this.getInputData(); const returnData = []; try { const credentials = await this.getCredentials('wordpressApi'); const nodeService = new NodeService_1.NodeService(this, credentials); // Detectar versão da API na primeira execução try { const client = nodeService.getClient(); const apiDetection = await client.detectApiVersion(); if (!apiDetection.isSupported && apiDetection.recommendedVersion) { console.warn(`[WordPress Node] ⚠️ Current API version (${apiDetection.detectedVersion}) may not be fully supported. Consider using version ${apiDetection.recommendedVersion}`); } // Descobrir rotas disponíveis para melhor tratamento de erros const routeDiscovery = await client.discoverRoutes(); if (routeDiscovery.success) { console.log(`[WordPress Node] ✅ Route discovery completed: ${routeDiscovery.routes.length} routes found`); } else { console.warn(`[WordPress Node] ⚠️ Route discovery failed: ${routeDiscovery.error}`); } } catch (initError) { // Não falhar a execução se a inicialização falhar, apenas logar console.warn(`[WordPress Node] ⚠️ API initialization warning: ${initError.message}`); } const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); for (let i = 0; i < items.length; i++) { try { const params = WordPressValidator_1.WordPressValidator.getParams(this, i, resource, operation); const result = await nodeService.executeOperation(params, resource, operation); // Formatar saída com base no tipo de operação if (operation === 'getAll') { const formattedResults = nodeService.formatMultipleOutput(result); returnData.push(...formattedResults); } else if (operation === 'delete') { const formattedResult = nodeService.formatBooleanOutput(result, typeof params === 'object' && 'id' in params ? params.id : undefined); returnData.push(...formattedResult); } else { const formattedResult = nodeService.formatSingleOutput(result); returnData.push(...formattedResult); } } catch (error) { // Capturar erros para item individual com informações detalhadas const errorMessage = error instanceof Error ? error.message : String(error); const errorDetails = { error: errorMessage, item: i, resource, operation, timestamp: new Date().toISOString(), }; // Adicionar informações específicas do erro se disponível if (error && typeof error === 'object') { if ('statusCode' in error) { errorDetails.statusCode = error.statusCode; } if ('type' in error) { errorDetails.errorType = error.type; } } // Obter parâmetros para log (se disponível) let logParams = 'N/A'; try { const currentParams = WordPressValidator_1.WordPressValidator.getParams(this, i, resource, operation); if (typeof currentParams === 'object' && currentParams && 'id' in currentParams) { logParams = { id: currentParams.id }; } } catch { // Ignorar erro ao obter parâmetros para log } // Log detalhado do erro para diagnóstico console.error(`[WordPress Node] ❌ Error in item ${i}:`, { resource, operation, params: logParams, error: errorMessage, errorDetails: error, }); if (this.continueOnFail()) { // Adicionar erro detalhado à saída returnData.push({ json: errorDetails, }); continue; } throw error; } } return [returnData]; } catch (error) { // Erro geral ao executar o nó if (this.continueOnFail()) { return [items]; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), error instanceof Error ? error : new Error(String(error))); } } } exports.WordPress = WordPress; exports.WordPressNode = WordPress; // Export default como classe construtora exports.default = WordPress; //# sourceMappingURL=WordPress.js.map