This workflow corresponds to n8n.io template #12050 — we link there as the canonical source.
This workflow follows the Emailsend → 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": "g4y8sY02aLGEIBdl",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Zoom Attendance Evaluator with Auto Follow-u",
"tags": [],
"nodes": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
48,
304
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "sticky1-2345-6789-abcd-ef1234567890",
"name": "Sticky Note - Start",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
128
],
"parameters": {
"color": 7,
"width": 416,
"height": 352,
"content": "## Workflow Start\nThis workflow runs hourly to check recent Zoom meetings for attendance issues.\n\nConfigure the schedule trigger based on when your meetings typically end."
},
"typeVersion": 1
},
{
"id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"name": "Get Recent Meetings",
"type": "n8n-nodes-base.zoom",
"position": [
272,
304
],
"parameters": {
"filters": {},
"operation": "getAll",
"authentication": "oAuth2"
},
"credentials": {
"zoomOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "sticky2-3456-7890-bcde-f23456789012",
"name": "Sticky Note - Zoom",
"type": "n8n-nodes-base.stickyNote",
"position": [
464,
112
],
"parameters": {
"color": 7,
"width": 384,
"height": 368,
"content": "## Zoom Connection Required\nConnect your Zoom OAuth2 credentials here to fetch meeting data.\n\nThis node retrieves meetings from the last 24 hours."
},
"typeVersion": 1
},
{
"id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
"name": "Split Meetings",
"type": "n8n-nodes-base.itemLists",
"position": [
496,
304
],
"parameters": {
"options": {},
"fieldToSplitOut": "meetings"
},
"typeVersion": 3
},
{
"id": "d4e5f6a7-b8c9-0123-defa-456789012345",
"name": "Get Meeting Details",
"type": "n8n-nodes-base.zoom",
"position": [
720,
304
],
"parameters": {
"meetingId": "={{ $json.id }}",
"operation": "get",
"authentication": "oAuth2",
"additionalFields": {}
},
"credentials": {
"zoomOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "e5f6a7b8-c9d0-1234-efab-567890123456",
"name": "Get Attendance Report",
"type": "n8n-nodes-base.httpRequest",
"position": [
944,
304
],
"parameters": {
"url": "https://api.zoom.us/v2/report/meetings/{{ $json.id }}/participants",
"options": {
"redirect": {
"redirect": {}
}
},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zoomOAuth2Api"
},
"credentials": {
"zoomOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "sticky3-4567-8901-cdef-567890123456",
"name": "Sticky Note - Attendance",
"type": "n8n-nodes-base.stickyNote",
"position": [
880,
96
],
"parameters": {
"color": 7,
"width": 416,
"height": 400,
"content": "## Attendance Data\nFetches participant data including:\n- Join/leave times\n- Duration in meeting\n- Registration info\n- Email addresses"
},
"typeVersion": 1
},
{
"id": "f6a7b8c9-d0e1-2345-fabc-678901234567",
"name": "Split Participants",
"type": "n8n-nodes-base.itemLists",
"position": [
1168,
304
],
"parameters": {
"options": {},
"fieldToSplitOut": "participants"
},
"typeVersion": 3
},
{
"id": "a7b8c9d0-e1f2-3456-abcd-789012345678",
"name": "Evaluate Attendance",
"type": "n8n-nodes-base.code",
"position": [
1392,
304
],
"parameters": {
"jsCode": "// Calculate attendance status\nconst participant = $input.item.json;\nconst meetingDuration = $('Get Meeting Details').item.json.duration || 60; // in minutes\nconst participantDuration = participant.duration || 0; // in minutes\n\n// Determine attendance status\nlet status = 'attended';\nlet sendFollowUp = false;\n\nif (participantDuration === 0) {\n status = 'no-show';\n sendFollowUp = true;\n} else if (participantDuration < (meetingDuration * 0.5)) {\n status = 'early-leaver';\n sendFollowUp = true;\n} else if (participantDuration < (meetingDuration * 0.8)) {\n status = 'partial-attendance';\n sendFollowUp = true;\n}\n\nreturn {\n ...participant,\n attendanceStatus: status,\n sendFollowUp: sendFollowUp,\n meetingTopic: $('Get Meeting Details').item.json.topic,\n meetingId: $('Get Meeting Details').item.json.id,\n meetingDuration: meetingDuration,\n attendancePercentage: Math.round((participantDuration / meetingDuration) * 100)\n};"
},
"typeVersion": 2
},
{
"id": "sticky4-5678-9012-defa-678901234567",
"name": "Sticky Note - Logic",
"type": "n8n-nodes-base.stickyNote",
"position": [
1344,
32
],
"parameters": {
"color": 7,
"height": 384,
"content": "## Attendance Logic\nClassifies participants as:\n- **No-show**: 0 minutes attended\n- **Early-leaver**: <50% attendance\n- **Partial**: 50-80% attendance\n- **Full**: >80% attendance\n\nAdjust thresholds in the code as needed."
},
"typeVersion": 1
},
{
"id": "b8c9d0e1-f2a3-4567-bcde-890123456789",
"name": "Needs Follow-up?",
"type": "n8n-nodes-base.if",
"position": [
1616,
304
],
"parameters": {
"options": {},
"conditions": {
"boolean": [
{
"value1": "={{ $json.sendFollowUp }}",
"value2": true
}
]
}
},
"typeVersion": 2
},
{
"id": "c9d0e1f2-a3b4-5678-cdef-901234567890",
"name": "Get Recording Link",
"type": "n8n-nodes-base.httpRequest",
"position": [
1840,
304
],
"parameters": {
"url": "https://api.zoom.us/v2/meetings/{{ $json.meetingId }}/recordings",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "zoomOAuth2Api"
},
"credentials": {
"zoomOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "d0e1f2a3-b4c5-6789-defa-012345678901",
"name": "Get Handout Materials",
"type": "n8n-nodes-base.googleDrive",
"position": [
2064,
304
],
"parameters": {
"operation": "get"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "sticky5-6789-0123-efab-789012345678",
"name": "Sticky Note - Resources",
"type": "n8n-nodes-base.stickyNote",
"position": [
2000,
80
],
"parameters": {
"color": 7,
"height": 432,
"content": "## Configure Resources\n**Google Drive**: Add the file ID of your handout materials\n\n**Database**: Store your next session registration links in a database or configure them here"
},
"typeVersion": 1
},
{
"id": "e1f2a3b4-c5d6-7890-efab-123456789012",
"name": "Prepare Email Data",
"type": "n8n-nodes-base.code",
"position": [
2288,
304
],
"parameters": {
"jsCode": "// Get next session registration link\n// This could come from a database or calendar integration\n// For now, using a placeholder that should be replaced\n\nconst nextSessionLink = 'https://zoom.us/meeting/register/YOUR_NEXT_SESSION_ID';\n\n// You could also fetch this from a Google Sheet or database\n// Example: Query upcoming events from a calendar or registration system\n\nreturn {\n ...($('Evaluate Attendance').item.json),\n recordingUrl: $('Get Recording Link').item.json.share_url || $('Get Recording Link').item.json.recording_files?.[0]?.download_url || 'Recording processing',\n handoutUrl: $('Get Handout Materials').item.json.webContentLink || 'Materials URL',\n nextSessionLink: nextSessionLink,\n emailSubject: `Follow-up: ${$('Evaluate Attendance').item.json.meetingTopic} - ${$('Evaluate Attendance').item.json.attendanceStatus === 'no-show' ? 'Recording Available' : 'Complete Recording Available'}`,\n};"
},
"typeVersion": 2
},
{
"id": "f2a3b4c5-d6e7-8901-fabc-234567890123",
"name": "Send Follow-up Email",
"type": "n8n-nodes-base.emailSend",
"position": [
2512,
304
],
"parameters": {
"options": {
"attachments": "={{ $('Get Handout Materials').item.binary }}"
},
"subject": "={{ $json.emailSubject }}"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "sticky6-7890-1234-fabc-890123456789",
"name": "Sticky Note - Email",
"type": "n8n-nodes-base.stickyNote",
"position": [
2416,
-16
],
"parameters": {
"color": 7,
"height": 464,
"content": "## Email Configuration\n**SMTP Credentials Required**\nConfigure your email server (Gmail, SendGrid, etc.)\n\nThe email template automatically adapts based on:\n- No-show vs early-leaver status\n- Attendance percentage\n- Meeting details"
},
"typeVersion": 1
},
{
"id": "a3b4c5d6-e7f8-9012-abcd-345678901234",
"name": "Log to Google Sheets",
"type": "n8n-nodes-base.googleSheets",
"position": [
2736,
304
],
"parameters": {
"columns": {
"value": {},
"mappingMode": "autoMapInputData"
},
"options": {},
"operation": "append",
"sheetName": "Attendance_Log",
"documentId": {
"__rl": true,
"mode": "id",
"value": "YOUR_GOOGLE_SHEET_ID"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.5
},
{
"id": "sticky7-8901-2345-abcd-901234567890",
"name": "Sticky Note - Logging",
"type": "n8n-nodes-base.stickyNote",
"position": [
2672,
16
],
"parameters": {
"color": 7,
"width": 304,
"height": 448,
"content": "## Tracking & Analytics\n**Google Sheets**: Configure the sheet ID to log all follow-ups sent\n\nThis creates an audit trail of:\n- Who received follow-ups\n- Attendance status\n- When emails were sent\n- Meeting details"
},
"typeVersion": 1
},
{
"id": "740ce576-f158-4727-93b0-90b54255cbb1",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-752,
-512
],
"parameters": {
"width": 736,
"height": 640,
"content": "# \ud83d\ude80 Zoom Attendance Evaluator with Auto Follow-up\n\nThis workflow automates the post-meeting process by analyzing participant attendance duration and sending personalized follow-up emails.\n\n### \ud83d\udcdd What it does\n1. **Monitors** completed Zoom meetings.\n2. **Calculates** attendance duration (No-show / Early-leaver / Full-attendance).\n3. **Fetches** cloud recordings and handout materials.\n4. **Sends** tailored emails via SMTP based on attendance status.\n5. **Logs** all activities to Google Sheets.\n\n### \u2699\ufe0f How to set up\n1. **Global Configuration:**\n - Double-click the **\"Global Configuration\"** node (first node).\n - Enter your `Google Sheet ID`, `Sheet Name`, and `Handout File ID`.\n2. **Credentials:**\n - Connect **Zoom** (OAuth2 with `report:read:meeting`, `recording:read` scopes).\n - Connect **Google Drive** & **Google Sheets**.\n - Connect **SMTP** (Gmail, SendGrid, etc.).\n3. **Activate:**\n - Turn on the workflow to run hourly.\n\n---\n*Created by [Your Name]*"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"timezone": "America/New_York",
"errorWorkflow": "",
"executionOrder": "v1",
"saveManualExecutions": true,
"saveExecutionProgress": true,
"saveDataErrorExecution": "all",
"saveDataSuccessExecution": "all"
},
"versionId": "0f6f9d5b-d070-4cf7-9272-fcd1e5f46da4",
"connections": {
"Split Meetings": {
"main": [
[
{
"node": "Get Meeting Details",
"type": "main",
"index": 0
}
]
]
},
"Needs Follow-up?": {
"main": [
[
{
"node": "Get Recording Link",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "Get Recent Meetings",
"type": "main",
"index": 0
}
]
]
},
"Get Recording Link": {
"main": [
[
{
"node": "Get Handout Materials",
"type": "main",
"index": 0
}
]
]
},
"Prepare Email Data": {
"main": [
[
{
"node": "Send Follow-up Email",
"type": "main",
"index": 0
}
]
]
},
"Split Participants": {
"main": [
[
{
"node": "Evaluate Attendance",
"type": "main",
"index": 0
}
]
]
},
"Evaluate Attendance": {
"main": [
[
{
"node": "Needs Follow-up?",
"type": "main",
"index": 0
}
]
]
},
"Get Meeting Details": {
"main": [
[
{
"node": "Get Attendance Report",
"type": "main",
"index": 0
}
]
]
},
"Get Recent Meetings": {
"main": [
[
{
"node": "Split Meetings",
"type": "main",
"index": 0
}
]
]
},
"Send Follow-up Email": {
"main": [
[
{
"node": "Log to Google Sheets",
"type": "main",
"index": 0
}
]
]
},
"Get Attendance Report": {
"main": [
[
{
"node": "Split Participants",
"type": "main",
"index": 0
}
]
]
},
"Get Handout Materials": {
"main": [
[
{
"node": "Prepare Email 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.
googleDriveOAuth2ApigoogleSheetsOAuth2ApismtpzoomOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Workflow Overview Zoom Attendance Evaluator with Follow-up is an n8n automation workflow that automatically evaluates Zoom meeting attendance and sends follow-up emails to no-shows and early leavers with recordings and materials. Who's it for Companies and organizations that…
Source: https://n8n.io/workflows/12050/ — 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.
This n8n workflow automatically finds apartments for rent in Germany, filters them by your city, rent budget, and number of rooms, and applies to them via email. Each application includes: A personali
This workflow monitors Google Calendar for events indicating that a customer will visit the company today or the next day, retrieves the required details, and sends reminder notifications to the relev
PCN. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 60 nodes.
Security teams, DevOps engineers, vulnerability analysts, and automation builders who want to eliminate repetitive Nessus scan parsing, AI-based risk triage, and manual reporting. Designed for orgs fo
Convalidaciones Académicas - Estructura Base. Uses googleSheets, emailSend, googleDrive, httpRequest. Webhook trigger; 35 nodes.