UNPKG

@ai-growth/wordpress

Version:

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

521 lines (520 loc) 24 kB
"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;