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 →
{
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "grade",
"options": {}
},
"id": "grade-webhook-id",
"name": "Webhook Grade",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
1500,
200
]
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "cfg-api-domain",
"name": "api_domain",
"value": "https://9router.n8n71.com/v1",
"type": "string"
},
{
"id": "cfg-lms-domain",
"name": "lms_domain",
"value": "https://lms.n8n71.com",
"type": "string"
},
{
"id": "cfg-key",
"name": "api_key",
"value": "",
"type": "string"
},
{
"id": "cfg-model",
"name": "model",
"value": "tesstm3",
"type": "string"
}
]
},
"options": {}
},
"id": "grade-setup-config-id",
"name": "Setup Config",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1720,
200
]
},
{
"parameters": {
"method": "GET",
"url": "={{ $('Setup Config').first().json.lms_domain }}/automation/sessions/{{ $('Webhook Grade').first().json.body.session_id }}/classes/{{ $('Webhook Grade').first().json.body.class_id }}/submissions",
"options": {
"allowUnauthorizedCerts": true,
"timeout": 30000
}
},
"id": "grade-get-subs-id",
"name": "GET Submissions",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1940,
200
]
},
{
"parameters": {
"jsCode": "return $input.all().map(item => {\n const sub = item.json;\n\n const systemPrompt = [\n 'B\u1ea1n l\u00e0 m\u1ed9t AI ch\u1ea5m b\u00e0i t\u1eadp l\u1eadp tr\u00ecnh t\u1ef1 \u0111\u1ed9ng cho h\u1ecdc sinh K-12.',\n '',\n 'QUY T\u1eaeC B\u1eaeT BU\u1ed8C:',\n '- Ph\u00e2n t\u00edch th\u00f4ng tin n\u1ed9p b\u00e0i (\u0111\u01b0\u1eddng d\u1eabn GitHub v\u00e0/ho\u1eb7c n\u1ed9i dung b\u00e0i) v\u00e0 \u0111\u01b0a ra nh\u1eadn x\u00e9t ng\u1eafn g\u1ecdn d\u01b0\u1edbi 3 c\u00e2u, mang t\u00ednh x\u00e2y d\u1ef1ng, kh\u00edch l\u1ec7 h\u1ecdc sinh.',\n '- Ch\u1ea5m \u0111i\u1ec3m ch\u1eef \u0111\u1ea1i di\u1ec7n cho b\u00e0i n\u1ed9p, CH\u1ec8 \u0111\u01b0\u1ee3c ch\u1ecdn 1 trong 4 gi\u00e1 tr\u1ecb: \"A\", \"B\", \"C\", \"D\" (A = xu\u1ea5t s\u1eafc, B = \u0111\u1ea1t y\u00eau c\u1ea7u, C = c\u00f2n thi\u1ebfu s\u00f3t, D = ch\u01b0a \u0111\u1ea1t).',\n '- CH\u1ec8 tr\u1ea3 v\u1ec1 m\u1ed9t JSON Object thu\u1ea7n, KH\u00d4NG markdown, KH\u00d4NG b\u1ecdc trong ```, \u0111\u00fang d\u1ea1ng: {\"comment\":\"nh\u1eadn x\u00e9t...\",\"note\":\"A\"}'\n ].join('\\n');\n\n const userPrompt = `Th\u00f4ng tin b\u00e0i n\u1ed9p:\\n- T\u00ean h\u1ecdc sinh: ${sub.student?.fullName || ''}\\n- Link n\u1ed9p b\u00e0i (Git): ${sub.link_git || ''}\\n- Ti\u00eau \u0111\u1ec1 b\u00e0i t\u1eadp: ${sub.homework_title || ''}`;\n\n return { json: { systemPrompt, userPrompt, exerciseId: sub.id } };\n});"
},
"id": "grade-build-prompt-id",
"name": "Build Prompt Grade",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2160,
200
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $('Setup Config').first().json.api_domain }}/chat/completions",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "=Bearer {{ $('Setup Config').first().json.api_key }}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ model: $('Setup Config').first().json.model, temperature: 0.3, messages: [ {role:'system', content: $json.systemPrompt}, {role:'user', content: $json.userPrompt} ] }) }}",
"options": {
"timeout": 120000
},
"retryOnFail": true,
"maxTries": 3,
"waitBetweenTries": 3000
},
"id": "grade-call-llm-id",
"name": "Call LLM Grade",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2380,
200
]
},
{
"parameters": {
"jsCode": "const ALLOWED_NOTES = ['A', 'B', 'C', 'D'];\n\nreturn $input.all().map((item, i) => {\n const raw = item.json.choices?.[0]?.message?.content || '';\n let gradeData = {};\n try {\n const m = raw.match(/\\{[\\s\\S]*\\}/);\n if (m) gradeData = JSON.parse(m[0]);\n } catch (e) {\n gradeData = {};\n }\n\n let note = String(gradeData.note || '').trim().toUpperCase();\n if (!ALLOWED_NOTES.includes(note)) note = 'B';\n\n const bp = $('Build Prompt Grade').all()[i]?.json || {};\n return { json: {\n exerciseId: bp.exerciseId,\n comment: String(gradeData.comment || '\u0110\u00e3 ch\u1ea5m b\u00e0i').trim(),\n note\n } };\n});"
},
"id": "grade-parse-output-id",
"name": "Parse & Normalize Grade",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2600,
200
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $('Setup Config').first().json.lms_domain }}/automation/grade",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json) }}",
"options": {
"allowUnauthorizedCerts": true,
"timeout": 30000
}
},
"id": "grade-post-lms-id",
"name": "POST to LMS Grade",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2820,
200
]
}
],
"connections": {
"Webhook Grade": {
"main": [
[
{
"node": "Setup Config",
"type": "main",
"index": 0
}
]
]
},
"Setup Config": {
"main": [
[
{
"node": "GET Submissions",
"type": "main",
"index": 0
}
]
]
},
"GET Submissions": {
"main": [
[
{
"node": "Build Prompt Grade",
"type": "main",
"index": 0
}
]
]
},
"Build Prompt Grade": {
"main": [
[
{
"node": "Call LLM Grade",
"type": "main",
"index": 0
}
]
]
},
"Call LLM Grade": {
"main": [
[
{
"node": "Parse & Normalize Grade",
"type": "main",
"index": 0
}
]
]
},
"Parse & Normalize Grade": {
"main": [
[
{
"node": "POST to LMS Grade",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Grade. Uses httpRequest. Webhook trigger; 7 nodes.
Source: https://github.com/DoanDuyThanh71/lmsv1/blob/b8627a2c443760d9b77fad30d6fc6eac76b41714/n8n_workflows/grade.json — 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 template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di
This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .
eek-Go v2 (Batch-Then-Review). Uses httpRequest. Webhook trigger; 75 nodes.
This workflow receives webhook requests from a content calendar and uses the X API v2 to publish text posts, threads, image/video posts, and polls, as well as delete existing posts and run a credentia
This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c