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": "gen-quiz",
"options": {}
},
"id": "quiz-webhook-id",
"name": "Webhook Quiz",
"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": "quiz-setup-config-id",
"name": "Setup Config",
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
1720,
200
]
},
{
"parameters": {
"jsCode": "return $input.all().map(item => {\n const p = item.json.body || {};\n const lesson = p.lesson || {};\n const session = p.session || {};\n const document = p.document || '';\n\n const systemPrompt = [\n 'B\u1ea1n l\u00e0 gi\u00e1o vi\u00ean l\u1eadp tr\u00ecnh K-12. H\u00e3y so\u1ea1n m\u1ed9t b\u00e0i tr\u1eafc nghi\u1ec7m (quiz) g\u1ed3m \u0111\u00fang 5 c\u00e2u h\u1ecfi d\u1ef1a tr\u00ean n\u1ed9i dung t\u00e0i li\u1ec7u l\u00fd thuy\u1ebft \u0111\u01b0\u1ee3c cung c\u1ea5p.',\n '',\n 'QUY T\u1eaeC B\u1eaeT BU\u1ed8C (kh\u00f4ng \u0111\u01b0\u1ee3c vi ph\u1ea1m):',\n '- CH\u1ec8 tr\u1ea3 v\u1ec1 m\u1ed9t JSON Object thu\u1ea7n, KH\u00d4NG markdown, KH\u00d4NG b\u1ecdc trong ```json, KH\u00d4NG gi\u1ea3i th\u00edch th\u00eam.',\n '- JSON c\u00f3 d\u1ea1ng: {\"title\":\"...\",\"questions\":[ ... ]} v\u1edbi \u0111\u00fang 5 ph\u1ea7n t\u1eed trong \"questions\".',\n '- M\u1ed7i c\u00e2u h\u1ecfi c\u00f3 CH\u00cdNH X\u00c1C c\u00e1c tr\u01b0\u1eddng sau:',\n ' {',\n ' \"question\": \"N\u1ed9i dung c\u00e2u h\u1ecfi\",',\n ' \"option_1\": \"\u0110\u00e1p \u00e1n 1\",',\n ' \"option_2\": \"\u0110\u00e1p \u00e1n 2\",',\n ' \"option_3\": \"\u0110\u00e1p \u00e1n 3\",',\n ' \"option_4\": \"\u0110\u00e1p \u00e1n 4\",',\n ' \"correct_answer\": \"1\", // l\u00e0 chu\u1ed7i, ch\u1ec9 \u0111\u01b0\u1ee3c l\u00e0 \"1\", \"2\", \"3\" ho\u1eb7c \"4\"',\n ' \"point\": 1, // s\u1ed1 \u0111i\u1ec3m, m\u1eb7c \u0111\u1ecbnh 1',\n ' \"skill_id\": \"variable\", // CH\u1ec8 \u0111\u01b0\u1ee3c ch\u1ecdn 1 trong c\u00e1c gi\u00e1 tr\u1ecb: \"variable\", \"condition\", \"loop\", \"function\", \"array\" \u2014 l\u00e0 k\u1ef9 n\u0103ng l\u1eadp tr\u00ecnh ch\u00ednh m\u00e0 c\u00e2u h\u1ecfi ki\u1ec3m tra',\n ' \"explanation_1\": \"Gi\u1ea3i th\u00edch ng\u1eafn v\u00ec sao \u0111\u00e1p \u00e1n 1 \u0111\u00fang/sai\",',\n ' \"explanation_2\": \"...\",',\n ' \"explanation_3\": \"...\",',\n ' \"explanation_4\": \"...\"',\n ' }'\n ].join('\\n');\n\n const userPrompt = `D\u01b0\u1edbi \u0111\u00e2y l\u00e0 t\u00e0i li\u1ec7u l\u00fd thuy\u1ebft b\u00e0i \u0111\u1ecdc:\\n${document}\\n\\nH\u00e3y so\u1ea1n b\u00e0i tr\u1eafc nghi\u1ec7m cho b\u00e0i h\u1ecdc \"${lesson.title || ''}\" thu\u1ed9c ch\u01b0\u01a1ng \"${session.title || ''}\".`;\n\n return { json: { systemPrompt, userPrompt, lesson_id: p.lesson_id, lesson_title: lesson.title || 'B\u00e0i h\u1ecdc' } };\n});"
},
"id": "quiz-build-prompt-id",
"name": "Build Prompt Quiz",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1940,
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": "quiz-call-llm-id",
"name": "Call LLM Quiz",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2160,
200
]
},
{
"parameters": {
"jsCode": "const ALLOWED_SKILLS = ['variable', 'condition', 'loop', 'function', 'array'];\nconst ALLOWED_ANSWERS = ['1', '2', '3', '4'];\n\nreturn $input.all().map(item => {\n const raw = item.json.choices?.[0]?.message?.content || '';\n let quizData = {};\n try {\n const m = raw.match(/\\{[\\s\\S]*\\}/);\n if (m) quizData = JSON.parse(m[0]);\n } catch (e) {\n quizData = {};\n }\n\n const bp = $('Build Prompt Quiz').first().json;\n const rawQuestions = Array.isArray(quizData.questions) ? quizData.questions : [];\n\n const questions = rawQuestions.slice(0, 5).map((q, idx) => {\n q = q || {};\n let correct = String(q.correct_answer ?? '1').trim();\n if (!ALLOWED_ANSWERS.includes(correct)) correct = '1';\n\n let skill = String(q.skill_id ?? '').trim();\n if (!ALLOWED_SKILLS.includes(skill)) skill = null;\n\n let point = Number(q.point);\n if (!Number.isFinite(point) || point <= 0) point = 1;\n\n return {\n question: String(q.question || `C\u00e2u h\u1ecfi ${idx + 1}`).trim(),\n option_1: String(q.option_1 ?? '').trim() || '\u0110\u00e1p \u00e1n 1',\n option_2: String(q.option_2 ?? '').trim() || '\u0110\u00e1p \u00e1n 2',\n option_3: String(q.option_3 ?? '').trim() || '\u0110\u00e1p \u00e1n 3',\n option_4: String(q.option_4 ?? '').trim() || '\u0110\u00e1p \u00e1n 4',\n correct_answer: correct,\n point,\n skill_id: skill,\n explanation_1: String(q.explanation_1 ?? '').trim(),\n explanation_2: String(q.explanation_2 ?? '').trim(),\n explanation_3: String(q.explanation_3 ?? '').trim(),\n explanation_4: String(q.explanation_4 ?? '').trim()\n };\n });\n\n return { json: {\n lesson_id: bp.lesson_id,\n title: String(quizData.title || ('B\u00e0i ki\u1ec3m tra: ' + bp.lesson_title)),\n questions\n } };\n});"
},
"id": "quiz-parse-output-id",
"name": "Parse & Normalize Quiz",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
2380,
200
]
},
{
"parameters": {
"method": "POST",
"url": "={{ $('Setup Config').first().json.lms_domain }}/automation/assignment",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json) }}",
"options": {
"allowUnauthorizedCerts": true,
"timeout": 30000
}
},
"id": "quiz-post-lms-id",
"name": "POST to LMS Quiz",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
2600,
200
]
}
],
"connections": {
"Webhook Quiz": {
"main": [
[
{
"node": "Setup Config",
"type": "main",
"index": 0
}
]
]
},
"Setup Config": {
"main": [
[
{
"node": "Build Prompt Quiz",
"type": "main",
"index": 0
}
]
]
},
"Build Prompt Quiz": {
"main": [
[
{
"node": "Call LLM Quiz",
"type": "main",
"index": 0
}
]
]
},
"Call LLM Quiz": {
"main": [
[
{
"node": "Parse & Normalize Quiz",
"type": "main",
"index": 0
}
]
]
},
"Parse & Normalize Quiz": {
"main": [
[
{
"node": "POST to LMS Quiz",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Gen Quiz. Uses httpRequest. Webhook trigger; 6 nodes.
Source: https://github.com/DoanDuyThanh71/lmsv1/blob/b8627a2c443760d9b77fad30d6fc6eac76b41714/n8n_workflows/gen_quiz.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