TUTORIAL 3
๐ŸŽ…

Naughty or Nice Calculator

Build a holiday quiz that scores kids' answers to determine if they're on Santa's Nice List, then uses AI to generate a personalized certificate message.

Video thumbnail
Watch the Walkthrough

Workflow Overview

Form
Anthropic
Code
Results

This workflow uses n8n's Form Trigger to collect quiz responses, sends them to Claude AI for scoring and personalized message generation, parses the JSON response, then displays results on a completion screen.

📋

Step-by-Step Guide

1

Create the Form Trigger

Add a Form Trigger node. Set the title to "Naughty or Nice Calculator" and add 9 form fields: Name (text), Age (number), Email, and 6 multiple-choice questions about sharing, helping, and kindness. Set Respond When to Workflow Finishes โ€” this is critical!

2

Add the Anthropic Node

Connect an Anthropic node. Use claude-3-haiku for speed. The prompt includes scoring rules (A=2pts, B=1pt, C=0pts), category thresholds, and instructions to return JSON with name, score, category, and a personalized message.

3

Add the Code Node

Add a Code node to parse the AI response. The AI returns JSON as text โ€” JSON.parse() converts it to a real object so we can access $json.name, $json.score, etc.

4

Add the Form Completion Node

Add an n8n Form node set to "Completion Screen". Display the results using expressions: {{ $json.name }}, {{ $json.category }}, {{ $json.score }}, and {{ $json.message }}.

5

Test Your Workflow

Click the Test URL in your Form Trigger, fill out the quiz, and submit. Watch the workflow execute and see your personalized certificate appear!

💻

The Code

return JSON.parse($input.first().json.content[0].text);
You are Santa's helper reviewing a child's "Naughty or Nice" quiz.

Here are their answers:

Name: {{ $json['Q1: What is your First Name?'] }}
Age: {{ $json['Q2: How old are you?'] }}

Q4 - Dropped snack: {{ $json['Q4: You see someone drop their snack on the floor. What do you do?'] }}
Q5 - Clean up toys: {{ $json['Q5: It's time to clean up toys. What's your move?'] }}
Q6 - Sharing: {{ $json['Q6: Someone wants a turn with something you're using. What do you do?'] }}
Q7 - Bump into someone: {{ $json['Q7: You accidentally bump into someone. What happens next?'] }}
Q8 - Chore: {{ $json['Q8: You're asked to help with a small chore. What do you do?'] }}
Q9 - Someone alone: {{ $json['Q9: You see someone sitting alone. What do you do?'] }}

Scoring rules:
- Answers starting with "A" = 2 points (nicest)
- Answers starting with "B" = 1 point (okay)
- Answers starting with "C" = 0 points (naughty)

Calculate their total score out of 12, then determine their category:
- 10-12: "Officially on the Nice List ๐ŸŒŸ"
- 6-9: "Nice List (with a few warnings) โœ…"
- 3-5: "On the Fence ๐Ÿค”"
- 0-2: "Coal is looking likely ๐Ÿ˜…"

Double-check your math before responding.

Respond with ONLY valid JSON in this exact format, no markdown:
{
  "name": "their name",
  "score": number,
  "maxScore": 12,
  "category": "their category with emoji",
  "message": "A fun, encouraging 2-3 sentence personalized message for the child. Keep it warm and playful, even for low scores. Mention something specific Santa's elves noticed about their answers."
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Your Nice List Certificate!</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body {
      font-family: Arial, sans-serif;
      background: linear-gradient(180deg, #0c1445 0%, #1a237e 100%);
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 20px;
    }
    .certificate {
      background: linear-gradient(135deg, #fef9f0 0%, #fff 100%);
      border-radius: 20px;
      padding: 40px;
      max-width: 500px;
      text-align: center;
      box-shadow: 0 20px 60px rgba(0,0,0,0.3), 0 0 0 4px #c41e3a, 0 0 0 8px #165b33;
    }
    .emoji { font-size: 60px; margin-bottom: 10px; }
    h1 { font-size: 24px; color: #165b33; margin-bottom: 10px; }
    .name { font-size: 36px; color: #c41e3a; margin: 15px 0; }
    .category { font-size: 22px; font-weight: bold; color: #165b33; margin: 15px 0; }
    .score { background: #165b33; color: white; padding: 10px 25px; border-radius: 20px; display: inline-block; margin: 15px 0; font-size: 18px; }
    .message { font-size: 16px; line-height: 1.6; color: #333; padding: 20px; background: #f8f8f8; border-radius: 12px; border-left: 4px solid #c41e3a; margin: 20px 0; text-align: left; }
    .footer { margin-top: 20px; font-size: 14px; color: #666; }
  </style>
</head>
<body>
  <div class="certificate">
    <div class="emoji">๐ŸŽ…</div>
    <h1>Official Nice List Certificate</h1>
    <p>This certifies that</p>
    <div class="name">{{ $json.name }}</div>
    <div class="category">{{ $json.category }}</div>
    <div class="score">Score: {{ $json.score }} / {{ $json.maxScore }}</div>
    <div class="message">{{ $json.message }}</div>
    <div class="footer">๐ŸŽ„ Verified by Santa's Workshop ๐ŸŽ„<br>December 2025</div>
  </div>
</body>
</html>
💡

Key Concepts

๐Ÿ“ Form Triggers

n8n's built-in forms collect user input without needing external tools. Perfect for quizzes, surveys, and intake forms.

๐Ÿค– AI Integration

LLMs like Claude can score responses, make decisions, and generate personalized content โ€” all in one node.

๐Ÿ”„ JSON Parsing

JSON.parse() converts text that looks like JSON into a real object n8n can work with.

โœ๏ธ Prompt Engineering

Clear instructions + explicit output format = predictable AI responses. Always specify the exact JSON structure you need.

๐ŸŽฏ Dynamic Responses

Combine form data with AI to create personalized experiences that feel magical to users.

You've completed this walkthrough!

Explore more holiday automations to level up your n8n skills.

Back to All Walkthroughs