Overview
All RSVP responses are stored in a Google Sheet identified by the SHEET_ID constant in google-apps-script.js. Within that spreadsheet, every submission is written as a new row in the RSVP_responses tab.
No database, no third-party storage service — the sheet acts as the persistent store and is directly accessible from any Google account with edit access.
Each time the Apps Script is re-deployed as a Web App, Google generates a new deployment URL. After re-deploying, update the url value in script.js (the AJAX call in submitForm()) to point to the new URL, otherwise form submissions will stop working.
Sheet structure
Sheet name: RSVP_responses
The sheet is created automatically by initializeSheet() if it does not already exist. Row 1 is the frozen header row; data begins at row 2.
Columns
| # | Column | Header | Description |
|---|
| A | 1 | Timestamp | Submission time in UTC+8, ISO format with T replaced by a space |
| B | 2 | name | Full name of the guest |
| C | 3 | relation | Relationship to the couple |
| D | 4 | attendance | Whether the guest is attending (yes / no) |
| E | 5 | guests | Total number of guests in the party |
| F | 6 | dietary | Dietary preference ("" / 1 / 2) |
| G | 7 | vegetarian-meals | Number of vegetarian meals required |
| H | 8 | children-seats | Whether children’s high chairs are needed (yes / no) |
| I | 9 | children-seats-count | Number of children’s high chairs required |
| J | 10 | invitation | Whether a paper invitation is requested (yes / no) |
| K | 11 | address | Mailing address for the paper invitation |
| L | 12 | message | Message to the couple |
| M | 13 | email | Guest’s email address |
The header row (row 1) is styled for quick visual identification:
- Background colour:
#f3701a (orange)
- Font colour: white
- Font weight: bold
- Frozen: row 1 is frozen so it remains visible when scrolling
- Borders: full borders on all header cells
Data validation rules
initializeSheet() applies dropdown validation to constrain sheet editors to expected values. The table below reflects exactly what the script configures.
| Column | Header | Allowed values | Invalid entries allowed? |
|---|
| D | attendance | yes, no | No — strictly enforced |
| 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 |
Only the attendance column uses setAllowInvalid(false). All other validated columns use setAllowInvalid(true), meaning the dropdown is a guide but does not block non-list values (which can be submitted programmatically by the form).
Timestamps
Every row receives a Timestamp value generated at write time:
var utc8Time = new Date(new Date().getTime() + 8 * 60 * 60 * 1000);
row.push(utc8Time.toISOString().replace('T', ' ').replace('Z', ' UTC+8'));
- Timezone: UTC+8 (Taiwan Standard Time), applied by adding the offset in milliseconds
- Format: ISO 8601 with the
T separator replaced by a space and Z replaced by UTC+8
- Example value:
2025-10-25 17:30:00.000 UTC+8
Getting RSVP statistics
The getRSVPStats() function reads all data rows and returns a summary object:
function getRSVPStats() {
// returns:
return {
total: data.length, // total number of RSVP responses
attending: 0, // count where attendance === 'yes'
notAttending: 0, // count where attendance === 'no'
totalGuests: 0 // sum of guests for all attending responses
};
}
To use it:
Open the Apps Script editor
In your Google Sheet, go to Extensions → Apps Script.
Select getRSVPStats
Choose getRSVPStats from the function dropdown at the top of the editor.
Run the function
Click Run and open the Execution log panel at the bottom of the page.
Read the result
The returned object is printed to the log: total responses, attending count, not-attending count, and total guest headcount.
Working with the sheet
Use Google Sheets’ built-in Filter feature to slice responses by attendance, relation, or date:
- Click any cell in the header row.
- Go to Data → Create a filter.
- Use the filter dropdowns on column D (attendance), C (relation), or A (timestamp) to narrow the view.
You can also use Data → Filter views to save named filters (e.g. “Attending”, “Friends of groom”) without affecting the view for other collaborators.