{
  "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
          }
        ]
      ]
    }
  }
}