This workflow corresponds to n8n.io template #17211 — we link there as the canonical source.
This workflow follows the Chainllm → 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 →
{
"id": "08YGLiiNUcn80TWp",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Generate weekly student progress reports with Gemini and Supabase",
"tags": [],
"nodes": [
{
"id": "2c08a20c-04c0-4870-9bec-cc426847e913",
"name": "Template Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-192,
1104
],
"parameters": {
"color": 4,
"width": 720,
"height": 1076,
"content": "## \ud83d\udcda Generate Weekly Student Progress Reports with Gemini and Supabase\n\n## Who's it for\nCoaching centers and tutoring businesses that track attendance and scores per student and want an automatic weekly report for staff, plus an early heads-up when a specific student needs attention, instead of a coach manually reviewing every student's numbers each week.\n\n## How it works\nOnce a week, the workflow pulls each student's attendance and scores from Supabase. Gemini writes a short performance summary per student and decides whether they need attention (e.g. a score drop or low attendance). Flagged students trigger an immediate WhatsApp alert to the coach and get logged separately, so nothing waits for the weekly report to surface a problem. Every student, flagged or not, also gets folded into one combined weekly report: generated as a PDF and sent to the coach over WhatsApp.\n\n## How to set up\n1. Connect your Supabase credentials and create the tables listed in the sticky notes near the Supabase nodes.\n2. Connect your Google Gemini API credentials to the Chat Model node.\n3. Connect your WhatsApp Business Cloud credentials to both send nodes.\n4. Get an API key from your HTML-to-PDF provider and a file-hosting provider.\n5. Open the Set Configuration node and fill in your table names, coach's WhatsApp number, WhatsApp phone number ID, and API details.\n6. Set your preferred run day/time in the Schedule Trigger.\n7. Activate the workflow.\n\n## Requirements\n- Supabase project with weekly student attendance/score data\n- Google Gemini API key\n- WhatsApp Business Cloud API access\n- An HTML-to-PDF API and a file-upload/hosting API\n\n## How to customize\nEdit the prompt in Generate Student Summary to change what counts as needing attention (e.g. a stricter score-drop threshold). Edit the PDF template in Build Weekly Report HTML to match your coaching center's branding."
},
"typeVersion": 1
},
{
"id": "6405acbb-dfcb-4ccb-8463-23f75ddb836d",
"name": "Upload Response Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
2784,
2256
],
"parameters": {
"color": 3,
"width": 312,
"height": 192,
"content": "\u26a0\ufe0f Verify field name\nAssumes your upload API returns the file's public link as `url`. Check your provider's actual response and update the next node if the field name differs."
},
"typeVersion": 1
},
{
"id": "4772340b-271d-4f71-82a7-553664c7fbe4",
"name": "Supabase Schema Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
3360,
1824
],
"parameters": {
"color": 7,
"width": 320,
"height": 252,
"content": "## Supabase Schema\nweekly_student_data: student_name, attendance_pct, avg_score, previous_avg_score, parent_name.\nattention_flags: student_name, flag_reason, created_at.\nweekly_reports: report_url, created_at."
},
"typeVersion": 1
},
{
"id": "09ffd6f1-7e58-43ae-90e5-edae25557394",
"name": "Section - Trigger and Setup",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
1584
],
"parameters": {
"color": 7,
"width": 900,
"height": 360,
"content": "## 1\ufe0f\u20e3\u20e3 2\ufe0f\u20e3 Trigger + Configuration\nRuns weekly, then pulls every student's attendance and score data. Required columns: student_name, attendance_pct, avg_score, previous_avg_score, parent_name."
},
"typeVersion": 1
},
{
"id": "804d993f-c02c-4b2a-80ff-fde333c7f332",
"name": "Section - AI Summary",
"type": "n8n-nodes-base.stickyNote",
"position": [
1488,
1536
],
"parameters": {
"color": 7,
"width": 700,
"height": 600,
"content": "## 3\ufe0f\u20e3 AI Summary Per Student\nRuns once per student. Gemini writes a short summary and decides flag_for_attention based on score drop or low attendance, edit the prompt to change that threshold."
},
"typeVersion": 1
},
{
"id": "2cf15f22-87ea-488d-b0a3-9b9208a03e4c",
"name": "Section - Attention Alert Branch",
"type": "n8n-nodes-base.stickyNote",
"position": [
2272,
1504
],
"parameters": {
"color": 7,
"width": 760,
"height": 340,
"content": "## 4\ufe0f\u20e3 If Flagged: Alert the Coach Immediately\nThis branch runs independently of the weekly report below, flagged students get a WhatsApp alert and a logged record right away, not once a week."
},
"typeVersion": 1
},
{
"id": "85fa964e-b733-4543-909e-4ca146e3bb8d",
"name": "Section - Compile and Send Report",
"type": "n8n-nodes-base.stickyNote",
"position": [
2224,
1952
],
"parameters": {
"color": 7,
"width": 1580,
"height": 360,
"content": "## 5\ufe0f\u20e3 Every Student: Compile the Weekly Report\nWaits for every student's summary, builds one combined HTML report, converts it to PDF, and sends it to the coach over WhatsApp."
},
"typeVersion": 1
},
{
"id": "c7a72fb0-5005-45c4-9ce0-9eb53f5c9666",
"name": "Every Week",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
624,
1744
],
"parameters": {
"rule": {
"interval": [
{
"field": "weeks",
"triggerAtHour": 18
}
]
}
},
"typeVersion": 1.3
},
{
"id": "6da23ff3-e3ca-4e3c-8135-a59df1e2fb57",
"name": "Set Configuration",
"type": "n8n-nodes-base.set",
"position": [
944,
1744
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "f9a4303a-badc-4927-8600-be6f77a54564",
"name": "coach_name",
"type": "string",
"value": "REPLACE_WITH_COACH_NAME"
},
{
"id": "4a09e065-5239-4601-95e1-21bd414af65d",
"name": "coach_notify_number",
"type": "string",
"value": "REPLACE_WITH_COACH_WHATSAPP_NUMBER"
},
{
"id": "ded2c8e5-1878-47dd-ba11-096b91baf886",
"name": "whatsapp_phone_number_id",
"type": "string",
"value": "REPLACE_WITH_WHATSAPP_PHONE_NUMBER_ID"
},
{
"id": "4ed40c76-023c-4952-a610-4bfe13aebcbe",
"name": "supabase_table_students",
"type": "string",
"value": "weekly_student_data"
},
{
"id": "5499e7e1-b1f7-4409-b628-4fdf91e8cb13",
"name": "supabase_table_flags",
"type": "string",
"value": "attention_flags"
},
{
"id": "d6b2fc0f-ea69-47ee-bed8-d65223904e6b",
"name": "supabase_table_reports",
"type": "string",
"value": "weekly_reports"
},
{
"id": "b5421c22-1823-4307-8516-50820f86a67a",
"name": "pdf_api_url",
"type": "string",
"value": "REPLACE_WITH_PDF_API_ENDPOINT"
},
{
"id": "fc848a03-d28d-48f8-9c09-7a3af3d8e729",
"name": "pdf_api_key",
"type": "string",
"value": "REPLACE_WITH_PDF_API_KEY"
},
{
"id": "ef159cf9-7939-44da-9476-17cb1c424640",
"name": "upload_api_url",
"type": "string",
"value": "REPLACE_WITH_UPLOAD_API_ENDPOINT"
},
{
"id": "c3bcec75-abac-4bb1-ba07-0c78f1fae917",
"name": "upload_api_key",
"type": "string",
"value": "REPLACE_WITH_UPLOAD_API_KEY"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "04abe450-6233-4932-8467-0bfaead3b490",
"name": "Fetch Weekly Student Data",
"type": "n8n-nodes-base.supabase",
"position": [
1296,
1744
],
"parameters": {
"tableId": "={{ $('Set Configuration').item.json.supabase_table_students }}",
"operation": "getAll",
"returnAll": true
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "506dbdb3-1568-4722-ad50-d7debb0e1f4a",
"name": "Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1600,
1984
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.5-flash"
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.1
},
{
"id": "1b76338c-5eed-433c-9748-5b3861df92af",
"name": "Generate Student Summary",
"type": "@n8n/n8n-nodes-langchain.chainLlm",
"position": [
1696,
1728
],
"parameters": {
"text": "=Write a short (2-3 sentence) weekly performance summary for this student, in an encouraging but honest tone.\n\nStudent: {{ $json.student_name }}\nAttendance this week: {{ $json.attendance_pct }}%\nAverage score this week: {{ $json.avg_score }}\nPrevious week's average score: {{ $json.previous_avg_score }}\n\nAlso decide if this student needs staff attention: flag_for_attention should be true if attendance is below 70%, or if avg_score dropped by more than 15 points compared to the previous week. If flagged, briefly explain why in flag_reason.",
"batching": {},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.8
},
{
"id": "99a1346f-a069-4a4e-a031-e1fb02c54970",
"name": "Summary Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1920,
1984
],
"parameters": {
"jsonSchemaExample": "{\n \"type\": \"object\",\n \"properties\": {\n \"summary_text\": {\n \"type\": \"string\"\n },\n \"flag_for_attention\": {\n \"type\": \"boolean\"\n },\n \"flag_reason\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"summary_text\",\n \"flag_for_attention\",\n \"flag_reason\"\n ]\n}"
},
"typeVersion": 1.3
},
{
"id": "13254808-7137-4730-a309-0792aaca83b9",
"name": "Needs Attention?",
"type": "n8n-nodes-base.if",
"position": [
2352,
1664
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "90fe5da6-964a-4d9a-8d94-7957a7f948cd",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.output.flag_for_attention }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "201b046e-beb6-49a3-ab99-db3542fa4497",
"name": "Notify Coach - Student Needs Attention",
"type": "n8n-nodes-base.whatsApp",
"position": [
2624,
1648
],
"parameters": {
"textBody": "=Heads up: {{ $json.student_name }} needs attention this week. {{ $json.output.flag_reason }}",
"operation": "send",
"phoneNumberId": "={{ $('Set Configuration').item.json.whatsapp_phone_number_id }}",
"additionalFields": {},
"recipientPhoneNumber": "={{ $('Set Configuration').item.json.coach_notify_number }}"
},
"credentials": {
"whatsAppApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.1
},
{
"id": "c278b07d-d387-40b9-a58c-65147d79762b",
"name": "Log Flagged Student",
"type": "n8n-nodes-base.supabase",
"position": [
2848,
1648
],
"parameters": {
"operation": "insert"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "42e216a4-8338-4e59-90d9-c3c5eef47aa8",
"name": "Aggregate All Summaries",
"type": "n8n-nodes-base.aggregate",
"position": [
2288,
2096
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "students"
},
"typeVersion": 1
},
{
"id": "16fba64d-9074-4e74-9c39-839064c37eec",
"name": "Build Weekly Report HTML",
"type": "n8n-nodes-base.code",
"position": [
2496,
2096
],
"parameters": {
"jsCode": "const students = $json.students;\n\nconst rows = students.map(s => {\n const flagBadge = s.output.flag_for_attention\n ? '<span style=\"color:#c0392b;font-weight:bold;\">Needs Attention</span>'\n : '<span style=\"color:#27ae60;\">On Track</span>';\n return `<tr>\n <td>${s.student_name}</td>\n <td>${s.attendance_pct}%</td>\n <td>${s.avg_score}</td>\n <td>${flagBadge}</td>\n <td>${s.output.summary_text}</td>\n </tr>`;\n}).join('');\n\nconst html = `<html><body style=\"font-family: Arial, sans-serif; padding: 24px;\">\n<h2>Weekly Progress Report</h2>\n<p>Prepared for ${$('Set Configuration').first().json.coach_name} on ${new Date().toISOString().slice(0,10)}</p>\n<table border=\"1\" cellpadding=\"8\" cellspacing=\"0\" style=\"border-collapse: collapse; width: 100%;\">\n<tr><th>Student</th><th>Attendance</th><th>Avg Score</th><th>Status</th><th>Summary</th></tr>\n${rows}\n</table>\n</body></html>`;\n\nreturn [{ json: { report_html: html } }];"
},
"typeVersion": 2
},
{
"id": "6a4f1c0d-e55b-4083-892b-74e5089fbd68",
"name": "Generate Report PDF",
"type": "n8n-nodes-base.httpRequest",
"position": [
2704,
2096
],
"parameters": {
"url": "={{ $('Set Configuration').item.json.pdf_api_url }}",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
},
"jsonBody": "={{ JSON.stringify({ html: $json.report_html }) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "CLIENT-API-KEY",
"value": "={{ $('Set Configuration').item.json.pdf_api_key }}"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.4
},
{
"id": "b6f110a3-7e7e-44ca-b4aa-a40466bb572d",
"name": "Upload Report PDF",
"type": "n8n-nodes-base.httpRequest",
"position": [
2928,
2096
],
"parameters": {
"url": "={{ $('Set Configuration').item.json.upload_api_url }}",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "multipart-form-data",
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "data"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "CLIENT-API-KEY",
"value": "={{ $('Set Configuration').item.json.upload_api_key }}"
}
]
}
},
"typeVersion": 4.4
},
{
"id": "abf17c4b-6ce8-4d00-8c93-242575d5ba1e",
"name": "Send Weekly Report to Coach",
"type": "n8n-nodes-base.whatsApp",
"position": [
3136,
2096
],
"parameters": {
"operation": "send",
"messageType": "document",
"phoneNumberId": "={{ $('Set Configuration').item.json.whatsapp_phone_number_id }}",
"additionalFields": {},
"recipientPhoneNumber": "={{ $('Set Configuration').item.json.coach_notify_number }}"
},
"credentials": {
"whatsAppApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.1
},
{
"id": "0c833dfe-0e53-4ccd-a1e4-e981355dcec8",
"name": "Log Report Sent",
"type": "n8n-nodes-base.supabase",
"position": [
3472,
2096
],
"parameters": {
"operation": "insert"
},
"credentials": {
"supabaseApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
}
],
"active": true,
"settings": {
"binaryMode": "separate",
"callerPolicy": "workflowsFromSameOwner",
"timeSavedMode": "fixed",
"availableInMCP": false,
"executionOrder": "v1",
"executionTimeout": -1
},
"versionId": "a722aef7-9bd3-493e-900a-4912e418a489",
"nodeGroups": [],
"connections": {
"Every Week": {
"main": [
[
{
"node": "Set Configuration",
"type": "main",
"index": 0
}
]
]
},
"Summary Parser": {
"ai_outputParser": [
[
{
"node": "Generate Student Summary",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Needs Attention?": {
"main": [
[
{
"node": "Notify Coach - Student Needs Attention",
"type": "main",
"index": 0
}
]
]
},
"Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "Generate Student Summary",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Set Configuration": {
"main": [
[
{
"node": "Fetch Weekly Student Data",
"type": "main",
"index": 0
}
]
]
},
"Upload Report PDF": {
"main": [
[
{
"node": "Send Weekly Report to Coach",
"type": "main",
"index": 0
}
]
]
},
"Generate Report PDF": {
"main": [
[
{
"node": "Upload Report PDF",
"type": "main",
"index": 0
}
]
]
},
"Aggregate All Summaries": {
"main": [
[
{
"node": "Build Weekly Report HTML",
"type": "main",
"index": 0
}
]
]
},
"Build Weekly Report HTML": {
"main": [
[
{
"node": "Generate Report PDF",
"type": "main",
"index": 0
}
]
]
},
"Generate Student Summary": {
"main": [
[
{
"node": "Needs Attention?",
"type": "main",
"index": 0
},
{
"node": "Aggregate All Summaries",
"type": "main",
"index": 0
}
]
]
},
"Fetch Weekly Student Data": {
"main": [
[
{
"node": "Generate Student Summary",
"type": "main",
"index": 0
}
]
]
},
"Send Weekly Report to Coach": {
"main": [
[
{
"node": "Log Report Sent",
"type": "main",
"index": 0
}
]
]
},
"Notify Coach - Student Needs Attention": {
"main": [
[
{
"node": "Log Flagged Student",
"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.
googlePalmApisupabaseApiwhatsAppApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow runs weekly to pull student attendance and score data from Supabase, uses Google Gemini to generate per-student performance summaries and attention flags, sends immediate WhatsApp alerts for flagged students, then compiles all summaries into a PDF report, uploads…
Source: https://n8n.io/workflows/17211/ — 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.
kisisel asistan. Uses toolWorkflow, toolHttpRequest, toolCalculator, toolThink. Scheduled trigger; 43 nodes.
This workflow listens for incoming WhatsApp messages from clinic staff, uses Google Gemini to extract prescription details, generates a prescription PDF via an HTML-to-PDF API, uploads it to a public
LinkedIn_Job_Hunt_and_Cover_Letter. Uses outputParserStructured, outputParserAutofixing, googleDrive, agent. Scheduled trigger; 85 nodes.
Automatically scan major financial newswires for biotech catalyst events, score them with AI sentiment analysis, and surface ranked trade candidates — all without manual monitoring.
Cyber Zap Public. Uses httpRequest, chainLlm, outputParserStructured, telegram. Scheduled trigger; 69 nodes.