appscript.dev
Automation Beginner Forms Gmail

Send branded confirmation emails on submission

Reply to every Northwind form submitter with a styled receipt — no more raw Google receipts.

Published Jul 1, 2025

Google’s own “send a copy of your response” option is functional, ugly, and unmistakably a Google receipt — which is exactly the wrong first impression for a Northwind enquiry. Clients sometimes assume the auto-reply is the actual reply and either chase too soon or write the studio off as unresponsive.

This script replaces the default receipt with a short, branded confirmation. On every submission it picks up the submitter’s email, sends them a plain-but-styled HTML message from Northwind Studios, and sets expectations on when they will hear back. Friendly, on-brand, and one less manual reply for the studio inbox.

What you’ll need

  • A Google Form with two short-answer questions named exactly Your name and Your email. The script tolerates either being blank, but the email is what makes the reply possible.
  • The form linked to its Apps Script project (Extensions -> Apps Script from the form editor).
  • A Gmail account whose name and signature you are happy to present to the outside world — the email goes out from your address.

The script

// The sender name shown in the recipient's inbox. Keep it short — many
// clients truncate after about 25 characters on mobile.
const SENDER_NAME = 'Northwind Studios';

// Subject line for the confirmation. Punchy beats clever — the goal is
// "your message arrived", not "open me for a surprise".
const SUBJECT = 'We got it — Northwind';

// How long Northwind promises to reply in. Adjust to the studio's
// actual turnaround so the confirmation does not over-promise.
const RESPONSE_SLA = 'one working day';

// The form questions we read. Single source of truth so renaming a
// question is a one-line change here, not a hunt through the body.
const NAME_FIELD = 'Your name';
const EMAIL_FIELD = 'Your email';

/**
 * Runs on every form submission. Sends a styled HTML confirmation to
 * the submitter so they know the message landed, without relying on
 * Google's default receipt template.
 *
 * @param {GoogleAppsScript.Events.FormsOnFormSubmit} e Form submit event.
 */
function onFormSubmit(e) {
  // 1. Read the email. If the form was submitted without one, there is
  //    nothing to do — skip silently, do not crash the trigger.
  const email = (e.namedValues[EMAIL_FIELD] && e.namedValues[EMAIL_FIELD][0]) || '';
  if (!email) {
    Logger.log('No email on submission — skipping confirmation.');
    return;
  }

  // 2. Read the name, falling back to a friendly default. Forms is happy
  //    to leave optional fields blank.
  const name = (e.namedValues[NAME_FIELD] && e.namedValues[NAME_FIELD][0]) || 'there';

  // 3. Build the HTML body inline. Keep the markup minimal — most email
  //    clients strip CSS, so a few <p> tags travel further than fancy
  //    layout. Escape the name to avoid stray angle brackets breaking
  //    the markup.
  const safeName = escapeHtml(name);
  const html =
    `<p>Hi ${safeName},</p>` +
    `<p>Thanks — we received your submission. We aim to reply within ${RESPONSE_SLA}.</p>` +
    `<p>— ${SENDER_NAME}</p>`;

  // 4. Send. Pass an empty plain-text body and an htmlBody — Gmail will
  //    auto-generate a plain text part from the HTML for accessibility.
  GmailApp.sendEmail(email, SUBJECT, '', {
    htmlBody: html,
    name: SENDER_NAME,
  });
  Logger.log('Confirmation sent to ' + email);
}

/**
 * Minimal HTML escape so a name like "Ellis <test>" does not leak angle
 * brackets into the email body.
 */
function escapeHtml(s) {
  return String(s)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;');
}

How it works

  1. onFormSubmit fires for every submission, with the answers under e.namedValues keyed by question title.
  2. It reads the email field first and bails out if it is empty — there is no one to send to, so logging and returning is the right move.
  3. It reads the name, defaulting to there so an anonymous form still produces a natural greeting (“Hi there,”).
  4. It escapes the name through escapeHtml before interpolating it into the markup. That stops a stray < in a real name from breaking the email or opening a tiny XSS hole.
  5. It builds an HTML body with three short paragraphs — greeting, confirmation with the SLA, signature — and hands it to GmailApp.sendEmail. The empty string as the third argument is the plain-text body; passing htmlBody in the options lets Gmail generate a plain part automatically.
  6. The name option overrides the sender’s display name for this message only, so the email shows up as from Northwind Studios rather than the account holder’s personal name.

Example run

A client submits the enquiry form with:

FieldValue
Your nameMaya Okafor
Your email[email protected]

Within a few seconds, Maya receives:

From: Northwind Studios Subject: We got it — Northwind

Hi Maya Okafor,

Thanks — we received your submission. We aim to reply within one working day.

— Northwind Studios

The Apps Script log records Confirmation sent to [email protected].

Trigger it

Wire the script to the form’s submit event:

  1. From the bound Apps Script project, open Triggers.
  2. Add a trigger for onFormSubmit, event source From form, type On form submit.
  3. Approve the Gmail scope on the first run, then submit a test response with an address you can check.

Watch out for

  • The email goes from the script owner’s Gmail address — replies land in that inbox. If the studio uses a shared inbox, install the script under that account, or use GmailApp.sendEmail with an alias the account is allowed to send from.
  • Gmail’s daily send quota is per account and modest on consumer accounts (around 100 emails per day). A busy form on a free account will hit the cap; Workspace accounts have a much higher allowance.
  • Heavy CSS rarely survives email clients. Stick to inline styles on simple tags if you want colour or spacing — and test in Gmail mobile, Outlook web, and Apple Mail before declaring it done.
  • The script trusts the form to provide a valid email. If the field type is set to short-answer rather than the dedicated email type, you may send confirmations into the void — switch the question to “email” so Forms validates the format for you.

Related