import { INodeType, INodeTypeDescription, IExecuteFunctions, NodeConnectionType } from 'n8n-workflow'; import { createClient, ApiKeyStrategy } from '@wix/sdk'; import { draftPosts } from '@wix/blog'; import { parseDocument } from 'htmlparser2'; enum TextAlignment { AUTO = 'AUTO', LEFT = 'LEFT', RIGHT = 'RIGHT', CENTER = 'CENTER', JUSTIFY = 'JUSTIFY', } enum NodeType { PARAGRAPH = 'PARAGRAPH', TEXT = 'TEXT', HEADING = 'HEADING', IMAGE = 'IMAGE', EMBEDDED_VIDEO = 'EMBEDDED_VIDEO', } enum DecorationType { BOLD = 'BOLD', ITALIC = 'ITALIC', UNDERLINE = 'UNDERLINE', } function parseHtmlToRichContent(html: string) { const document = parseDocument(html); const paragraphs: any[] = []; const traverse = (node: any) => { if (node.type === 'tag') { switch (node.name) { case 'h2': case 'h3': paragraphs.push({ type: NodeType.HEADING, nodes: [ { type: NodeType.TEXT, textData: { text: node.children[0].data.trim(), }, }, ], }); break; case 'p': const { cleanText, textDecorations } = extractTextAndDecorations(node.children); paragraphs.push({ type: NodeType.PARAGRAPH, nodes: [ { type: NodeType.TEXT, textData: { text: cleanText, decorations: textDecorations, }, }, ], paragraphData: { textStyle: { textAlignment: TextAlignment.AUTO }, indentation: 0, }, }); break; case 'img': const src = node.attribs.src; if (src) { paragraphs.push({ type: NodeType.IMAGE, nodes: [ { type: NodeType.TEXT, textData: { text: 'Image', }, }, ], imageData: { src, alt: node.attribs.alt || '', }, }); } break; case 'iframe': const videoSrc = node.attribs.src; if (videoSrc) { paragraphs.push({ type: NodeType.EMBEDDED_VIDEO, nodes: [ { type: NodeType.TEXT, textData: { text: 'Embedded Video', }, }, ], videoData: { url: videoSrc, }, }); } break; default: break; } } if (node.children && Array.isArray(node.children)) { node.children.forEach((child: any) => traverse(child)); } }; traverse(document); if (paragraphs.length === 0) { const { cleanText, textDecorations } = extractTextAndDecorations(document.children); paragraphs.push({ type: NodeType.PARAGRAPH, nodes: [ { type: NodeType.TEXT, textData: { text: cleanText, decorations: textDecorations, }, }, ], paragraphData: { textStyle: { textAlignment: TextAlignment.AUTO }, indentation: 0, }, }); } return { nodes: paragraphs, metadata: {} }; } function extractTextAndDecorations(nodes: any[]) { let cleanText = ''; const decorations: { type: DecorationType; start: number; end: number }[] = []; function processNode(node: any, activeDecorations: DecorationType[] = []) { if (node.type === 'text') { const start = cleanText.length; cleanText += node.data; const end = cleanText.length; activeDecorations.forEach((type) => { decorations.push({ type, start, end }); }); } else if (node.type === 'tag') { let newDecorations = [...activeDecorations]; if (node.name === 'b' || node.name === 'strong') newDecorations.push(DecorationType.BOLD); if (node.name === 'i' || node.name === 'em') newDecorations.push(DecorationType.ITALIC); if (node.name === 'u') newDecorations.push(DecorationType.UNDERLINE); if (node.children && Array.isArray(node.children)) { node.children.forEach((child: any) => processNode(child, newDecorations)); } } } nodes.forEach((node) => processNode(node)); return { cleanText, textDecorations: decorations }; } export class WixBlog implements INodeType { description: INodeTypeDescription = { displayName: 'Wix Blog', name: 'wixBlog', group: ['transform'], version: 1, description: 'Publishes draft posts to Wix Blog using Wix REST API', defaults: { name: 'Wix Blog', color: '#32a852' }, inputs: [{ type: NodeConnectionType.Main }], outputs: [{ type: NodeConnectionType.Main }], properties: [ { displayName: 'API Key', name: 'apiKey', type: 'string', default: '', required: true }, { displayName: 'Site ID', name: 'siteId', type: 'string', default: '', required: true }, { displayName: 'Article Title', name: 'articleTitle', type: 'string', default: '', required: true }, { displayName: 'HTML Content', name: 'htmlContent', type: 'string', default: '', required: true }, { displayName: 'Member ID', name: 'memberId', type: 'string', default: '', required: true }, ], }; async execute(this: IExecuteFunctions) { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { const apiKey = this.getNodeParameter('apiKey', i) as string; const siteId = this.getNodeParameter('siteId', i) as string; const articleTitle = this.getNodeParameter('articleTitle', i) as string; const htmlContent = this.getNodeParameter('htmlContent', i) as string; const memberId = this.getNodeParameter('memberId', i) as string; // Get the member ID const richContent = parseHtmlToRichContent(htmlContent); const myWixClient = createClient({ modules: { draftPosts }, auth: ApiKeyStrategy({ siteId, apiKey }), }); // Pass the memberId to the API request const result = await myWixClient.draftPosts.createDraftPost({ title: articleTitle, richContent: richContent, memberId: memberId, // Added memberId to the request }); returnData.push({ json: result as unknown as { [key: string]: any }, // Returning the result with dynamic properties }); } return this.prepareOutputData(returnData); } }