AutomationFlowsWeb Scraping › Gen Quiz

Gen Quiz

Gen Quiz. Uses httpRequest. Webhook trigger; 6 nodes.

Webhook trigger★★★★☆ complexity6 nodesHTTP Request
Web Scraping Trigger: Webhook Nodes: 6 Complexity: ★★★★☆ Added:

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 →

Download .json
{
  "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
          }
        ]
      ]
    }
  }
}
Pro

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 →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

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

n8n, Execute Workflow Trigger, HTTP Request +1
Web Scraping

This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .

HTTP Request, Ssh
Web Scraping

eek-Go v2 (Batch-Then-Review). Uses httpRequest. Webhook trigger; 75 nodes.

HTTP Request
Web Scraping

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

HTTP Request
Web Scraping

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

HTTP Request