This workflow corresponds to n8n.io template #13806 — we link there as the canonical source.
This workflow follows the Agent → 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "0ed000fc-5884-4d56-a94c-c6bf2722c173",
"name": "Webhook - Upload Test Paper",
"type": "n8n-nodes-base.webhook",
"position": [
-1872,
-464
],
"parameters": {
"path": "grade-assignment",
"options": {
"rawBody": true
},
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "14bf826a-9bba-410c-9482-2578ea26b949",
"name": "Extract Text from Test Paper",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1648,
-464
],
"parameters": {
"options": {},
"operation": "pdf"
},
"typeVersion": 1
},
{
"id": "7acd4df7-f43b-480c-a7a3-2ea497c6ad2e",
"name": "Prepare Assignment Data",
"type": "n8n-nodes-base.set",
"position": [
-1424,
-464
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "studentName",
"name": "studentName",
"type": "string",
"value": "={{ $json.body.studentName || 'Unknown Student' }}"
},
{
"id": "assignmentTitle",
"name": "assignmentTitle",
"type": "string",
"value": "={{ $json.body.assignmentTitle || 'Engineering Assignment' }}"
},
{
"id": "testPaperText",
"name": "testPaperText",
"type": "string",
"value": "={{ $('Extract Text from Test Paper').item.json.data }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "243a790d-0757-4814-83d0-4d3733dc15aa",
"name": "Load Answer Script",
"type": "n8n-nodes-base.set",
"position": [
-1200,
-464
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "answerScript",
"name": "answerScript",
"type": "string",
"value": "=Question 1: Explain Ohm's Law and its applications (10 marks)\nAnswer: Ohm's Law states V=IR where V is voltage, I is current, R is resistance. Applications include circuit design, electrical troubleshooting, power calculations.\n\nQuestion 2: Describe the working principle of a DC motor (15 marks)\nAnswer: DC motor converts electrical energy to mechanical energy using electromagnetic induction. Current through armature creates magnetic field that interacts with stator field causing rotation.\n\nQuestion 3: Calculate stress in a beam under load (20 marks)\nAnswer: Stress = Force/Area. For bending stress: \u03c3 = My/I where M is moment, y is distance from neutral axis, I is moment of inertia.\n\nQuestion 4: Explain thermodynamic cycles (15 marks)\nAnswer: Common cycles include Carnot, Otto, Diesel, Rankine. Each involves heat addition, expansion, heat rejection, compression stages for energy conversion.\n\nQuestion 5: Discuss Boolean algebra and logic gates (10 marks)\nAnswer: Boolean algebra uses AND, OR, NOT operations. Logic gates implement these: AND gate outputs 1 only when all inputs are 1, OR gate outputs 1 when any input is 1."
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a3932528-d56a-49c1-9242-c26cf539f43f",
"name": "AI Agent - Grade Assignment",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-976,
-464
],
"parameters": {
"text": "=You are an expert engineering professor grading student assignments. \n\nANSWER SCRIPT (Correct Answers with Marks):\n{{ $json.answerScript }}\n\nSTUDENT SUBMISSION:\n{{ $json.testPaperText }}\n\nGrade this engineering assignment by:\n1. Comparing student answers against the answer script\n2. Award marks based on correctness, completeness, and technical accuracy\n3. Provide detailed feedback for each question\n4. Calculate total marks obtained\n\nProvide output in this JSON format:\n{\n \"questions\": [\n {\n \"questionNumber\": 1,\n \"maxMarks\": 10,\n \"marksObtained\": 8,\n \"feedback\": \"Good explanation of Ohm's Law but missing practical examples\"\n }\n ],\n \"totalMarks\": 70,\n \"totalObtained\": 55,\n \"percentage\": 78.57,\n \"grade\": \"B+\",\n \"overallFeedback\": \"Strong understanding of core concepts with room for improvement in practical applications\"\n}",
"options": {
"systemMessage": "You are a precise grading assistant. Always return valid JSON only."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 1.7
},
{
"id": "27d5f8e7-2af0-4df9-9420-0eca38b94e04",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-832,
-240
],
"parameters": {},
"typeVersion": 1.2
},
{
"id": "95194943-b7c5-4a0c-a2f5-a0a9ab3243b9",
"name": "Generate Results Table",
"type": "n8n-nodes-base.code",
"position": [
-624,
-464
],
"parameters": {
"jsCode": "const gradingResult = $input.first().json;\nconst studentName = $('Prepare Assignment Data').first().json.studentName;\nconst assignmentTitle = $('Prepare Assignment Data').first().json.assignmentTitle;\n\n// Create HTML table\nlet htmlTable = `\n<h2>Grading Report: ${assignmentTitle}</h2>\n<h3>Student: ${studentName}</h3>\n<table border=\"1\" cellpadding=\"10\" cellspacing=\"0\" style=\"border-collapse: collapse; width: 100%;\">\n <thead>\n <tr style=\"background-color: #4CAF50; color: white;\">\n <th>Question</th>\n <th>Max Marks</th>\n <th>Marks Obtained</th>\n <th>Feedback</th>\n </tr>\n </thead>\n <tbody>\n`;\n\ngradingResult.questions.forEach(q => {\n htmlTable += `\n <tr>\n <td>Question ${q.questionNumber}</td>\n <td>${q.maxMarks}</td>\n <td>${q.marksObtained}</td>\n <td>${q.feedback}</td>\n </tr>\n `;\n});\n\nhtmlTable += `\n </tbody>\n <tfoot>\n <tr style=\"background-color: #f2f2f2; font-weight: bold;\">\n <td>TOTAL</td>\n <td>${gradingResult.totalMarks}</td>\n <td>${gradingResult.totalObtained}</td>\n <td>Grade: ${gradingResult.grade} (${gradingResult.percentage.toFixed(2)}%)</td>\n </tr>\n </tfoot>\n</table>\n<p><strong>Overall Feedback:</strong> ${gradingResult.overallFeedback}</p>\n`;\n\n// Create CSV data\nlet csvData = \"Question,Max Marks,Marks Obtained,Feedback\\n\";\ngradingResult.questions.forEach(q => {\n csvData += `\"Question ${q.questionNumber}\",${q.maxMarks},${q.marksObtained},\"${q.feedback.replace(/\"/g, '\"\"')}\"\\n`;\n});\ncsvData += `\"TOTAL\",${gradingResult.totalMarks},${gradingResult.totalObtained},\"Grade: ${gradingResult.grade} (${gradingResult.percentage.toFixed(2)}%)\"\\n`;\n\nreturn {\n studentName,\n assignmentTitle,\n htmlTable,\n csvData,\n gradingResult,\n summary: `${studentName} scored ${gradingResult.totalObtained}/${gradingResult.totalMarks} (${gradingResult.percentage.toFixed(2)}%) - Grade: ${gradingResult.grade}`\n};"
},
"typeVersion": 2
},
{
"id": "26226c89-7643-472c-9fea-b14e2370eb63",
"name": "Convert to CSV File",
"type": "n8n-nodes-base.convertToFile",
"position": [
-176,
-464
],
"parameters": {
"options": {},
"binaryPropertyName": "=result-{{ $json.body.studentName || 'Unknown Student' }}"
},
"typeVersion": 1.1
},
{
"id": "da46bbc9-f392-4c18-b2e8-2c84506854dd",
"name": "Prepare CSV Data",
"type": "n8n-nodes-base.set",
"position": [
-400,
-464
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "data",
"name": "data",
"type": "string",
"value": "={{ $('Generate Results Table').first().json.csvData }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "2eb6444f-ec80-4d99-9cda-16f3ffdb908b",
"name": "Google Gemini Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
-976,
-240
],
"parameters": {
"options": {}
},
"credentials": {
"googlePalmApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "2d334fb3-448f-4bcf-b6ee-5516c1aef5ae",
"name": "Upload file",
"type": "n8n-nodes-base.googleDrive",
"position": [
48,
-464
],
"parameters": {
"name": "=result-{{ $json.body.studentName || 'Unknown Student' }}",
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
},
"inputDataFieldName": "result-{{ $json.body.studentName || 'Unknown Student' }}"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "9b832100-ecbc-4d17-bba2-5039bdfa4157",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2560,
-768
],
"parameters": {
"width": 560,
"height": 464,
"content": "## AI Assignment Grader\n\n\n### How it works\n1. The workflow triggers when a student's test paper is uploaded via a webhook.\n2. It extracts text from the uploaded PDF and loads a predefined answer script.\n3. An AI model compares the student's submission against the correct answers, providing detailed feedback, marks per question, and a total score.\n4. A comprehensive grading report is generated in both HTML and CSV formats.\n5. The CSV grading report is then uploaded to your specified Google Drive folder.\n\n\n### Setup\n- [ ] Connect your Google Gemini account.\n- [ ] Connect your Google Drive account.\n- [ ] Configure the Webhook URL to receive test paper submissions.\n- [ ] Adjust the 'Load Answer Script' node with your specific assignment's correct answers and marking scheme.\n- [ ] Select the target Google Drive folder for saving graded reports."
},
"typeVersion": 1
},
{
"id": "3f2f4532-bb4b-4f3a-8593-52f998c2b1de",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1936,
-544
],
"parameters": {
"color": 7,
"width": 656,
"height": 288,
"content": "## Get question paper\n"
},
"typeVersion": 1
},
{
"id": "b85e3a83-db4b-4b30-943c-c1a5521a275c",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1216,
-544
],
"parameters": {
"color": 7,
"width": 736,
"height": 464,
"content": "## check answers "
},
"typeVersion": 1
},
{
"id": "a63b898a-15a8-4c45-a741-6aaffc075733",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-464,
-544
],
"parameters": {
"color": 7,
"width": 704,
"height": 256,
"content": "## upload result to drive"
},
"typeVersion": 1
}
],
"connections": {
"Prepare CSV Data": {
"main": [
[
{
"node": "Convert to CSV File",
"type": "main",
"index": 0
}
]
]
},
"Load Answer Script": {
"main": [
[
{
"node": "AI Agent - Grade Assignment",
"type": "main",
"index": 0
}
]
]
},
"Convert to CSV File": {
"main": [
[
{
"node": "Upload file",
"type": "main",
"index": 0
}
]
]
},
"Generate Results Table": {
"main": [
[
{
"node": "Prepare CSV Data",
"type": "main",
"index": 0
}
]
]
},
"Prepare Assignment Data": {
"main": [
[
{
"node": "Load Answer Script",
"type": "main",
"index": 0
}
]
]
},
"Google Gemini Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent - Grade Assignment",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "AI Agent - Grade Assignment",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"AI Agent - Grade Assignment": {
"main": [
[
{
"node": "Generate Results Table",
"type": "main",
"index": 0
}
]
]
},
"Webhook - Upload Test Paper": {
"main": [
[
{
"node": "Extract Text from Test Paper",
"type": "main",
"index": 0
}
]
]
},
"Extract Text from Test Paper": {
"main": [
[
{
"node": "Prepare Assignment 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.
googleDriveOAuth2ApigooglePalmApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow is designed for educators, professors, academic institutions, coaching centers, and edtech platforms that want to automate the grading of written assignments or test papers. It’s ideal for scenarios where consistent evaluation, detailed feedback, and structured…
Source: https://n8n.io/workflows/13806/ — 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.
Resume Screening & Behavioral Interviews with Gemini, Elevenlabs, & Notion ATS copy. Uses outputParserStructured, chainLlm, googleDrive, stickyNote. Webhook trigger; 67 nodes.
Candidate Engagement | Resume Screening | AI Voice Interviews | Applicant Insights
Automated social media content creation from video transcripts Action: Receives webhook from Airtable automation Data: RecordId and action type (e.g., "post-ig") Purpose: Starts the content generation
⏺ 🚀 How it works
Are you drowning in daily operational chaos, desperately trying to juggle sales, projects, content, and client communication? Imagine an AI brain that handles it all, freeing you to lead your business