AutomationFlowsAI & RAG › Daily Gmail Inbox Digest to Discord with Gpt-4.1-mini and PDF Conversion

Daily Gmail Inbox Digest to Discord with Gpt-4.1-mini and PDF Conversion

Bymoosa @moosa on n8n.io

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Cron / scheduled trigger★★★★☆ complexityAI-powered18 nodesDiscordOpenAI ChatHTTP RequestChain SummarizationN8N Nodes PdfcoGmail
AI & RAG Trigger: Cron / scheduled Nodes: 18 Complexity: ★★★★☆ AI nodes: yes Added:

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

This workflow follows the Chainsummarization → HTTP Request 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "3b5b2708-da04-420a-aa33-498cd726ab8d",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        0,
        -224
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 20
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "602ac44e-3936-4cfe-81fc-0c89aa180904",
      "name": "Discord",
      "type": "n8n-nodes-base.discord",
      "position": [
        2272,
        -224
      ],
      "parameters": {
        "files": {
          "values": [
            {}
          ]
        },
        "content": "= {{ $('separate text and markdown').item.json.plainText }}",
        "options": {},
        "authentication": "webhook"
      },
      "credentials": {
        "discordWebhookApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "cab9950b-4b4f-418b-ae4c-bd29a4966bb5",
      "name": "OpenAI Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        880,
        -64
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "85dde31c-3895-4ece-bb8c-ee5f21f55c89",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1920,
        -224
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "a49d8c5b-f638-4309-add4-7524c347e9cb",
      "name": "Summarization Chain",
      "type": "@n8n/n8n-nodes-langchain.chainSummarization",
      "position": [
        896,
        -224
      ],
      "parameters": {
        "options": {
          "summarizationMethodAndPrompts": {
            "values": {
              "prompt": "You will receive a collection of emails.\n\nSummarize them in **two formats**:\n\n1. **Plain Text Digest**  \n   - Use clear sentences.  \n   - Separate different senders with line breaks.  \n   - Keep it compact but readable.  \n   - Mention only the most important details (credentials, OTPs, deadlines, required actions).  \n   - Mark urgent items with [Action Required].  \n\n2. **Markdown Digest**  \n   - Use headings for senders.  \n   - Bullets for details.  \n   - Highlight actions with **[Action Required]**.  \n\nHere are the emails:\n\n\"{text}\"\n\nNow output:\n\nPLAIN TEXT:\n...\n\nMARKDOWN:\n...\n",
              "summarizationMethod": "stuff"
            }
          }
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "7f9ab61d-ffd9-477e-8886-2472e5d4a1ab",
      "name": "PDFco Api",
      "type": "n8n-nodes-pdfco.PDFco Api",
      "position": [
        1696,
        -224
      ],
      "parameters": {
        "html": "={{ $json.data }}",
        "operation": "URL/HTML to PDF",
        "convertType": "htmlToPDF",
        "advancedOptions": {}
      },
      "credentials": {
        "pdfcoApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "156e95b9-c5c7-477d-b1a4-0c3545a56669",
      "name": "Markdown",
      "type": "n8n-nodes-base.markdown",
      "position": [
        1472,
        -224
      ],
      "parameters": {
        "mode": "markdownToHtml",
        "options": {},
        "markdown": "=\n{{ $json.markdown }}"
      },
      "typeVersion": 1
    },
    {
      "id": "190586e3-685c-4c95-87f1-882dba9e54ca",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        672,
        -224
      ],
      "parameters": {
        "include": "specifiedFields",
        "options": {},
        "aggregate": "aggregateAllItemData",
        "fieldsToInclude": "subject, from, plainText"
      },
      "typeVersion": 1
    },
    {
      "id": "9c7247ee-9811-4ad4-bb4a-bbc53a23ab38",
      "name": "extract required sections from mails",
      "type": "n8n-nodes-base.code",
      "position": [
        448,
        -224
      ],
      "parameters": {
        "jsCode": "// n8n Code node (JavaScript)\n\n// Helper: decode Gmail's base64url\nfunction decodeBase64Url(str) {\n  if (!str) return \"\";\n  str = str.replace(/-/g, '+').replace(/_/g, '/');\n  return Buffer.from(str, 'base64').toString('utf8');\n}\n\n// Helper: clean text\nfunction cleanText(txt) {\n  if (!txt) return \"\";\n\n  return txt\n    // remove long URLs\n    .replace(/https?:\\/\\/\\S+/g, \"\")\n    // remove multiple stars/dashes\n    .replace(/[*]{3,}|[-]{3,}/g, \"\")\n    // remove extra blank lines\n    .replace(/\\n\\s*\\n\\s*\\n+/g, \"\\n\\n\")\n    // trim\n    .trim();\n}\n\nconst items = $input.all();\nconst returnData = [];\n\nfor (let i = 0; i < items.length; i++) {\n  const email = items[i].json;\n  let plainText = \"\";\n\n  // Case 1: direct body\n  if (email?.payload?.body?.data) {\n    plainText = decodeBase64Url(email.payload.body.data);\n  }\n\n  // Case 2: multipart body\n  if (!plainText && Array.isArray(email?.payload?.parts)) {\n    for (const part of email.payload.parts) {\n      if (part.mimeType === \"text/plain\" && part.body?.data) {\n        plainText = decodeBase64Url(part.body.data);\n        break;\n      }\n    }\n  }\n\n  // Fallback if you already had email.text\n  if (!plainText && email.text) {\n    plainText = email.text;\n  }\n\n  const extractedData = {\n    id: email.id || \"\",\n    subject: email.subject || email.payload?.headers?.find(h => h.name === \"Subject\")?.value || \"\",\n    from: email.from?.text || email.from || email.payload?.headers?.find(h => h.name === \"From\")?.value || \"\",\n    to: email.to?.text || email.to || email.payload?.headers?.find(h => h.name === \"To\")?.value || \"\",\n    plainText: cleanText(plainText),\n  };\n\n  returnData.push({ json: extractedData });\n}\n\nreturn returnData;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "157ef58a-86fa-41fc-96d4-b058684d513f",
      "name": "get mails from past 24 h",
      "type": "n8n-nodes-base.gmail",
      "position": [
        224,
        -224
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "labelIds": [
            "INBOX",
            "IMPORTANT"
          ],
          "receivedAfter": "={{$now.minus({days: 1}).toISO()}}"
        },
        "options": {},
        "operation": "getAll",
        "returnAll": true
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "0df5a671-79aa-4c7d-bbd7-296a214b4c9c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -368
      ],
      "parameters": {
        "width": 400,
        "height": 320,
        "content": "## extract fields and aggregate\n- sender\n- subject\n- body"
      },
      "typeVersion": 1
    },
    {
      "id": "5a0a95ad-14a7-484a-94c2-ef6a582151fa",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        176,
        -304
      ],
      "parameters": {
        "width": 208,
        "height": 208,
        "content": "## get mails\n- Important and inbox"
      },
      "typeVersion": 1
    },
    {
      "id": "2335cdb8-b1e1-4d7c-98f7-e84dfec2e4c0",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        -320
      ],
      "parameters": {
        "width": 192,
        "height": 256,
        "content": "## daily trigger"
      },
      "typeVersion": 1
    },
    {
      "id": "b82da96e-aa95-45fd-b13e-51f998143f6c",
      "name": "separate text and markdown",
      "type": "n8n-nodes-base.code",
      "position": [
        1248,
        -224
      ],
      "parameters": {
        "jsCode": "const output = $json[\"output\"][\"text\"];\n\n// Match plain text - works for both \"PLAIN TEXT\" and \"PLAIN TEXT DIGEST\"\nconst plainText = output.match(/PLAIN TEXT(?: DIGEST)?:\\s*([\\s\\S]*?)(?:\\n\\n---\\n\\nMARKDOWN DIGEST:|\\n\\nMARKDOWN:)/)?.[1]?.trim();\n\n// Match markdown - works for both \"MARKDOWN\" and \"MARKDOWN DIGEST\"\nconst markdown = output.match(/MARKDOWN(?: DIGEST)?:\\s*([\\s\\S]*)/)?.[1]?.trim();\n\nreturn [{\n  plainText,\n  markdown\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "44150497-0310-40d3-bb8d-8bd7624ab4c1",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        -384
      ],
      "parameters": {
        "width": 320,
        "height": 480,
        "content": "## summarize all mails\n- ### model used gpt 4o-mini"
      },
      "typeVersion": 1
    },
    {
      "id": "e77850b7-6d9c-44da-8c36-33ab2cac645f",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1392,
        -304
      ],
      "parameters": {
        "width": 432,
        "height": 240,
        "content": "## convert markdown to html and convert html to pdf using PDFco Api"
      },
      "typeVersion": 1
    },
    {
      "id": "24c297f1-9195-43e2-b27d-208aaad5b518",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1856,
        -400
      ],
      "parameters": {
        "height": 336,
        "content": "## Download PDF\n- ### using link generated from pdfco"
      },
      "typeVersion": 1
    },
    {
      "id": "31e1f02c-4b0a-49c6-ad17-3d8bef1fc35c",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2192,
        -352
      ],
      "parameters": {
        "width": 336,
        "height": 304,
        "content": "## Send discord\n- using webhook\n- result will contain summary and a pdf of summary"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Markdown": {
      "main": [
        [
          {
            "node": "PDFco Api",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Summarization Chain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PDFco Api": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Discord",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "get mails from past 24 h",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Summarization Chain",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Summarization Chain": {
      "main": [
        [
          {
            "node": "separate text and markdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "get mails from past 24 h": {
      "main": [
        [
          {
            "node": "extract required sections from mails",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "separate text and markdown": {
      "main": [
        [
          {
            "node": "Markdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "extract required sections from mails": {
      "main": [
        [
          {
            "node": "Aggregate",
            "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

This workflow contains community nodes that are only compatible with the self-hosted version of n8n.

Source: https://n8n.io/workflows/8358/ — 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

This workflow is ideal for HR professionals, recruiters, and small businesses looking to streamline resume screening with AI-powered analysis and CRM integration.

Jot Form Trigger, Postgres, OpenAI +5
AI & RAG

Deduplicate Scraping Ai Grants For Eligibility Using Ai. Uses splitOut, httpRequest, lmChatOpenAi, informationExtractor. Scheduled trigger; 24 nodes.

HTTP Request, OpenAI Chat, Information Extractor +2
AI & RAG

This n8n template scrapes a list of AI grants from grants.gov and qualifies them using AI; determining interest and eligibility for the business. It then sends an email alert of interesting items to t

HTTP Request, OpenAI Chat, Information Extractor +2
AI & RAG

Sign up for Decodo — get better pricing here

@Decodo/N8N Nodes Decodo, Information Extractor, OpenAI Chat +4
AI & RAG

gmail label and notify. Uses lmChatOpenAi, textClassifier, gmail, openAi. Scheduled trigger; 16 nodes.

OpenAI Chat, Text Classifier, Gmail +2