Workflow: 📄🛠️PDF2Blog
Integrations: code, extractFromFile, formTrigger, ghost, if, noOp, stickyNote, stopAndError

{"id": "dMiUunCiaMsCr1Wu", "meta": {"instanceId": "workflow-01e9f3c3", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:43.759775", "updatedAt": "2025-09-29T07:07:43.759794", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production"}, "name": "\ud83d\udcc4\ud83d\udee0\ufe0fPDF2Blog", "tags": ["automation", "n8n", "production-ready", "excellent", "optimized"], "nodes": [{"id": "58a4923b-3e8f-4abd-bebc-6488f8b04101", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [580, 1340], "parameters": {"color": 3, "width": 461, "height": 359.27075107113785, "content": "## Upload PDF and Extract Text"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "eb0ec98a-9c9d-4203-9586-9e81e23e7232", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [1087.027580347215, 1340], "parameters": {"color": 4, "width": 508.8267597424673, "height": 532.0416571599118, "content": "## Create Blog Post"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "b2d3cb70-4335-43a2-80db-889559ebf020", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [2020, 1340], "parameters": {"color": 6, "width": 370.4721755771028, "height": 352.3823858238478, "content": "## Publish Draft Blog Post to Ghost"}, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow."}, {"id": "766daeb8-23e8-4ee9-acee-ea2a787bbfda", "name": "Upload PDF", "type": "n8n-nodes-base.formTrigger", "position": [660, 1480], "webhookId": "6c4a4180-7206-469f-a645-f41824ccbf42", "parameters": {"path": "pdf", "options": {}, "formTitle": "PDF2Blog", "formFields": {"values": [{"fieldType": "file", "fieldLabel": "Upload PDF File", "multipleFiles": false, "requiredField": true, "acceptFileTypes": ".pdf"}]}, "formDescription": "Transform PDFs into captivating blog posts"}, "typeVersion": 2.1, "notes": "This formTrigger node performs automated tasks as part of the workflow."}, {"id": "055a734e-7128-487a-b109-a64214010bb2", "name": "Extract Text", "type": "n8n-nodes-base.extractFromFile", "position": [860, 1480], "parameters": {"options": {}, "operation": "pdf", "binaryPropertyName": "Upload_PDF_File"}, "typeVersion": 1, "notes": "This extractFromFile node performs automated tasks as part of the workflow."}, {"id": "44256745-276a-4c88-80b6-d12a568d07e9", "name": "Post to Ghost", "type": "n8n-nodes-base.ghost", "position": [2140, 1480], "parameters": {"title": "={{ $json.title }}", "source": "adminApi", "content": "={{ $json.content }}", "operation": "create", "additionalFields": {}}, "credentials": {"ghostAdminApi": {"id": "yiqmX1MjG1FU3wyR", "name": "Ghost Admin account"}}, "typeVersion": 1, "notes": "This ghost node performs automated tasks as part of the workflow."}, {"id": "9796d4eb-e9d6-43bb-80c0-c527f3dc8843", "name": "gpt-4o-mini", "type": "n8n-nodes-base.noOp", "position": [1180, 1680], "parameters": {"model": "gpt-4o-mini-2024-07-18", "options": {"responseFormat": "json_object"}}, "credentials": {"openAiApi": {"id": "h597GY4ZJQD47RQd", "name": "OpenAi account"}}, "typeVersion": 1, "notes": "This lmChatOpenAi node performs automated tasks as part of the workflow."}, {"id": "719e7578-df85-441c-8d2f-cb7d3f7bb92f", "name": "Structured Output - JSON", "type": "n8n-nodes-base.noOp", "position": [1400, 1680], "parameters": {"jsonSchemaExample": "{\n    \"title\": \"title\",\n    \"content\": \"content\"\n}"}, "typeVersion": 1.2, "notes": "This outputParserStructured node performs automated tasks as part of the workflow."}, {"id": "5f16e695-3585-468f-8fcb-794f5e3b56d4", "name": "Separate Title & Content", "type": "n8n-nodes-base.code", "position": [1660, 1480], "parameters": {"jsCode": "try {\n  // Check if input exists and has the expected structure\n  const input = $input.all();\n  if (!input || !input.length) {\n    throw new Error('No input data received');\n  }\n\n  const firstItem = input[0];\n  if (!firstItem || !firstItem.json || !firstItem.json.output || !firstItem.json.output.output) {\n    throw new Error('Invalid input structure: missing required properties');\n  }\n\n  const output = firstItem.json.output.output;\n  \n  // Validate title exists\n  if (!output.title) {\n    throw new Error('Missing title in output');\n  }\n\n  // Validate content exists\n  if (!output.content) {\n    throw new Error('Missing content in output');\n  }\n\n  const title = output.title;\n  const content = output.content.replace(/<h1>.*?<\\/h1>/s, '').trim();\n\n  // Validate final content is not empty after processing\n  if (!content) {\n    throw new Error('Content is empty after processing');\n  }\n\n  console.log('Successfully processed content');\n\n  console.log(title)\n  console.log(content)\n  \n  return { title, content };\n\n} catch (error) {\n  // Log the error for debugging\n  console.error('Error processing content:', error.message);\n  \n  // Return a graceful failure object\n  return {\n    error: true,\n    message: error.message,\n    title: '',\n    content: '',\n    timestamp: new Date().toISOString()\n  };\n}"}, "typeVersion": 2, "notes": "This code node performs automated tasks as part of the workflow."}, {"id": "e4d41cf6-575d-469a-a7c5-fba0fc1cc568", "name": "If Node", "type": "n8n-nodes-base.if", "position": [1840, 1480], "parameters": {"options": {}, "conditions": {"options": {"version": 2, "leftValue": "", "caseSensitive": true, "typeValidation": "strict"}, "combinator": "and", "conditions": [{"id": "aaf83c73-65f3-4a88-87f3-25b1acaf93ef", "operator": {"type": "string", "operation": "notEmpty", "singleValue": true}, "leftValue": "={{ $json.title }}", "rightValue": ""}, {"id": "d9af5bce-f0fb-4c20-8b6a-b01a3bf3e1d1", "operator": {"type": "string", "operation": "notEmpty", "singleValue": true}, "leftValue": "={{ $json.content }}", "rightValue": ""}]}}, "typeVersion": 2.2, "notes": "This if node performs automated tasks as part of the workflow."}, {"id": "b6b64f53-b689-440c-bc2e-478bccbfa5f5", "name": "Do Nothing", "type": "n8n-nodes-base.noOp", "position": [2020, 1740], "parameters": {}, "typeVersion": 1, "notes": "This noOp node performs automated tasks as part of the workflow."}, {"id": "20b12b54-d329-4c70-9fa2-0dc598477a66", "name": "Create Structured Blog Post", "type": "n8n-nodes-base.noOp", "position": [1200, 1480], "parameters": {"text": "={{ $json.text }}", "agent": "conversationalAgent", "options": {"systemMessage": "=Analyze the provided PDF article and create a compelling blog post that will be returned in JSON format with two fields: \"title\" and \"content\". Follow these specifications:\n\n## Title Requirements\n- Create an engaging, SEO-friendly title under 10 words\n- Must not contain a colon\n- Should capture the article's essence\n- Will be formatted as an H1 in the content\n\n## Content Structure\n- Introduction (150-200 words)\n  * Compelling hook\n  * Topic context and importance\n  * Preview of main points\n\n- Main Content (6-8 chapters)\n  * Each chapter requires:\n    - Relevant H2 heading\n    - 300-400 words of unique content\n    - Specific topic focus\n    - Source material quotes/data\n    - Smooth transitions\n\n- Conclusion (200-250 words)\n  * Key takeaways\n  * Final thoughts/implications\n\n## Formatting Guidelines\n- Use proper HTML tags throughout\n- Structure with <p> tags for paragraphs\n- Include appropriate spacing\n- Use <blockquote> for direct quotes\n- Maintain consistent formatting\n- Write in clear, professional tone\n- Break up long paragraphs\n- Use engaging subheadings\n- Include transitional phrases\n\nThe content should be original, avoid direct copying, and maintain a consistent voice throughout. The final JSON response should contain only the title and content fields, with the content including all HTML formatting."}, "promptType": "define", "hasOutputParser": true}, "retryOnFail": true, "typeVersion": 1.6, "notes": "This agent node performs automated tasks as part of the workflow."}, {"id": "error-1c5b67d5", "name": "Error Handler", "type": "n8n-nodes-base.stopAndError", "typeVersion": 1, "position": [1000, 400], "parameters": {"message": "Workflow execution error", "options": {}}}], "active": false, "pinData": {}, "settings": {"executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000}, "versionId": "ae25fae9-8ae8-4a49-ae90-dd2a89599f08", "connections": {"055a734e-7128-487a-b109-a64214010bb2": {"main": [[{"node": "error-handler-055a734e-7128-487a-b109-a64214010bb2-86725086", "type": "main", "index": 0}]]}, "9796d4eb-e9d6-43bb-80c0-c527f3dc8843": {"main": [[{"node": "error-handler-9796d4eb-e9d6-43bb-80c0-c527f3dc8843-dd972d26", "type": "main", "index": 0}]]}}, "description": "Automated workflow: \ud83d\udcc4\ud83d\udee0\ufe0fPDF2Blog. This workflow integrates 11 different services: stickyNote, formTrigger, code, agent, ghost. It contains 14 nodes and follows best practices for error handling and security.", "notes": "Excellent quality workflow: \ud83d\udcc4\ud83d\udee0\ufe0fPDF2Blog. This workflow has been optimized for production use with comprehensive error handling, security, and documentation."}