@ai-growth/n8n-nodes-wordpress
Version:
n8n node for WordPress integration with AI GROWTH - SEO WP plugin
373 lines • 21 kB
JavaScript
;
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