This workflow corresponds to n8n.io template #7861 — we link there as the canonical source.
This workflow follows the Agent → Google Sheets 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "ab1b7d2d-7eac-45eb-9e0a-36f14c56df14",
"name": "When clicking \u2018Execute workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
1728,
288
],
"parameters": {},
"typeVersion": 1
},
{
"id": "2015e3a3-026b-46af-adfc-1fcff0031e66",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
2720,
608
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.2
},
{
"id": "3bce7fdc-3fe1-451f-9e3f-ed37563a8fb5",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
3072,
576
],
"parameters": {
"jsonSchemaExample": "{\n\t\"summary\": \"summary\"\n}"
},
"typeVersion": 1.3
},
{
"id": "93cb6107-c70b-4a48-95e4-1ddda24d87e1",
"name": "Sticky Note53",
"type": "n8n-nodes-base.stickyNote",
"position": [
1632,
-272
],
"parameters": {
"color": 7,
"width": 2144,
"height": 1056,
"content": "# \ud83d\udcca Marketing Spend Report \u2192 Google Sheets + PDF\n\nThis workflow pulls **marketing data from Google Sheets**, aggregates spend by channel, generates an **AI-written summary**, and outputs a formatted **PDF report** using a custom HTML template on **PDF.co**. \n\n"
},
"typeVersion": 1
},
{
"id": "00aba054-1dab-429e-beb4-2c18e21c7e3a",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
-272
],
"parameters": {
"width": 400,
"height": 1056,
"content": "\n## \u2699\ufe0f Setup Instructions\n\n### 1\ufe0f\u20e3 Prepare Your Google Sheet \n- Copy this template into your Google Drive: [Sample Marketing Data](https://docs.google.com/spreadsheets/d/1UDWt0-Z9fHqwnSNfU3vvhSoYCFG6EG3E-ZewJC_CLq4/edit?gid=365710158#gid=365710158) \n- Add or update your marketing spend data in rows 2\u2013100. \n\n#### Connect Google Sheets in n8n \n1. Go to **n8n \u2192 Credentials \u2192 New \u2192 Google Sheets (OAuth2)** \n2. Log in with your Google account and grant access \n3. Select the **Spreadsheet ID** and **Worksheet** in the workflow \n\n---\n\n### 2\ufe0f\u20e3 Set Up PDF.co for PDF Reports \n1. Create a free account at [PDF.co](https://pdf.co/) \n2. In **PDF.co Dashboard \u2192 HTML to PDF Templates**, create a new **Mustache template** \n - Paste the HTML provided at the bottom of this description \n - Save, and note your **Template ID** \n3. In **n8n \u2192 Credentials \u2192 New \u2192 PDF.co API**, paste your **API Key** and save \n4. In the workflow, select your **PDF.co credential** in the `Create PDF` node \n5. Replace the `templateId` with your Template ID \n\n\n\n## \ud83d\udcec Contact \nNeed help customizing this (e.g., filtering by campaign, sending reports by email, or formatting your PDF)? \n\n- \ud83d\udce7 **robert@ynteractive.com** \n- \ud83d\udd17 **[Robert Breen](https://www.linkedin.com/in/robert-breen-29429625/)** \n- \ud83c\udf10 **[ynteractive.com](https://ynteractive.com)** \n\n\n"
},
"typeVersion": 1
},
{
"id": "2d0dba31-964f-4b8c-94e4-215b5448f2b4",
"name": "Get Marketing Data",
"type": "n8n-nodes-base.googleSheets",
"position": [
1952,
464
],
"parameters": {
"options": {},
"sheetName": {
"__rl": true,
"mode": "list",
"value": 365710158,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1UDWt0-Z9fHqwnSNfU3vvhSoYCFG6EG3E-ZewJC_CLq4/edit#gid=365710158",
"cachedResultName": "Data"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1UDWt0-Z9fHqwnSNfU3vvhSoYCFG6EG3E-ZewJC_CLq4",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1UDWt0-Z9fHqwnSNfU3vvhSoYCFG6EG3E-ZewJC_CLq4/edit?usp=drivesdk",
"cachedResultName": "Sample Marketing Data - n8n"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "385bdda8-e751-4c71-8ddc-ff1b93eb5698",
"name": "Sum Spend by Channel",
"type": "n8n-nodes-base.summarize",
"position": [
2256,
288
],
"parameters": {
"options": {},
"fieldsToSplitBy": "Channel",
"fieldsToSummarize": {
"values": [
{
"field": "Spend ($)",
"aggregation": "sum"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "433d72c6-032c-43b9-9c34-36191d3181b5",
"name": "Sum Spend",
"type": "n8n-nodes-base.summarize",
"position": [
2256,
128
],
"parameters": {
"options": {},
"fieldsToSummarize": {
"values": [
{
"field": "Spend ($)",
"aggregation": "sum"
}
]
}
},
"typeVersion": 1.1
},
{
"id": "dbcd16cf-f023-467b-bc92-d70c9110cf1b",
"name": "Write Summary",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
2832,
304
],
"parameters": {
"text": "={{ $json.data }}",
"options": {
"systemMessage": "You are writing a daily update message about the marketing data. The data is provided. Output a 4 sentance summary. \n\nOutput like this. \n\n{\n\t\"summary\": \"summary\"\n}"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 2.2
},
{
"id": "4d2c9c31-7fc8-4a4b-a6ca-3b36777ff96b",
"name": "Combine All",
"type": "n8n-nodes-base.merge",
"position": [
3136,
48
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition",
"numberInputs": 3
},
"typeVersion": 3.2
},
{
"id": "d6a77a5d-c9c4-4496-8a8e-520425b54400",
"name": "Convert to PDF Upload",
"type": "n8n-nodes-base.code",
"position": [
3504,
-160
],
"parameters": {
"jsCode": "// n8n Code node (JavaScript)\n// Input: ONE item whose .json is the array you posted\n// Output: ONE item in correct n8n shape: [{ json: <object for HTML/Mustache> }]\n\nconst fmtUSD = (n) => Number(n || 0).toLocaleString('en-US', { style: 'currency', currency: 'USD' });\n\nconst items = $input.all();\nif (!items.length) {\n return [{ json: { error: 'No input data' } }];\n}\n\n// Handle your exact incoming shape (array with one object)\nlet root = items[0].json;\nif (Array.isArray(root)) root = root[0] || {};\n\nconst totalSpendRaw = Number(root[\"sum_Spend_($)\"] || 0);\nconst channelsRaw = Array.isArray(root.data) ? root.data : [];\nconst summary = (typeof root.output?.summary === 'string') ? root.output.summary : '';\n\n// Build channels list for the HTML template\nconst channels = channelsRaw.map(r => ({\n channel: r.Channel || 'Unknown',\n spendFmt: fmtUSD(Number(r[\"sum_Spend_($)\"] || 0)),\n}));\n\n// Final object expected by your HTML/Mustache\nconst out = {\n generatedDate: new Date().toISOString().slice(0, 10),\n totalSpendFmt: fmtUSD(totalSpendRaw),\n channelCount: channels.length,\n channels,\n summary,\n};\n\n// \u2705 Return in proper n8n format\nreturn [{ json: out }];\n"
},
"typeVersion": 2
},
{
"id": "5d147144-87a1-4e6c-a03c-4366896deffe",
"name": "Create PDF",
"type": "n8n-nodes-pdfco.PDFco Api",
"position": [
3552,
560
],
"parameters": {
"operation": "URL/HTML to PDF",
"templateId": "12011",
"convertType": "htmlTemplateToPDF",
"templateData": "={{ JSON.stringify($json) }}\n",
"advancedOptions": {}
},
"credentials": {
"pdfcoApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "0a330ed9-9b83-4915-a867-432752e0a6fc",
"name": "Covert to 1 row",
"type": "n8n-nodes-base.aggregate",
"position": [
2496,
224
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "a3ecc29f-ef2f-4325-b477-b4a536dc86d6",
"name": "Sticky Note59",
"type": "n8n-nodes-base.stickyNote",
"position": [
3440,
64
],
"parameters": {
"color": 3,
"width": 288,
"height": 624,
"content": "### 2\ufe0f\u20e3 Connect PDF.co\n1. Create a free account at [PDF.co](https://pdf.co/) \n2. Copy your **API Key** from the dashboard \n3. In **n8n \u2192 Credentials \u2192 New \u2192 PDF.co API** \n - Paste your API Key \u2192 **Save** \n4. In the **PDF.co node**, select your credential and choose the **HTML Template to PDF** operation \n\n---\n\n### 3\ufe0f\u20e3 Create Your PDF.co HTML Template\n1. In your [PDF.co dashboard](https://app.pdf.co/), go to **Templates \u2192 New Template** \n2. Paste in the HTML from the template section below \n3. Save the template and copy its **Template ID** \n4. Replace the `templateId` in the workflow with your new ID \n\n---\n"
},
"typeVersion": 1
},
{
"id": "2fe228de-8f55-4f3f-8856-a2d0216c3dd3",
"name": "Sticky Note60",
"type": "n8n-nodes-base.stickyNote",
"position": [
1888,
32
],
"parameters": {
"color": 3,
"width": 224,
"height": 576,
"content": "### 1\ufe0f\u20e3 Prepare Your Google Sheet \n- Copy this template into your Google Drive: [Sample Marketing Data](https://docs.google.com/spreadsheets/d/1UDWt0-Z9fHqwnSNfU3vvhSoYCFG6EG3E-ZewJC_CLq4/edit?gid=365710158#gid=365710158) \n- Add or update your marketing spend data in rows 2\u2013100. \n\n#### Connect Google Sheets in n8n \n1. Go to **n8n \u2192 Credentials \u2192 New \u2192 Google Sheets (OAuth2)** \n2. Log in with your Google account and grant access \n3. Select the **Spreadsheet ID** and **Worksheet** in the workflow \n"
},
"typeVersion": 1
}
],
"connections": {
"Sum Spend": {
"main": [
[
{
"node": "Combine All",
"type": "main",
"index": 0
}
]
]
},
"Combine All": {
"main": [
[
{
"node": "Convert to PDF Upload",
"type": "main",
"index": 0
}
]
]
},
"Write Summary": {
"main": [
[
{
"node": "Combine All",
"type": "main",
"index": 2
}
]
]
},
"Covert to 1 row": {
"main": [
[
{
"node": "Combine All",
"type": "main",
"index": 1
},
{
"node": "Write Summary",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Write Summary",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Get Marketing Data": {
"main": [
[
{
"node": "Sum Spend",
"type": "main",
"index": 0
},
{
"node": "Sum Spend by Channel",
"type": "main",
"index": 0
}
]
]
},
"Sum Spend by Channel": {
"main": [
[
{
"node": "Covert to 1 row",
"type": "main",
"index": 0
}
]
]
},
"Convert to PDF Upload": {
"main": [
[
{
"node": "Create PDF",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Write Summary",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Get Marketing Data",
"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.
googleSheetsOAuth2ApiopenAiApipdfcoApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow pulls marketing data from Google Sheets, aggregates spend by channel, generates an AI-written summary, and outputs a formatted PDF report using a custom HTML template on PDF.co. Copy this template into your Google Drive: Sample Marketing Data Add or update your…
Source: https://n8n.io/workflows/7861/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.
Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.
This template is designed for marketers, content creators, and e-commerce brands who want to automate the creation of professional ad videos at scale. It’s ideal for teams looking to generate consiste
This comprehensive n8n workflow automates the entire Meta (Facebook/Instagram) advertising process, from asset analysis to ad creation. It combines AI-powered content analysis with automated ad deploy
This automation is designed to help you generate AI-powered music tracks, cover art, and fully rendered music videos — all triggered from a simple Telegram chat and managed via Google Sheets.