{ "id": "dMiUunCiaMsCr1Wu", "meta": { "instanceId": "03907a25f048377a8789a4332f28148522ba31ee907fababf704f1d88130b1b6", "templateCredsSetupCompleted": true }, "name": "📄🛠️PDF2Blog", "tags": [], "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "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 }, { "id": "9796d4eb-e9d6-43bb-80c0-c527f3dc8843", "name": "gpt-4o-mini", "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi", "position": [ 1180, 1680 ], "parameters": { "model": "gpt-4o-mini-2024-07-18", "options": { "responseFormat": "json_object" } }, "credentials": { "openAiApi": { "id": "h597GY4ZJQD47RQd", "name": "OpenAi account" } }, "typeVersion": 1 }, { "id": "719e7578-df85-441c-8d2f-cb7d3f7bb92f", "name": "Structured Output - JSON", "type": "@n8n/n8n-nodes-langchain.outputParserStructured", "position": [ 1400, 1680 ], "parameters": { "jsonSchemaExample": "{\n \"title\": \"title\",\n \"content\": \"content\"\n}" }, "typeVersion": 1.2 }, { "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(/
tags for paragraphs\n- Include appropriate spacing\n- Use
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 } ], "active": false, "pinData": {}, "settings": { "executionOrder": "v1" }, "versionId": "ae25fae9-8ae8-4a49-ae90-dd2a89599f08", "connections": { "If": { "main": [ [ { "node": "Post to Ghost", "type": "main", "index": 0 } ], [ { "node": "Do Nothing", "type": "main", "index": 0 } ] ] }, "Upload PDF": { "main": [ [ { "node": "Extract Text", "type": "main", "index": 0 } ] ] }, "gpt-4o-mini": { "ai_languageModel": [ [ { "node": "Create Structured Blog Post", "type": "ai_languageModel", "index": 0 } ] ] }, "Extract Text": { "main": [ [ { "node": "Create Structured Blog Post", "type": "main", "index": 0 } ] ] }, "Separate Title & Content": { "main": [ [ { "node": "If", "type": "main", "index": 0 } ] ] }, "Structured Output - JSON": { "ai_outputParser": [ [ { "node": "Create Structured Blog Post", "type": "ai_outputParser", "index": 0 } ] ] }, "Create Structured Blog Post": { "main": [ [ { "node": "Separate Title & Content", "type": "main", "index": 0 } ] ] } } }