Overview
Google Apps Script is a cloud-based JavaScript platform that runs on Google’s servers. The wedding RSVP site uses it as a zero-cost backend — no server to provision, no hosting fees — that receives form submissions, writes rows to a Google Sheet, and dispatches email notifications via Gmail. Key reasons it was chosen:- Free — runs entirely within the Google Workspace quota
- No server required — deployed as a Web App, accessible via a public HTTPS URL
- Native Google Sheets integration —
SpreadsheetAppreads and writes directly to the spreadsheet - Native Gmail integration —
GmailAppsends confirmation and admin emails without any SMTP configuration
Constants
| Constant | Value | Purpose |
|---|---|---|
SHEET_NAME | "RSVP_responses" | The tab name inside the Google Sheet |
SHEET_ID | (your sheet ID) | Identifies which Google Sheet to open |
Functions
doGet(e)
Handles HTTP GET requests sent to the Web App URL. Returns a JSON test response that confirms the script is live and reachable.
Timestamps throughout the script are expressed in UTC+8 (Taiwan Standard Time). The offset is applied manually by adding
8 * 60 * 60 * 1000 milliseconds to the current UTC time before formatting.doPost(request)
The HTTP entry point for RSVP form submissions. Every POST from the frontend is routed here and immediately delegated to handleRequest.
doPost thin makes the script easier to unit-test and extend: swap out handleRequest without touching the Web App entry point.
handleRequest(request)
The core function. It acquires a concurrency lock, writes the submission to the sheet, triggers email notifications, and returns a JSON result.
LockService.getPublicLock() creates a lock shared across all simultaneous executions of the script. waitLock(30000) blocks the current invocation for up to 30 seconds until the lock is free. This prevents two concurrent submissions from writing to the same row. The lock is always released in the finally block.
setup()
A one-time initialisation function. Run it once from the Apps Script editor after pasting the script and setting SHEET_ID.
Paste the script
Replace the default
myFunction content with the full google-apps-script.js file content.initializeSheet()
Called by setup(). Creates the RSVP_responses sheet tab if it does not exist, writes the header row if missing, and applies column widths and data validation rules.
Column widths set by initializeSheet()
| Column | Header | Width (px) |
|---|---|---|
| A | Timestamp | 150 |
| B | name | 200 |
| C | relation | 150 |
| D | attendance | 120 |
| E | guests | 100 |
| F | dietary | 150 |
| G | vegetarian-meals | 150 |
| H | children-seats | 150 |
| I | children-seats-count | 150 |
| J | invitation | 150 |
| K | address | 300 |
| L | message | 300 |
| M | 200 |
| Column | Allowed values | Invalid allowed? |
|---|---|---|
| D — attendance | yes, no | No |
| E — guests | 1, 2, 3, 4, 5 | Yes |
| C — relation | friends-groom, friends-bride, other | Yes |
| F — dietary | "", 1, 2 | Yes |
| G — vegetarian-meals | "", 1, 2, 3, 4, 5 | Yes |
| H — children-seats | yes, no | Yes |
| I — children-seats-count | "", 1, 2, 3, 4, 5 | Yes |
| J — invitation | yes, no | Yes |
attendance (column D) uses setAllowInvalid(false) — all other columns permit values outside the dropdown list.
getRSVPStats()
Returns a summary of RSVP responses. Run it manually from the Apps Script editor to get a quick count.
getRSVPStats from the function dropdown, click Run, and inspect the execution log.
testSetup()
A convenience test function. It verifies sheet access and sends a test email with dummy data.
testSetup() from the Apps Script editor after initial setup to confirm everything is wired correctly. Check the execution log for pass/fail messages and verify that a test email arrives at the admin address.
POST request parameters
The frontend serialises the RSVP form and POSTs it to the Web App URL. All fields are sent asapplication/x-www-form-urlencoded string values.
Full name of the guest submitting the RSVP.
Relationship to the couple. One of:
friends-groom, friends-bride, other. Optional — not required by client-side validation.Whether the guest is attending. One of:
yes, no.Total number of guests in the party. Possible values:
0, 1, 2, 3, 4, 5, 6, 7, 99 (where 99 represents 8 or more guests — the “乾爹包桌” option).Dietary preference. One of:
"" (regular), 1 (vegetarian), 2 (fasting).Number of vegetarian meals needed. Required when
dietary is 1. One of: 1, 2, 3.Whether children’s high chairs are needed. One of:
yes, no.Number of children’s high chairs needed. Required when
children-seats is yes. One of: 1, 2, 3.Whether a physical paper invitation is requested. One of:
yes, no.Mailing address for the paper invitation. Required when
invitation is yes.Optional message to the couple.
Guest’s email address. If provided, a confirmation email is sent to this address.
Response fields
"success" on a successful write, "error" if an exception was caught.Human-readable status message. Present on success responses.
Error message from the caught exception. Present only when
result is "error".