Recipes / Recipe 3

Send an email automatically when a Google Form is submitted

Get every response in your inbox (with Reply going straight to the customer) and send respondents an instant confirmation.

Apps ScriptFormsEmail Setup time: 10 minutes

You'll need: A Google Form linked to a response spreadsheet (Form → Responses → Link to Sheets).

Steps

  1. Open the response spreadsheet (not the form), then Extensions → Apps Script.
  2. Paste the script and set notifyTo to your address.
  3. Set emailQuestion and nameQuestion to the exact question titles in your form (e.g. “Email address”). If your form collects emails automatically, use 'Email Address'.
  4. Choose the function installFormTrigger in the toolbar and click Run. Approve the permissions (it needs to send email as you).
  5. Submit a test response. You should get the notification within a minute.
Code.gsApps Script
/**
 * Email yourself (and optionally the respondent) every time a Google Form is submitted.
 * Put this in the spreadsheet that collects the form responses, then run installFormTrigger once.
 */
const FORM_EMAIL_CONFIG = {
  notifyTo: '[email protected]',     // where new submissions go (comma-separate several)
  subjectPrefix: 'New form response',
  emailQuestion: 'Email',          // exact question title that holds the respondent's email
  nameQuestion: 'Name',            // exact question title for their name (optional)
  sendConfirmation: true,          // also send the respondent a "we got it" email
  confirmationSubject: 'Thanks, we received your request',
  confirmationBody: 'Hi {name},\n\nThanks for getting in touch. We received your request and will reply within one business day.\n\nYour answers:\n{answers}\n'
};

/** Run this once from the editor (Run > installFormTrigger) and approve the permissions. */
function installFormTrigger() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const exists = ScriptApp.getProjectTriggers()
    .some((t) => t.getHandlerFunction() === 'onFormSubmitHandler');
  if (exists) return;
  ScriptApp.newTrigger('onFormSubmitHandler').forSpreadsheet(ss).onFormSubmit().create();
}

/** Pure function: turns e.namedValues into readable "Question: answer" lines. */
function formatAnswers(namedValues) {
  return Object.keys(namedValues)
    .filter((q) => q !== 'Timestamp')
    .map((q) => q + ': ' + [].concat(namedValues[q]).join(', '))
    .join('\n');
}

function firstAnswer(namedValues, question) {
  const v = namedValues[question];
  return v ? String([].concat(v)[0]).trim() : '';
}

function onFormSubmitHandler(e) {
  const cfg = FORM_EMAIL_CONFIG;
  const nv = e.namedValues || {};
  const answers = formatAnswers(nv);
  const email = firstAnswer(nv, cfg.emailQuestion);
  const name = firstAnswer(nv, cfg.nameQuestion) || 'there';
  const validEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);

  const notice = {
    to: cfg.notifyTo,
    subject: cfg.subjectPrefix + (name !== 'there' ? ': ' + name : ''),
    body: answers + '\n\nSheet: ' + SpreadsheetApp.getActiveSpreadsheet().getUrl()
  };
  if (validEmail) notice.replyTo = email; // hit Reply to answer the respondent directly
  MailApp.sendEmail(notice);

  if (cfg.sendConfirmation && validEmail) {
    MailApp.sendEmail({
      to: email,
      subject: cfg.confirmationSubject,
      body: cfg.confirmationBody.replace('{name}', name).replace('{answers}', answers)
    });
  }
}

Good to know

Do it yourself

Recipe Club: $12/month

Prefer to set things up yourself? Join the Recipe Club and get access to a private GitHub repository of ready-made, tested automations for Sheets, Apps Script, Python and Node. Each one comes with setup notes and sample data.

  • A new recipe added every week
  • Everything in the free library, plus the longer, more complete versions
  • Use them in your own business as much as you like
  • Cancel anytime by email (or the Stripe customer portal once available)

Recipe Club opens soon: join the waitlist

You'll need a free GitHub account. After checkout, reply with your GitHub username and we'll send the repo invite, usually within one business day.

Or buy a one-time recipe pack ($19–$29)

  • Clean Data Pack $19
    Dedupe, cleaning, merging and normalizing scripts and formulas for messy exports, with a sample sheet.
    Coming soon
  • Forms & Inbox Pack $19
    Form auto-replies, request routing, a lead log and follow-up nudges, ready to paste into Apps Script.
    Coming soon
  • Money Ops Pack $29
    Invoice reminders, a monthly revenue dashboard with QUERY, a receipts log and nightly backups.
    Coming soon

Written with AI assistance. Script logic is unit-tested; formulas follow documented Google Sheets behavior. Always try new automations on a copy of your sheet first.