RSVP → Google Sheets setup
Integration status
Checking…
1. Create the script
Go to script.google.com → New project. Replace the contents of Code.gs with the code below and save.
2. Authorize & create the spreadsheet
Choose the
setupfunction in the toolbar and click Run. Approve the Google permissions (Advanced → Go to project if warned). This automatically creates the “Haider & Munira — RSVPs” spreadsheet in your Drive. Open the Execution log to see its link and a TOKEN.3. Deploy as web app
Deploy → New deployment → type Web app. Execute as: Me. Who has access: Anyone. Deploy and copy the URL ending in
/exec.4. Configure the endpoint
In chat, ask to add the secrets
RSVP_ENDPOINT_URL(the /exec URL) andRSVP_SHARED_SECRET(the TOKEN from the log). They are stored privately on the server — never shown on the page.5. Test
Click “Send test RSVP” above. Only once it succeeds is the integration live. You can delete the TEST row afterwards.
Apps Script code
// Haider & Munira — RSVP receiver (Google Apps Script)
const SHEET_NAME = 'RSVPs';
const HEADERS = ['Timestamp','Guest Name','Guest Count','Attendance','Events','Message','Source'];
// Run this ONCE from the editor: creates the spreadsheet and stores its ID.
function setup() {
const props = PropertiesService.getScriptProperties();
let id = props.getProperty('SHEET_ID');
if (!id) {
const ss = SpreadsheetApp.create('Haider & Munira — RSVPs');
id = ss.getId();
props.setProperty('SHEET_ID', id);
const sh = ss.getSheets()[0];
sh.setName(SHEET_NAME);
sh.appendRow(HEADERS);
sh.setFrozenRows(1);
sh.getRange(1,1,1,HEADERS.length).setFontWeight('bold').setBackground('#0b4d3b').setFontColor('#f5e6b8');
}
// Optional shared secret — copy this value into the website's RSVP_SHARED_SECRET.
if (!props.getProperty('TOKEN')) props.setProperty('TOKEN', Utilities.getUuid());
Logger.log('Spreadsheet: https://docs.google.com/spreadsheets/d/' + id);
Logger.log('TOKEN: ' + props.getProperty('TOKEN'));
}
// Health check: open the /exec URL in a browser to confirm deployment.
function doGet() {
return json({ ok: true, service: 'haider-munira-rsvp' });
}
function validate(b) {
const name = String(b.name || '').trim();
if (name.length < 2 || name.length > 100) return 'invalid name';
if (b.attendance !== 'attending' && b.attendance !== 'declined') return 'invalid attendance';
const guests = Number(b.guests);
const events = Array.isArray(b.events) ? b.events.filter(function (x) { return x === 'mehendi' || x === 'reception'; }) : [];
if (b.attendance === 'attending') {
if (!(guests >= 1 && guests <= 20 && Math.floor(guests) === guests)) return 'invalid guest count';
if (!events.length) return 'select at least one event';
}
b.name = name; b.events = events;
b.guests = b.attendance === 'attending' ? guests : 0;
b.message = String(b.message || '').slice(0, 500);
return null;
}
// Requests are sent as text/plain (a CORS "simple request"), so browsers need no
// preflight; Apps Script web apps automatically allow cross-origin reads of the JSON.
function doPost(e) {
try {
const props = PropertiesService.getScriptProperties();
const body = JSON.parse(e.postData.contents);
const token = props.getProperty('TOKEN');
if (token && body.token !== token) return json({ ok: false, error: 'unauthorized' });
const err = validate(body);
if (err) return json({ ok: false, error: err });
const ss = SpreadsheetApp.openById(props.getProperty('SHEET_ID'));
const sh = ss.getSheetByName(SHEET_NAME);
const lock = LockService.getScriptLock(); lock.waitLock(10000);
try {
sh.appendRow([new Date(), body.name, body.guests, body.attendance,
body.events.join(', '), body.message, body.test ? 'TEST' : 'website']);
} finally { lock.releaseLock(); }
return json({ ok: true });
} catch (err) {
return json({ ok: false, error: String(err) });
}
}
function json(o) {
return ContentService.createTextOutput(JSON.stringify(o)).setMimeType(ContentService.MimeType.JSON);
}Spreadsheet schema (sheet “RSVPs”)
| Col | Header | Values |
|---|---|---|
| A | Timestamp | Date/time the RSVP was received |
| B | Guest Name | Text, 2–100 chars |
| C | Guest Count | 1–20 if attending, 0 if declined |
| D | Attendance | attending | declined |
| E | Events | mehendi, reception (comma-separated) |
| F | Message | Optional, up to 500 chars |
| G | Source | website | TEST |
Event summary
- Mehendi — Tuesday, 5 January 2027, 4:00 PM onwards
Evane Muffadal Hall, P7, Continental Heights, Rambhau Bhogle Marg, Mazgaon, Mumbai 400010 - Reception — Thursday, 7 January 2027, 7:00 PM onwards
Hatemi Masjid, 4th Floor, Mathar Pakhadi Rd, Thakkar Estate, Mazgaon, Mumbai 400010