@ai-growth/wordpress
Version:
n8n node for WordPress integration with AI GROWTH - SEO WP plugin
521 lines (520 loc) • 24 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeService = void 0;
var WordPressClient_1 = require("../utils/WordPressClient");
var ContentService_1 = require("../services/ContentService");
var PostCreateService_1 = require("../services/PostCreateService");
var TaxonomyService_1 = require("../services/TaxonomyService");
var MediaUploadService_1 = require("../services/MediaUploadService");
var FeaturedImageService_1 = require("../services/FeaturedImageService");
/**
* Serviço para executar operações do nó WordPress
*/
var NodeService = /** @class */ (function () {
/**
* Construtor do serviço
* @param execFunctions Funções de execução do n8n
* @param credentials Credenciais do WordPress
*/
function NodeService(execFunctions, credentials) {
this.execFunctions = execFunctions;
// Obter credenciais
var domain = credentials.domain;
var username = credentials.username;
var password = credentials.password;
var apiVersion = credentials.apiVersion || 'v2';
// Criar cliente WordPress
this.client = new WordPressClient_1.WordPressClient({
url: domain,
username: username,
password: password,
}, {
apiVersion: apiVersion,
debug: false,
});
// Inicializar serviços
this.contentService = new ContentService_1.ContentService(this.client);
this.postCreateService = new PostCreateService_1.PostCreateService(this.client);
this.taxonomyService = new TaxonomyService_1.TaxonomyService(this.client);
this.mediaService = new MediaUploadService_1.MediaUploadService(this.client);
this.featuredImageService = new FeaturedImageService_1.FeaturedImageService(this.client);
}
/**
* Executa uma operação de post/página
* @param params Parâmetros da operação
* @param resource Tipo de recurso (post ou page)
* @param operation Operação a ser realizada
* @returns Dados resultantes da operação
*/
NodeService.prototype.executeOperation = function (params, resource, operation) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (operation) {
case 'create':
return [2 /*return*/, this.createResource(params, resource)];
case 'update':
return [2 /*return*/, this.updateResource(params, resource)];
case 'get':
return [2 /*return*/, this.getResource(params, resource)];
case 'getAll':
return [2 /*return*/, this.getAllResources(params, resource)];
case 'delete':
return [2 /*return*/, this.deleteResource(params, resource)];
default:
throw new Error("Unsupported operation: ".concat(operation));
}
return [2 /*return*/];
});
});
};
/**
* Converte parâmetros do nó para o formato da API WordPress
* @param params Parâmetros do nó
* @returns Parâmetros formatados para a API
*/
NodeService.prototype.convertToWordPressPost = function (params) {
var wpPost = {
title: params.title,
content: params.content,
status: params.status,
};
if (params.excerpt) {
wpPost.excerpt = params.excerpt;
}
if (params.slug) {
wpPost.slug = params.slug;
}
if (params.featured_media) {
wpPost.featured_media = params.featured_media;
}
// Converter arrays de números para strings
if (params.categories) {
wpPost.categories = params.categories.map(function (id) { return id.toString(); });
}
if (params.tags) {
wpPost.tags = params.tags.map(function (id) { return id.toString(); });
}
// Adicionar metadados SEO
if (params.meta_title) {
wpPost.meta_title = params.meta_title;
}
if (params.meta_description) {
wpPost.meta_description = params.meta_description;
}
if (params.meta_keywords) {
wpPost.meta_keywords = params.meta_keywords;
}
// Adicionar FAQ e CTA
if (params.faq) {
wpPost.faq = params.faq;
}
if (params.cta) {
wpPost.cta = params.cta;
}
return wpPost;
};
/**
* Cria um novo post/página
* @param params Parâmetros de criação
* @param resource Tipo de recurso (post ou page)
* @returns Recurso criado
*/
NodeService.prototype.createResource = function (params, resource) {
return __awaiter(this, void 0, void 0, function () {
var options, wpPost, result, categories, tags;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
options = {
updateSeoMetadata: params.updateSeoMetadata || false,
updateFaqs: params.updateFaqs || false,
updateCta: params.updateCta || false,
};
wpPost = this.convertToWordPressPost(params);
if (!(resource === 'post')) return [3 /*break*/, 2];
return [4 /*yield*/, this.postCreateService.createPost(wpPost, options)];
case 1:
result = _c.sent();
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, this.postCreateService.createPage(wpPost, options)];
case 3:
result = _c.sent();
_c.label = 4;
case 4:
if (!(((_a = params.categories) === null || _a === void 0 ? void 0 : _a.length) || ((_b = params.tags) === null || _b === void 0 ? void 0 : _b.length))) return [3 /*break*/, 12];
categories = params.categories || [];
tags = params.tags || [];
if (!(resource === 'post')) return [3 /*break*/, 6];
return [4 /*yield*/, this.taxonomyService.associateTaxonomiesWithPost(result.id, categories, tags)];
case 5:
_c.sent();
return [3 /*break*/, 8];
case 6: return [4 /*yield*/, this.taxonomyService.associateTaxonomiesWithPage(result.id, categories, tags)];
case 7:
_c.sent();
_c.label = 8;
case 8:
if (!(resource === 'post')) return [3 /*break*/, 10];
return [4 /*yield*/, this.contentService.getPost(result.id, {
includeSeoMetadata: options.updateSeoMetadata,
includeFaqs: options.updateFaqs,
includeCta: options.updateCta
})];
case 9:
result = _c.sent();
return [3 /*break*/, 12];
case 10: return [4 /*yield*/, this.contentService.getPage(result.id, {
includeSeoMetadata: options.updateSeoMetadata,
includeFaqs: options.updateFaqs,
includeCta: options.updateCta
})];
case 11:
result = _c.sent();
_c.label = 12;
case 12: return [2 /*return*/, result];
}
});
});
};
/**
* Atualiza um post/página existente
* @param params Parâmetros de atualização
* @param resource Tipo de recurso (post ou page)
* @returns Recurso atualizado
*/
NodeService.prototype.updateResource = function (params, resource) {
return __awaiter(this, void 0, void 0, function () {
var id, options, wpPost, result, categories, tags;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
id = params.id;
options = {
updateSeoMetadata: params.updateSeoMetadata || false,
updateFaqs: params.updateFaqs || false,
updateCta: params.updateCta || false,
};
wpPost = {};
if (params.title) {
wpPost.title = params.title;
}
if (params.content) {
wpPost.content = params.content;
}
if (params.status) {
wpPost.status = params.status;
}
if (params.excerpt) {
wpPost.excerpt = params.excerpt;
}
if (params.slug) {
wpPost.slug = params.slug;
}
if (params.featured_media) {
wpPost.featured_media = params.featured_media;
}
// Adicionar metadados SEO
if (params.meta_title) {
wpPost.meta_title = params.meta_title;
}
if (params.meta_description) {
wpPost.meta_description = params.meta_description;
}
if (params.meta_keywords) {
wpPost.meta_keywords = params.meta_keywords;
}
// Adicionar FAQ e CTA
if (params.faq) {
wpPost.faq = params.faq;
}
if (params.cta) {
wpPost.cta = params.cta;
}
if (!(resource === 'post')) return [3 /*break*/, 2];
return [4 /*yield*/, this.postCreateService.updatePost(id, wpPost, options)];
case 1:
result = _c.sent();
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, this.postCreateService.updatePage(id, wpPost, options)];
case 3:
result = _c.sent();
_c.label = 4;
case 4:
if (!(((_a = params.categories) === null || _a === void 0 ? void 0 : _a.length) || ((_b = params.tags) === null || _b === void 0 ? void 0 : _b.length))) return [3 /*break*/, 12];
categories = params.categories || [];
tags = params.tags || [];
if (!(resource === 'post')) return [3 /*break*/, 6];
return [4 /*yield*/, this.taxonomyService.associateTaxonomiesWithPost(id, categories, tags)];
case 5:
_c.sent();
return [3 /*break*/, 8];
case 6: return [4 /*yield*/, this.taxonomyService.associateTaxonomiesWithPage(id, categories, tags)];
case 7:
_c.sent();
_c.label = 8;
case 8:
if (!(resource === 'post')) return [3 /*break*/, 10];
return [4 /*yield*/, this.contentService.getPost(id, {
includeSeoMetadata: options.updateSeoMetadata,
includeFaqs: options.updateFaqs,
includeCta: options.updateCta
})];
case 9:
result = _c.sent();
return [3 /*break*/, 12];
case 10: return [4 /*yield*/, this.contentService.getPage(id, {
includeSeoMetadata: options.updateSeoMetadata,
includeFaqs: options.updateFaqs,
includeCta: options.updateCta
})];
case 11:
result = _c.sent();
_c.label = 12;
case 12: return [2 /*return*/, result];
}
});
});
};
/**
* Obtém um post/página específico
* @param params Parâmetros da consulta
* @param resource Tipo de recurso (post ou page)
* @returns Recurso obtido
*/
NodeService.prototype.getResource = function (params, resource) {
return __awaiter(this, void 0, void 0, function () {
var id, includeSeoMetadata, includeFaqs, includeCta, options;
return __generator(this, function (_a) {
id = params.id, includeSeoMetadata = params.includeSeoMetadata, includeFaqs = params.includeFaqs, includeCta = params.includeCta;
options = {
includeSeoMetadata: includeSeoMetadata || false,
includeFaqs: includeFaqs || false,
includeCta: includeCta || false,
};
if (resource === 'post') {
return [2 /*return*/, this.contentService.getPost(id, options)];
}
else {
return [2 /*return*/, this.contentService.getPage(id, options)];
}
return [2 /*return*/];
});
});
};
/**
* Obtém múltiplos posts/páginas
* @param params Parâmetros da consulta
* @param resource Tipo de recurso (post ou page)
* @returns Lista de recursos
*/
NodeService.prototype.getAllResources = function (params, resource) {
return __awaiter(this, void 0, void 0, function () {
var options;
return __generator(this, function (_a) {
options = {
page: params.page || 1,
perPage: params.limit || 10,
status: params.status || 'publish',
search: params.search,
categories: params.categories,
tags: params.tags,
includeSeoMetadata: params.includeSeoMetadata || false,
includeFaqs: params.includeFaqs || false,
includeCta: params.includeCta || false,
};
if (resource === 'post') {
return [2 /*return*/, this.contentService.getPosts(options)];
}
else {
return [2 /*return*/, this.contentService.getPages(options)];
}
return [2 /*return*/];
});
});
};
/**
* Exclui um post/página
* @param params Parâmetros de exclusão
* @param resource Tipo de recurso (post ou page)
* @returns true se excluído com sucesso
*/
NodeService.prototype.deleteResource = function (params, resource) {
return __awaiter(this, void 0, void 0, function () {
var id, force;
return __generator(this, function (_a) {
id = params.id, force = params.force;
if (resource === 'post') {
return [2 /*return*/, this.postCreateService.deletePost(id, force)];
}
else {
return [2 /*return*/, this.postCreateService.deletePage(id, force)];
}
return [2 /*return*/];
});
});
};
/**
* Converte um único resultado em formato de nó n8n
* @param result Resultado da operação
* @returns Dados formatados para o n8n
*/
NodeService.prototype.formatSingleOutput = function (result) {
var _a;
if (!result) {
return [{
json: {
success: false,
message: 'No data returned from WordPress API',
timestamp: new Date().toISOString(),
}
}];
}
// Adicionar campos úteis para uso em workflows subsequentes
var enhancedResult = __assign(__assign({}, result), { success: true, timestamp: new Date().toISOString(),
// Extrair URL completa do post para facilitar acesso
permalink: result.link || null,
// Fornecer status formatado para legibilidade
statusLabel: this.getStatusLabel(result.status),
// ID formatado para uso em templates
id_str: result.id ? result.id.toString() : '',
// Extrair texto do conteúdo (sem HTML)
content_text: ((_a = result.content) === null || _a === void 0 ? void 0 : _a.rendered) ? this.stripHtml(result.content.rendered) : '',
// URL da imagem destacada (se disponível)
featured_image_url: result.featured_media_url || null });
return [{ json: enhancedResult }];
};
/**
* Converte múltiplos resultados em formato de nó n8n
* @param results Lista de resultados
* @returns Dados formatados para o n8n
*/
NodeService.prototype.formatMultipleOutput = function (results) {
var _this = this;
if (!results || !Array.isArray(results) || results.length === 0) {
return [{
json: {
success: false,
items: [],
count: 0,
message: 'No items found matching the criteria',
timestamp: new Date().toISOString(),
}
}];
}
// Adicionar metadados úteis para cada item
var enhancedResults = results.map(function (item) {
var _a;
return __assign(__assign({}, item), { success: true,
// Extrair URL completa do post para facilitar acesso
permalink: item.link || null,
// Fornecer status formatado para legibilidade
statusLabel: _this.getStatusLabel(item.status),
// ID formatado para uso em templates
id_str: item.id ? item.id.toString() : '',
// Extrair texto do conteúdo (sem HTML)
content_text: ((_a = item.content) === null || _a === void 0 ? void 0 : _a.rendered) ? _this.stripHtml(item.content.rendered) : '',
// URL da imagem destacada (se disponível)
featured_image_url: item.featured_media_url || null });
});
// Para cada item, criar um objeto de saída para n8n
return enhancedResults.map(function (item) { return ({ json: item }); });
};
/**
* Converte resultado booleano em formato de nó n8n
* @param success Resultado da operação
* @param id ID do recurso (opcional)
* @returns Dados formatados para o n8n
*/
NodeService.prototype.formatBooleanOutput = function (success, id) {
return [{
json: {
success: success,
id: id,
message: success
? id
? "Operation completed successfully for item with ID ".concat(id)
: 'Operation completed successfully'
: 'Operation failed',
timestamp: new Date().toISOString(),
}
}];
};
/**
* Remove tags HTML de uma string
* @param html String HTML
* @returns Texto sem HTML
*/
NodeService.prototype.stripHtml = function (html) {
// Remover tags HTML
var text = html.replace(/<\/?[^>]+(>|$)/g, ' ');
// Normalizar espaços
return text.replace(/\s+/g, ' ').trim();
};
/**
* Obtém o label do status para exibição
* @param status Status do WordPress
* @returns Label formatado
*/
NodeService.prototype.getStatusLabel = function (status) {
var statusMap = {
'publish': 'Published',
'draft': 'Draft',
'pending': 'Pending Review',
'private': 'Private',
'future': 'Scheduled',
'trash': 'Trash',
};
return statusMap[status] || status;
};
return NodeService;
}());
exports.NodeService = NodeService;