Build a quiz with instant personalized feedback
Email scored Northwind quiz results with explanations the moment a quiz is submitted.
Published Jul 9, 2025
Northwind’s onboarding quiz runs on a Google Form, which is fine for collecting answers but tells the person who submitted it almost nothing. Google’s built-in quiz mode can show a score, but it cannot explain why an answer was wrong, and chasing that feedback by hand defeats the point of an automated quiz.
This automation closes the loop the moment a quiz is submitted. A form-submit trigger scores the response against an answer key, builds a per-question review with a one-line explanation for each, and emails the result straight to the person who took the quiz. They get a score and the reasoning behind it within seconds, with no marking by anyone.
What you’ll need
- A Google Form quiz whose question titles exactly match the keys in the
ANSWERSobject below — the script looks answers up by question title. - A short-answer or email question titled
Your emailso the script knows where to send the result. - The Form connected to its script (open the Form, choose Script editor from the three-dot menu) so the form-submit trigger can be installed.
The script
ANSWERS is the answer key — one entry per question, each with the correct
answer and a one-line explanation. onFormSubmit runs on every submission.
// The answer key. Each key MUST match a Form question title exactly.
// "correct" is the expected answer; "explain" is the feedback line.
const ANSWERS = {
'Q1: What does .clear() do on a Sheet?': {
correct: 'Clears values',
explain: 'Removes data, keeps formatting.',
},
'Q2: What does CacheService persist?': {
correct: 'Strings for 6 hours',
explain: 'Items are evicted at the TTL or under pressure.',
},
};
// The Form question that collects the respondent's email address.
const EMAIL_QUESTION = 'Your email';
/**
* Runs on every form submission. Scores the response against ANSWERS,
* builds a per-question review, and emails it to the respondent.
*
* @param {Object} e The form-submit event, with e.namedValues.
*/
function onFormSubmit(e) {
let score = 0;
const review = [];
// 1. Check each question in the answer key against what was submitted.
for (const [question, expected] of Object.entries(ANSWERS)) {
const given = e.namedValues[question]?.[0];
const right = given === expected.correct;
if (right) score++;
// Tick or cross, the question, then the explanation underneath.
review.push(`${right ? '✓' : '✗'} ${question}\n ${expected.explain}`);
}
// 2. Find where to send the result.
const email = e.namedValues[EMAIL_QUESTION]?.[0];
if (!email) {
Logger.log('No email address on this submission — cannot send feedback.');
return;
}
// 3. Email the score and the per-question review.
const total = Object.keys(ANSWERS).length;
GmailApp.sendEmail(
email,
`Quiz: ${score} / ${total}`,
review.join('\n\n')
);
}
How it works
onFormSubmitruns automatically each time the quiz is submitted. Apps Script passes the answers ine.namedValues, keyed by question title.- The script loops over every entry in
ANSWERS. For each question it reads the submitted answer withe.namedValues[question]?.[0]— the?.keeps it safe if a question was left blank. - It compares the submitted answer to
expected.correct. A match adds one toscore. - For every question it pushes a review line — a tick or cross, the question, and the explanation indented underneath — so the feedback is the same whether the answer was right or wrong.
- It reads the respondent’s email from the
Your emailquestion. If there is no address, it logs a message and stops rather than throwing. - It emails the result: the subject carries the score (
3 / 5), and the body is the full review joined with blank lines between questions.
Example run
Someone submits the quiz, answering Q1 correctly and Q2 incorrectly, with the
email [email protected]. They receive:
Subject: Quiz: 1 / 2
✓ Q1: What does .clear() do on a Sheet? Removes data, keeps formatting.
✗ Q2: What does CacheService persist? Items are evicted at the TTL or under pressure.
They see their score and, for the question they missed, the explanation that tells them what the right answer involved — all within a few seconds of clicking submit.
Trigger it
The script must run on every submission, so install a form-submit trigger:
- In the Apps Script editor, open Triggers (the clock icon).
- Click Add trigger.
- Choose function
onFormSubmit, event source From form, event type On form submit. - Save and approve the authorisation prompt.
Submit a test response to confirm the email arrives and the score is right.
Watch out for
- Question titles must match exactly. The keys in
ANSWERSare looked up againste.namedValuesverbatim. A trailing space or a renamed question breaks the match silently — that question simply scores zero. - Answer matching is exact and case-sensitive.
Clears valueswill not matchclears values. For multiple-choice questions this is fine; for short-answer questions, normalise both sides before comparing. - One email per submission counts against your Gmail quota. Consumer accounts send roughly 100 mails a day, Workspace accounts around 1,500. A busy quiz day can approach the consumer limit.
- Use the trigger event, not
getResponses(). Reading responses on a timer risks emailing the same person twice. The form-submit trigger fires once per submission, which is exactly what you want. - The trigger runs as you. Every feedback email is sent from your account and shows your address as the sender. Set a friendly reply-to or alias if that matters.
Related
Trigger an onboarding sequence on form submit
Kick off tasks when a new Northwind hire submits their starter form.
Updated Oct 17, 2025
Build a content-submission queue
Collect Northwind guest posts or ideas for review through a Form.
Updated Oct 9, 2025
Score sentiment in open-text feedback
Rate Northwind feedback comments without manual review — using the in-Sheet sentiment function.
Updated Oct 5, 2025
Build a peer-nomination and voting system
Collect and tally Northwind nominations for awards or initiatives — one ballot, anonymous.
Updated Oct 1, 2025
Roll a form over each cycle
Archive old responses and reset for the next Northwind cycle — quarterly OKR check-ins.
Updated Sep 27, 2025