AutomationFlowsAI & RAG › Send PDF Document Summaries with Corenexis Ocr, Gpt-4.1-mini, Gpt-4o-mini…

Send PDF Document Summaries with Corenexis Ocr, Gpt-4.1-mini, Gpt-4o-mini…

Original n8n title: Send PDF Document Summaries with Corenexis Ocr, Gpt-4.1-mini, Gpt-4o-mini and Gmail

ByisaWOW @isawow on n8n.io

Upload any PDF through a form and this workflow extracts the full text using CoreNexis OCR, generates a structured 5-section summary with GPT-4.1-mini, converts it into a branded HTML email with GPT-4o-mini, and delivers it to your inbox automatically. User fills a form with…

Event trigger★★★★☆ complexityAI-powered26 nodesForm TriggerHTTP RequestAgentOpenAI ChatGmail
AI & RAG Trigger: Event Nodes: 26 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #15956 — we link there as the canonical source.

This workflow follows the Agent → Form Trigger recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "oxrpLX3I4Mw9RYAu",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "PDF AI Summary Mailer",
  "tags": [],
  "nodes": [
    {
      "id": "4d1d5421-da70-47ec-892b-38ba144c2a91",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1952,
        -416
      ],
      "parameters": {
        "color": 4,
        "width": 588,
        "height": 1172,
        "content": "## PDF Document Summarizer \u2014 CoreNexis OCR + GPT-4.1-mini + GPT-4o-mini + Gmail\n\nFor anyone who wants to upload a PDF and automatically receive a professional document summary in their inbox. User fills a form with their name, email, and PDF upload. A Code node extracts the binary PDF and user metadata. The PDF is submitted to the CoreNexis OCR API for async text extraction. A Code node extracts the job ID. After an initial 4-second wait the status endpoint is polled \u2014 if still processing, a 1-minute retry loop runs; once completed the extracted text file URL is downloaded. A Code node prepares the text for the AI. GPT-4.1-mini generates a 5-section structured Markdown summary. A second Code node extracts the summary text. GPT-4o-mini converts the Markdown summary into a branded HTML email with inline CSS. A final Code node cleans the HTML output and handles fallback formatting. Gmail sends the HTML summary to the user.\n\n## How it works\n- **1. Form \u2014 PDF Upload** collects name, email, and PDF file\n- **2. Code \u2014 Prepare PDF Data** finds the PDF binary key and extracts user metadata\n- **3. HTTP \u2014 CoreNexis OCR Submit** posts the PDF to CoreNexis with output_format=text and lang=eng\n- **4. Code \u2014 Get Job ID** validates the response and extracts job_id, status_url, total_pages\n- **5. Wait \u2014 4 Seconds** gives the OCR API initial processing time\n- **6. HTTP \u2014 Poll OCR Status** polls the job status endpoint\n- **7. Code \u2014 Merge Status** updates status, txt_url, pages_done, and poll_count\n- **8. IF \u2014 Still Processing?** \u2014 TRUE: 1-minute retry wait then polls again | FALSE: checks completed\n- **9. Wait \u2014 1 Minute Retry** waits 1 minute before re-polling (note: named 4s but actually 1 minute)\n- **10. IF \u2014 OCR Completed?** \u2014 TRUE: downloads text | FALSE: stops (failed or unknown status)\n- **11. HTTP \u2014 Download Extracted Text** downloads the extracted .txt file from CoreNexis\n- **12. Code \u2014 Prep Text for Agent** merges the text with meeting metadata for the summary agent\n- **13. AI Agent \u2014 Generate Document Summary** uses GPT-4.1-mini to write a 5-section Markdown summary\n- **OpenAI \u2014 GPT-4.1-mini Model** language model for summary agent\n- **14. Code \u2014 Extract Summary** pulls the summary Markdown and assembles the email payload\n- **15. AI Agent \u2014 Generate HTML Email** uses GPT-4o-mini to convert the summary into branded HTML\n- **OpenAI \u2014 GPT-4o-mini Model** language model for HTML email agent\n- **16. Code \u2014 Extract HTML** strips markdown fences and handles HTML fallback\n- **17. Gmail \u2014 Send Summary Email** sends the HTML email to the user's submitted email address\n\n## Set up steps\n1. In **3. HTTP \u2014 CoreNexis OCR Submit** \u2014 replace `YOUR_CORENEXIS_API_KEY` with your CoreNexis API key (get it at api.corenexis.com)\n2. In **6. HTTP \u2014 Poll OCR Status** \u2014 replace `YOUR_CORENEXIS_API_KEY`\n3. In **OpenAI \u2014 GPT-4.1-mini Model** \u2014 connect your OpenAI API credential\n4. In **OpenAI \u2014 GPT-4o-mini Model** \u2014 connect your OpenAI API credential\n5. In **17. Gmail \u2014 Send Summary Email** \u2014 connect your Gmail OAuth2 credential"
      },
      "typeVersion": 1
    },
    {
      "id": "3c4689fd-7357-483d-8582-8356a829a6e2",
      "name": "Section \u2014 Form Submission and PDF Data Preparation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1328,
        -128
      ],
      "parameters": {
        "color": 5,
        "width": 436,
        "height": 516,
        "content": "## Form Submission and PDF Data Preparation\nForm collects name, email, and PDF file upload. Code node finds the PDF binary key and extracts user metadata into a clean JSON object."
      },
      "typeVersion": 1
    },
    {
      "id": "2852f600-d369-4292-b0ef-75f4f989f162",
      "name": "Section \u2014 CoreNexis OCR Submit and Job ID Extract",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -864,
        -64
      ],
      "parameters": {
        "color": 6,
        "width": 644,
        "height": 372,
        "content": "## CoreNexis OCR API Submit and Job ID Extract\nSubmits the PDF binary to CoreNexis OCR API with text output format. Validates the response and extracts job_id and status_url. Initial 4-second wait before first poll."
      },
      "typeVersion": 1
    },
    {
      "id": "833ebe1f-5da3-41a9-8747-9d5f0c68ec9a",
      "name": "Section \u2014 OCR Status Polling Loop",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -176,
        -112
      ],
      "parameters": {
        "color": 6,
        "width": 996,
        "height": 500,
        "content": "## OCR Status Polling Loop\nPolls the CoreNexis job status endpoint. Merges status into the data object. IF still processing \u2014 1-minute retry wait then polls again. IF not processing \u2014 checks for completed status to proceed to download."
      },
      "typeVersion": 1
    },
    {
      "id": "e6546b1b-81f1-4891-9458-e138deeafca8",
      "name": "Section \u2014 Text Download and Agent Preparation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        896,
        -144
      ],
      "parameters": {
        "color": 6,
        "width": 644,
        "height": 308,
        "content": "## Text Download and Agent Preparation\nDownloads the extracted text file from the CoreNexis output URL. Merges with job metadata for the summary AI agent."
      },
      "typeVersion": 1
    },
    {
      "id": "aa371816-006c-41fc-a166-c6a7df5f4fd5",
      "name": "Section \u2014 GPT-4.1-mini Document Summary Generation",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1584,
        -272
      ],
      "parameters": {
        "color": 6,
        "width": 532,
        "height": 772,
        "content": "## GPT-4.1-mini Document Summary Generation\nGenerates a 5-section structured Markdown summary: Document Overview, Key Points, Important Numbers and Dates, Action Items, and Executive Summary. Code node extracts the output and assembles the email payload."
      },
      "typeVersion": 1
    },
    {
      "id": "77c9be2d-9a58-4242-9f21-807cf43f0310",
      "name": "Section \u2014 GPT-4o-mini HTML Email Build and Gmail Send",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2176,
        -224
      ],
      "parameters": {
        "color": 4,
        "width": 804,
        "height": 628,
        "content": "## GPT-4o-mini HTML Email Build and Gmail Send\nConverts the Markdown summary into a branded HTML email with CoreNexis styling and inline CSS. Code node cleans the output and handles fallback. Gmail sends the HTML summary to the user's submitted email."
      },
      "typeVersion": 1
    },
    {
      "id": "8077f6e7-4705-4fce-9029-7606addc0726",
      "name": "1. Form \u2014 PDF Upload",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -1264,
        80
      ],
      "parameters": {
        "options": {
          "respondWithOptions": {
            "values": {}
          }
        },
        "formTitle": "PDF Document Summarizer \u2014 Powered by CoreNexis",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Your Name",
              "placeholder": "Aapka naam",
              "requiredField": true
            },
            {
              "fieldType": "email",
              "fieldLabel": "Your Email",
              "placeholder": "user@example.com",
              "requiredField": true
            },
            {
              "fieldType": "file",
              "fieldLabel": "PDF Document",
              "multipleFiles": false,
              "requiredField": true
            }
          ]
        },
        "formDescription": "Apna PDF upload karein. AI summary generate karke aapke email pe bhej diya jayega."
      },
      "typeVersion": 2.2
    },
    {
      "id": "bf07531c-b8a4-4926-ab44-2ea6e3d361a0",
      "name": "2. Code \u2014 Prepare PDF Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -1040,
        80
      ],
      "parameters": {
        "jsCode": "const body = $input.first().json;\nconst binary = $input.first().binary || {};\n\nconst pdfKey = Object.keys(binary).find(k => \n  (binary[k].mimeType || '').includes('pdf') ||\n  k.toLowerCase().includes('pdf') ||\n  k.includes('Document')\n) || Object.keys(binary)[0];\n\nif (!pdfKey) {\n  throw new Error('PDF file nahi mili. Please PDF upload karein.');\n}\n\nreturn [{\n  json: {\n    name: body['Your Name'] || 'User',\n    email: body['Your Email'],\n    pdf_key: pdfKey,\n    started_at: new Date().toISOString()\n  },\n  binary: binary\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "f5445462-9d07-4359-9db9-3a7e60116d07",
      "name": "3. HTTP \u2014 CoreNexis OCR Submit",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -816,
        80
      ],
      "parameters": {
        "url": "https://api.corenexis.com/pdf-to-text/v1",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "pdf",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "={{ $json.pdf_key }}"
            },
            {
              "name": "output_format",
              "value": "text"
            },
            {
              "name": "lang",
              "value": "eng"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "YOUR_CORENEXIS_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9c0c4085-9ec4-419e-9b0d-c96e1d1c2d43",
      "name": "4. Code \u2014 Get Job ID",
      "type": "n8n-nodes-base.code",
      "position": [
        -592,
        80
      ],
      "parameters": {
        "jsCode": "const resp = $input.first().json;\n\nif (!resp.success) {\n  throw new Error('CoreNexis Error: ' + (resp.message || JSON.stringify(resp)));\n}\n\nconst prev = $('2. Code \u2014 Prepare PDF Data').first().json;\n\nreturn [{\n  json: {\n    ...prev,\n    job_id: resp.data.job_id,\n    status_url: resp.data.status_url,\n    total_pages: resp.data.total_pages,\n    file_size: resp.data.file_size,\n    poll_count: 0\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "2cd16073-d555-4c77-aef8-483c0795eb47",
      "name": "5. Wait \u2014 4 Seconds",
      "type": "n8n-nodes-base.wait",
      "position": [
        -368,
        80
      ],
      "parameters": {
        "amount": 4
      },
      "typeVersion": 1.1
    },
    {
      "id": "7e0240f6-6712-4731-a7d3-ff5e4be76c25",
      "name": "6. HTTP \u2014 Poll OCR Status",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -144,
        80
      ],
      "parameters": {
        "url": "=https://api.corenexis.com/pdf-to-text/status/{{ $json.job_id }}",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "x-api-key",
              "value": "YOUR_CORENEXIS_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b177fda9-6695-4f7f-8745-ea9ea3d6560e",
      "name": "7. Code \u2014 Merge Status",
      "type": "n8n-nodes-base.code",
      "position": [
        96,
        16
      ],
      "parameters": {
        "jsCode": "const resp = $input.first().json;\nconst prev = $('4. Code \u2014 Get Job ID').first().json;\n\nreturn [{\n  json: {\n    ...prev,\n    status: resp.data.status,\n    txt_url: resp.data?.output?.txt || null,\n    pages_done: resp.data?.pages_processed || 0,\n    poll_count: (prev.poll_count || 0) + 1\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "c8840221-0c42-4bdb-a7fc-1daf482e5452",
      "name": "8. IF \u2014 Still Processing?",
      "type": "n8n-nodes-base.if",
      "position": [
        400,
        16
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "still-processing",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "processing"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "00e8523a-9695-445b-8ff3-39e9b02bf3b6",
      "name": "9. Wait \u2014 1 Minute Retry",
      "type": "n8n-nodes-base.wait",
      "position": [
        624,
        176
      ],
      "parameters": {
        "unit": "minutes",
        "amount": 1
      },
      "typeVersion": 1.1
    },
    {
      "id": "93cfb3bc-5fc4-4c16-ae90-d968ec8b5afa",
      "name": "10. IF \u2014 OCR Completed?",
      "type": "n8n-nodes-base.if",
      "position": [
        624,
        -32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "is-completed",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "completed"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "58d5cc64-b654-4f47-8473-58acbc41ce57",
      "name": "11. HTTP \u2014 Download Extracted Text",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        976,
        -48
      ],
      "parameters": {
        "url": "={{ $json.txt_url }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "45231b72-11b4-41a9-a594-f5a994c50dc4",
      "name": "12. Code \u2014 Prep Text for Agent",
      "type": "n8n-nodes-base.code",
      "position": [
        1376,
        -48
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json;\nconst prev = $('7. Code \u2014 Merge Status').first().json;\n\nconst text = typeof raw === 'string' ? raw : JSON.stringify(raw);\n\nreturn [{\n  json: {\n    ...prev,\n    extracted_text: text\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "7bdc766e-f6bd-440c-94c7-4c558abf8f80",
      "name": "13. AI Agent \u2014 Generate Document Summary",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1632,
        -64
      ],
      "parameters": {
        "text": "=Analyze this document and generate a structured summary:\n\n{{ $json.extracted_text }}",
        "options": {
          "systemMessage": "You are a professional document analyst.\n\nRead the document carefully and produce a structured summary in this EXACT format:\n\n## Document Overview\n(2-3 sentences describing what this document is about)\n\n## Key Points\n- (key point 1)\n- (key point 2)\n- (key point 3)\n- (key point 4)\n- (key point 5)\n\n## Important Numbers & Dates\n- (all amounts, percentages, dates, deadlines from the document)\n\n## Action Items\n- (required actions or next steps \u2014 write 'None identified' if none found)\n\n## Executive Summary\n(3-4 sentence professional summary of the entire document)\n\nRules:\n- Be accurate and factual\n- Only use information present in the document\n- Be concise but comprehensive\n- Use clean Markdown formatting"
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "9be71eaf-4407-430e-bcf4-51706c1542c2",
      "name": "OpenAI \u2014 GPT-4.1-mini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1632,
        304
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini",
          "cachedResultName": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "784308f2-1360-469b-b74a-0c55943f305e",
      "name": "14. Code \u2014 Extract Summary",
      "type": "n8n-nodes-base.code",
      "position": [
        1984,
        -64
      ],
      "parameters": {
        "jsCode": "const agentOutput = $input.first().json;\nconst summary = agentOutput.output || agentOutput.text || '';\nconst prev = $('12. Code \u2014 Prep Text for Agent').first().json;\n\nreturn [{\n  json: {\n    name: prev.name,\n    email: prev.email,\n    started_at: prev.started_at,\n    pages_done: prev.pages_done,\n    file_name: prev.file_name || 'document.pdf',\n    job_id: prev.job_id,\n    summary_md: summary\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "166d2ecc-5a7d-46b0-a26b-2800a63c7a00",
      "name": "15. AI Agent \u2014 Generate HTML Email",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        2208,
        -64
      ],
      "parameters": {
        "text": "={{ $('14. Code \u2014 Extract Summary').item.json.name }} ke liye document summary email banao.\n\nDate: {{ $('14. Code \u2014 Extract Summary').item.json.started_at }}\nPages: {{ $('14. Code \u2014 Extract Summary').item.json.pages_done }}\nFile: {{ $('14. Code \u2014 Extract Summary').item.json.file_name }}\n\n=== SUMMARY TO CONVERT ===\n{{ $('14. Code \u2014 Extract Summary').item.json.summary_md }}\n=== END OF SUMMARY ===\n\nOutput ONLY raw HTML \u2014 no markdown, no backticks, no explanation.",
        "options": {
          "systemMessage": "You are an expert HTML email designer.\n\nConvert the given document summary into a beautiful, professional HTML email.\n\nSTRICT OUTPUT RULES:\n- Output ONLY raw HTML starting with <!DOCTYPE html>\n- NO markdown before or after the HTML\n- NO backticks or code fences\n- NO explanation text\n- Just pure HTML from start to finish\n\nDESIGN SPECIFICATIONS (all CSS must be inline):\n\n1. HEADER SECTION:\n<div style=\"background:#1a1a2e;padding:28px;text-align:center;\">\n  <p style=\"color:#e94560;font-size:11px;letter-spacing:2px;margin:0 0 8px;\">CORENEXIS OCR</p>\n  <h1 style=\"color:white;font-size:22px;font-weight:600;margin:0;\">Document Summary Report</h1>\n</div>\n\n2. INFO BAR:\n<div style=\"background:#e94560;padding:10px 28px;\">\n  <p style=\"color:white;font-size:12px;margin:0;\">For: [name] | [date] | [pages] pages processed</p>\n</div>\n\n3. CONTENT BODY:\n<div style=\"background:white;padding:28px;\">\n  - Each ## section becomes its own block with border-top:2px solid #f0f0f0\n  - Section headings: color:#1a1a2e, font-size:15px, font-weight:bold\n  - Bullet points in <ul><li style=\"color:#444;line-height:1.8;\"> tags\n  - Numbers and amounts wrapped in <strong style=\"color:#e94560;\">\n</div>\n\n4. FOOTER:\n<div style=\"background:#f8f8f8;padding:16px;text-align:center;margin-top:20px;\">\n  <p style=\"color:#888;font-size:11px;margin:0;\">Powered by CoreNexis OCR API | api.corenexis.com</p>\n</div>\n\nMax width: 600px centered with margin:0 auto\nFont: Arial, Helvetica, sans-serif throughout\nMust render correctly in Gmail"
        },
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "cd8e9f42-0f0d-414c-a78c-5dd08eedd4d2",
      "name": "OpenAI \u2014 GPT-4o-mini Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        2208,
        208
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "7de364f0-d2c5-4ef6-ac65-0e17c2aa1823",
      "name": "16. Code \u2014 Extract HTML",
      "type": "n8n-nodes-base.code",
      "position": [
        2560,
        -64
      ],
      "parameters": {
        "jsCode": "const agentOutput = $input.first().json;\nconst prev = $('14. Code \u2014 Extract Summary').first().json;\n\nlet html = agentOutput.output || agentOutput.text || '';\n\nhtml = html\n  .replace(/^```html\\s*/im, '')\n  .replace(/^```\\s*/im, '')\n  .replace(/\\s*```\\s*$/im, '')\n  .trim();\n\nif (!html.startsWith('<!DOCTYPE') && !html.startsWith('<html')) {\n  const safe = (prev.summary_md || '')\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;');\n  html = `<!DOCTYPE html>\n<html>\n<body style=\"font-family:Arial,sans-serif;max-width:600px;margin:0 auto;background:#f4f4f4;padding:20px;\">\n  <div style=\"background:#1a1a2e;padding:28px;text-align:center;\">\n    <p style=\"color:#e94560;font-size:11px;margin:0 0 8px;letter-spacing:2px;\">CORENEXIS OCR</p>\n    <h1 style=\"color:white;margin:0;font-size:22px;\">Document Summary Report</h1>\n  </div>\n  <div style=\"background:#e94560;padding:10px 28px;\">\n    <p style=\"color:white;font-size:12px;margin:0;\">For: ${prev.name} | ${prev.started_at} | ${prev.pages_done} page(s)</p>\n  </div>\n  <div style=\"background:white;padding:28px;\">\n    <pre style=\"white-space:pre-wrap;font-family:Arial;font-size:14px;line-height:1.8;color:#333;\">${safe}</pre>\n  </div>\n  <div style=\"background:#f8f8f8;padding:16px;text-align:center;margin-top:20px;\">\n    <p style=\"color:#888;font-size:11px;margin:0;\">Powered by CoreNexis OCR API | api.corenexis.com</p>\n  </div>\n</body>\n</html>`;\n}\n\nreturn [{\n  json: {\n    email: prev.email,\n    file_name: prev.file_name,\n    name: prev.name,\n    html_body: html\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "7bd51279-bec3-4ef6-9ae9-dec74fe29252",
      "name": "17. Gmail \u2014 Send Summary Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2784,
        -64
      ],
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "message": "={{ $json.html_body }}",
        "options": {},
        "subject": "=Document Summary Ready \u2014 {{ $json.file_name }} | CoreNexis"
      },
      "typeVersion": 2.1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "executionOrder": "v1"
  },
  "versionId": "22d3f5e3-8f67-4661-8662-fc7efb7c3c69",
  "connections": {
    "5. Wait \u2014 4 Seconds": {
      "main": [
        [
          {
            "node": "6. HTTP \u2014 Poll OCR Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1. Form \u2014 PDF Upload": {
      "main": [
        [
          {
            "node": "2. Code \u2014 Prepare PDF Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4. Code \u2014 Get Job ID": {
      "main": [
        [
          {
            "node": "5. Wait \u2014 4 Seconds",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7. Code \u2014 Merge Status": {
      "main": [
        [
          {
            "node": "8. IF \u2014 Still Processing?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "10. IF \u2014 OCR Completed?": {
      "main": [
        [
          {
            "node": "11. HTTP \u2014 Download Extracted Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "16. Code \u2014 Extract HTML": {
      "main": [
        [
          {
            "node": "17. Gmail \u2014 Send Summary Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9. Wait \u2014 1 Minute Retry": {
      "main": [
        [
          {
            "node": "6. HTTP \u2014 Poll OCR Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6. HTTP \u2014 Poll OCR Status": {
      "main": [
        [
          {
            "node": "7. Code \u2014 Merge Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8. IF \u2014 Still Processing?": {
      "main": [
        [
          {
            "node": "9. Wait \u2014 1 Minute Retry",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "10. IF \u2014 OCR Completed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "14. Code \u2014 Extract Summary": {
      "main": [
        [
          {
            "node": "15. AI Agent \u2014 Generate HTML Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2. Code \u2014 Prepare PDF Data": {
      "main": [
        [
          {
            "node": "3. HTTP \u2014 CoreNexis OCR Submit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI \u2014 GPT-4o-mini Model": {
      "ai_languageModel": [
        [
          {
            "node": "15. AI Agent \u2014 Generate HTML Email",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI \u2014 GPT-4.1-mini Model": {
      "ai_languageModel": [
        [
          {
            "node": "13. AI Agent \u2014 Generate Document Summary",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "12. Code \u2014 Prep Text for Agent": {
      "main": [
        [
          {
            "node": "13. AI Agent \u2014 Generate Document Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3. HTTP \u2014 CoreNexis OCR Submit": {
      "main": [
        [
          {
            "node": "4. Code \u2014 Get Job ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "11. HTTP \u2014 Download Extracted Text": {
      "main": [
        [
          {
            "node": "12. Code \u2014 Prep Text for Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "15. AI Agent \u2014 Generate HTML Email": {
      "main": [
        [
          {
            "node": "16. Code \u2014 Extract HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "13. AI Agent \u2014 Generate Document Summary": {
      "main": [
        [
          {
            "node": "14. Code \u2014 Extract Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Upload any PDF through a form and this workflow extracts the full text using CoreNexis OCR, generates a structured 5-section summary with GPT-4.1-mini, converts it into a branded HTML email with GPT-4o-mini, and delivers it to your inbox automatically. User fills a form with…

Source: https://n8n.io/workflows/15956/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

22-Automate_Multi_Platform_Social_Media_Content_Creation. Uses outputParserStructured, lmChatGoogleGemini, lmChatOpenAi, httpRequest. Event-driven trigger; 57 nodes.

Output Parser Structured, Google Gemini Chat, OpenAI Chat +11
AI & RAG

This workflow automates end-to-end contract and invoice management using AI intelligence. It processes proposals through intelligent contract generation, approval workflows, and automated invoicing. O

Form Trigger, Data Table, Agent +4
AI & RAG

Automates SaaS operations by consolidating user management, AI-driven support triage, analytics, and billing into one unified system. User signups flow through registration, support requests route via

Form Trigger, Data Table, Agent +7
AI & RAG

The workflow runs every hour with a randomized delay of 5–20 minutes to help distribute load. It records the exact date and time a lead is emailed so you can track outreach. Follow-ups are automatical

Google Sheets, Agent, OpenAI Chat +5
AI & RAG

This n8n workflow automates turning short user ideas into production-ready real-estate marketing assets (photorealistic images and optional 360° videos). A form submission seeds a prompt board → an LL

Form Trigger, Google Sheets, Agent +6