This workflow corresponds to n8n.io template #14081 — we link there as the canonical source.
This workflow follows the Gmail → Google Drive 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 →
{
"id": "2ihlAZ1ciTaRcK4D",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Bulk certificate generator with Google Slides",
"tags": [],
"nodes": [
{
"id": "7e27628a-143d-4695-a7d5-99c16cf41706",
"name": "When clicking 'Test workflow'",
"type": "n8n-nodes-base.manualTrigger",
"position": [
496,
272
],
"parameters": {},
"typeVersion": 1
},
{
"id": "d31e2c79-a934-4e43-a867-8698907d28c5",
"name": "Process One at a Time",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1024,
272
],
"parameters": {
"options": {
"reset": false
}
},
"typeVersion": 3
},
{
"id": "2f920ad0-869f-425f-93cc-ef74b7e4323d",
"name": "Copy Slides Template",
"type": "n8n-nodes-base.httpRequest",
"position": [
1280,
288
],
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files/xxx/copy",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify({ name: 'Certificate_' + $json['N.'] }) }}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleDriveOAuth2Api"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "60648c15-95db-48b4-9eee-3b1666285bfc",
"name": "Replace Template Placeholders",
"type": "n8n-nodes-base.httpRequest",
"position": [
1488,
288
],
"parameters": {
"url": "=https://slides.googleapis.com/v1/presentations/{{ $json.id }}:batchUpdate",
"method": "POST",
"options": {},
"jsonBody": "={\n \"requests\": [\n {\n \"replaceAllText\": {\n \"containsText\": { \"text\": \"[Name]\", \"matchCase\": false },\n \"replaceText\": \"{{ $('Process One at a Time').item.json['First Name'] }} {{ $('Process One at a Time').item.json['Last Name'] }}\"\n }\n },\n {\n \"replaceAllText\": {\n \"containsText\": { \"text\": \"[Date]\", \"matchCase\": false },\n \"replaceText\": \"{{ $now.format('dd/LL/yyyy') }}\"\n }\n },\n {\n \"replaceAllText\": {\n \"containsText\": { \"text\": \"[N]\", \"matchCase\": false },\n \"replaceText\": \"#{{ $('Process One at a Time').item.json['N.'] }}\"\n }\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleSlidesOAuth2Api"
},
"credentials": {
"googleSlidesOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "4f13e912-7e8f-4e4f-9295-9535bcd9ed40",
"name": "Export to PDF",
"type": "n8n-nodes-base.httpRequest",
"position": [
1712,
288
],
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files/{{ $('Copy Slides Template').item.json.id }}/export?mimeType=application/pdf",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleSlidesOAuth2Api"
},
"credentials": {
"googleSlidesOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "616681e9-bf9d-4713-913f-b84ddeee1d1f",
"name": "Save PDF to Drive",
"type": "n8n-nodes-base.googleDrive",
"position": [
1280,
960
],
"parameters": {
"name": "=certificate_{{ $('Process One at a Time').item.json['N.'] }}.pdf",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive",
"cachedResultUrl": "https://drive.google.com/drive/my-drive",
"cachedResultName": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "1tkCr7xdraoZwsHqeLm7FZ4aRWY94oLbZ",
"cachedResultUrl": "https://drive.google.com/drive/folders/1tkCr7xdraoZwsHqeLm7FZ4aRWY94oLbZ",
"cachedResultName": "n8n"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3,
"alwaysOutputData": true
},
{
"id": "57962326-14e2-49bb-b46e-40ada76f8d99",
"name": "Mark as Processed",
"type": "n8n-nodes-base.googleSheets",
"position": [
1520,
960
],
"parameters": {
"columns": {
"value": {
"Sent": "x",
"row_number": "={{ $('Process One at a Time').item.json.row_number }}"
},
"schema": [
{
"id": "N.",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "N.",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "First Name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "First Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Last Name",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Last Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Email",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Email",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Sent",
"type": "string",
"display": true,
"removed": false,
"required": false,
"displayName": "Sent",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "row_number",
"type": "number",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "row_number",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"row_number"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update",
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1fHcfilCPpI4aAiJFQC3cPIAdJMmctMubz3kcOeai1yA/edit#gid=0",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1fHcfilCPpI4aAiJFQC3cPIAdJMmctMubz3kcOeai1yA",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1fHcfilCPpI4aAiJFQC3cPIAdJMmctMubz3kcOeai1yA/edit?usp=drivesdk",
"cachedResultName": "Certifications"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "c3db4aa9-ff10-4054-81bb-232bb7c874cd",
"name": "Send a message",
"type": "n8n-nodes-base.gmail",
"position": [
1280,
608
],
"parameters": {
"sendTo": "={{$('Process One at a Time').item.json['Email']}}",
"message": "=\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f4f4f4; padding: 40px 0;\">\n <tr>\n <td align=\"center\">\n <table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#ffffff; border-radius:8px; overflow:hidden;\">\n\n <!-- Header -->\n <tr>\n <td style=\"background-color:#ff6d5a; padding: 32px 40px; text-align:center;\">\n <h1 style=\"margin:0; color:#ffffff; font-size:24px; font-weight:bold;\">\ud83c\udf89 Congratulations!</h1>\n </td>\n </tr>\n\n <!-- Body -->\n <tr>\n <td style=\"padding: 40px 40px 24px 40px; color:#333333; font-size:15px; line-height:1.7;\">\n <p style=\"margin:0 0 16px 0;\">Dear <strong>{{$('Process One at a Time').item.json['First Name']}} {{$('Process One at a Time').item.json['Last Name']}}</strong>,</p>\n <p style=\"margin:0 0 16px 0;\">Congratulations on successfully completing the <strong>n8n course</strong>!</p>\n <p style=\"margin:0 0 16px 0;\">It has been a pleasure having you on this learning journey. Your commitment and dedication throughout the course have been truly commendable, and we hope the knowledge and skills you gained will make a real difference in your day-to-day work.</p>\n <p style=\"margin:0 0 16px 0;\">Please find attached your <strong>official certificate of completion</strong>. We encourage you to share it proudly \u2014 you've earned it.</p>\n <p style=\"margin:0 0 16px 0;\">Thank you for being part of this program, and we wish you all the best in your automation journey.</p>\n </td>\n </tr>\n\n <!-- CTA -->\n <tr>\n <td style=\"padding: 0 40px 40px 40px; text-align:center;\">\n <p style=\"margin:0 0 24px 0; color:#333333; font-size:15px;\">Share your achievement on LinkedIn and let the world know!</p>\n <a href=\"https://www.linkedin.com\" style=\"background-color:#ff6d5a; color:#ffffff; text-decoration:none; padding:14px 32px; border-radius:6px; font-size:15px; font-weight:bold; display:inline-block;\">Share on LinkedIn</a>\n </td>\n </tr>\n\n <!-- Footer -->\n <tr>\n <td style=\"background-color:#f4f4f4; padding: 24px 40px; text-align:center; border-top:1px solid #e0e0e0;\">\n <p style=\"margin:0; color:#999999; font-size:12px;\">This email was sent by n3w Italia \u00b7 <a href=\"https://n3w.it\" style=\"color:#ff6d5a; text-decoration:none;\">n3w.it</a></p>\n </td>\n </tr>\n\n </table>\n </td>\n </tr>\n </table>\n",
"options": {
"attachmentsUi": {
"attachmentsBinary": [
{}
]
}
},
"subject": "Your n8n Certificate"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "14b280e9-b95d-4fba-8990-be9881a950fd",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
1984,
944
],
"parameters": {},
"typeVersion": 3.2
},
{
"id": "08598641-28bd-4baa-8c6b-021e5c1485e7",
"name": "Wait 10s",
"type": "n8n-nodes-base.wait",
"position": [
2240,
944
],
"parameters": {
"amount": 10
},
"typeVersion": 1.1
},
{
"id": "57f6a4e7-b234-4514-8608-4beec902ce5b",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
144
],
"parameters": {
"color": 7,
"width": 656,
"height": 304,
"content": "## STEP 2 - Template\nReplace xxx with the Google Slides base template file id [like this](https://docs.google.com/presentation/d/1YWYsNfq4FeHP03MSYFz1cobVczBHWxwEW95BE4w0FHc/edit?slide=id.p#slide=id.p).\nAfter personalization, the workflow automatically converts the generated Google Slides document into a **PDF file**"
},
"typeVersion": 1
},
{
"id": "b8e5e740-7d8c-4293-b39d-d119c6aad242",
"name": "Delete Temp Slide",
"type": "n8n-nodes-base.httpRequest",
"position": [
1744,
960
],
"parameters": {
"url": "=https://www.googleapis.com/drive/v3/files/{{ $('Copy Slides Template').item.json.id }}",
"method": "DELETE",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "googleSlidesOAuth2Api"
},
"credentials": {
"googleSlidesOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "43d185ba-e4ea-4abe-b86d-b9d1045e4830",
"name": "Read File",
"type": "n8n-nodes-base.googleSheets",
"position": [
752,
272
],
"parameters": {
"options": {},
"filtersUI": {
"values": [
{
"lookupColumn": "Sent"
}
]
},
"sheetName": {
"__rl": true,
"mode": "list",
"value": "gid=0",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1fHcfilCPpI4aAiJFQC3cPIAdJMmctMubz3kcOeai1yA/edit#gid=0",
"cachedResultName": "Foglio1"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1fHcfilCPpI4aAiJFQC3cPIAdJMmctMubz3kcOeai1yA",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1fHcfilCPpI4aAiJFQC3cPIAdJMmctMubz3kcOeai1yA/edit?usp=drivesdk",
"cachedResultName": "Certifications"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "336bcffe-1625-4882-8838-14ccbab5ce9e",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
672,
144
],
"parameters": {
"color": 7,
"width": 528,
"height": 304,
"content": "## STEP 1 - DB\nClone [this Sheet](https://docs.google.com/spreadsheets/d/1fHcfilCPpI4aAiJFQC3cPIAdJMmctMubz3kcOeai1yA/edit?usp=sharing). The workflow can generate and send personalized certificates for many recipients in bulk, making it ideal for courses, events, webinars, or training programs."
},
"typeVersion": 1
},
{
"id": "dc1f88c2-1c9e-408a-920f-c291b51e2858",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1200,
-384
],
"parameters": {
"width": 672,
"height": 480,
"content": "## Bulk certificate generator with Google Slides\n\n\n### How it works\n\nThis workflow bulk-generates personalized certificates by reading recipient data from Google Sheets and processing only rows that have not been marked as sent. For each recipient, it creates a copy of a Google Slides certificate template, replaces placeholders such as name, date, and certificate number, exports the personalized slide deck as a PDF, saves it to Google Drive, emails it through Gmail, updates the source sheet to mark the row as processed, and deletes the temporary Slides file. A batch loop plus a 10-second wait keeps processing stable and helps avoid Google API rate limits.\n\n### Setup steps\n\nSet up a Google Sheet with recipient data and columns for certificate number, name, email, and sent status, then point the workflow\u2019s Google Sheets nodes to that document. Create a Google Slides template with the exact placeholders `[Name]`, `[Date]`, and `[N]`, update the template file ID in the copy step, and choose the Google Drive folder where generated PDFs will be stored. After that, connect valid Google OAuth2 credentials for Drive, Slides, Sheets, and Gmail in n8n, then review the Gmail node content and confirm the PDF attachment is sourced from the export step.\n"
},
"typeVersion": 1
},
{
"id": "308eda62-8989-4d70-8781-9da27efc2b46",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
480
],
"parameters": {
"color": 7,
"width": 656,
"height": 304,
"content": "## STEP 3 - Email\nCertificates are automatically sent to recipients"
},
"typeVersion": 1
},
{
"id": "54863914-ad67-4fee-939c-ac670c4a26cf",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1216,
816
],
"parameters": {
"color": 7,
"width": 656,
"height": 304,
"content": "## STEP 4 - Save to Google Drive\nTemporary Google Slides files created during the generation process are automatically deleted after use, keeping **Google Drive clean and organized**."
},
"typeVersion": 1
},
{
"id": "b5afef8e-6853-421c-815b-908839bf3884",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
432,
-640
],
"parameters": {
"color": 7,
"width": 736,
"height": 736,
"content": "## MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new **YouTube channel**](https://youtube.com/@n3witalia). Here I\u2019ll share videos and Shorts with practical tutorials and **FREE templates for n8n**.\n\n[](https://youtube.com/@n3witalia)"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "3c018ed2-5b9e-4408-a579-01726573a853",
"connections": {
"Merge": {
"main": [
[
{
"node": "Wait 10s",
"type": "main",
"index": 0
}
]
]
},
"Wait 10s": {
"main": [
[
{
"node": "Process One at a Time",
"type": "main",
"index": 0
}
]
]
},
"Read File": {
"main": [
[
{
"node": "Process One at a Time",
"type": "main",
"index": 0
}
]
]
},
"Export to PDF": {
"main": [
[
{
"node": "Save PDF to Drive",
"type": "main",
"index": 0
},
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"Send a message": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Delete Temp Slide": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Mark as Processed": {
"main": [
[
{
"node": "Delete Temp Slide",
"type": "main",
"index": 0
}
]
]
},
"Save PDF to Drive": {
"main": [
[
{
"node": "Mark as Processed",
"type": "main",
"index": 0
}
]
]
},
"Copy Slides Template": {
"main": [
[
{
"node": "Replace Template Placeholders",
"type": "main",
"index": 0
}
]
]
},
"Process One at a Time": {
"main": [
[],
[
{
"node": "Copy Slides Template",
"type": "main",
"index": 0
}
]
]
},
"Replace Template Placeholders": {
"main": [
[
{
"node": "Export to PDF",
"type": "main",
"index": 0
}
]
]
},
"When clicking 'Test workflow'": {
"main": [
[
{
"node": "Read File",
"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.
gmailOAuth2googleDriveOAuth2ApigoogleSheetsOAuth2ApigoogleSlidesOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates the bulk generation and delivery of personalized certificates using Google Sheets, Google Slides, Google Drive, and Gmail.
Source: https://n8n.io/workflows/14081/ — 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.
Shopify and E-Commerce store owners often struggle to create engaging 3D videos from static product images. This workflow automates that entire process—from image upload to video delivery—so store own
Hiring teams often struggle with document follow-ups, offer letter generation, and stakeholder communication. Manual checks, email back-and-forth, and missing files slow down hiring and create chaos d
Paste your interview recording URL into a simple form, describe the moments you want to find, and the workflow takes care of everything else. WayinVideo AI scans the full recording and extracts only t
Submit a new employee's details and your onboarding recording URL via a simple form and the workflow automatically extracts the specific training moments relevant to that employee. WayinVideo's Find M
This workflow automates the generation and delivery of personalized business documents (e.g., contracts, job offers, invoices, pay slips) in PDF format. The data source is a Google Sheet, and the docu