Google Sheets recipe
Two paths: native Sheets integration (one click) or your own Apps Script web app for full control over columns.
Option A — Native Sheets integration
- Webhooks → Add integration → Google Sheets.
- Authorize. Pick a spreadsheet (or Create new).
- We append a row per submission, with a header row matching your form fields. New fields added later get a new column on next submission.
That's it. No code.
Option B — Apps Script web app
Use this when you want custom columns, formulas, conditional formatting, or routing across sheets.
1. Create the Apps Script
In Google Sheets: Extensions → Apps Script. Replace the default file:
const SECRET = PropertiesService.getScriptProperties().getProperty('FORMSPRING_SECRET');
function doPost(e) {
const raw = e.postData.contents;
const sig = e.parameter['x-formspring-signature'] || '';
const expected = Utilities.computeHmacSha256Signature(raw, SECRET)
.map(b => ('0' + (b & 0xff).toString(16)).slice(-2))
.join('');
if (expected !== sig) {
return ContentService.createTextOutput('unauthorized').setMimeType(ContentService.MimeType.TEXT);
}
const body = JSON.parse(raw);
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Submissions')
|| SpreadsheetApp.getActiveSpreadsheet().insertSheet('Submissions');
const row = [
body.received_at,
body.submission_id,
body.payload.email || '',
body.payload.name || '',
body.payload.message || '',
body.meta?.ip_country || '',
];
sheet.appendRow(row);
return ContentService.createTextOutput('ok');
}
2. Store the secret
In Apps Script: Project Settings → Script Properties → Add property.
Key: FORMSPRING_SECRET. Value: the secret from your webhook.
3. Deploy
Deploy → New deployment → Web app. Execute as: Me. Access: Anyone. Copy the web app URL.
4. Wire it up
In Formspring: Webhooks → Add webhook → Generic. Paste the web app URL.
Apps Script doesn't expose request headers in e.parameter directly — the snippet above expects the signature as a query param. Easier route: configure the webhook URL like https://script.google.com/.../exec?x-formspring-signature=$signature (we don't currently template that). The cleaner approach is a thin proxy (Cloudflare Worker, Lambda) in front that verifies and forwards. Pick your poison.
Notes
- Sheets caps at ~10M cells per spreadsheet. For high-volume forms, rotate sheets monthly or use a database.
- Apps Script web apps have a 6-minute execution limit. A simple append is well under it.
- The native integration handles auth refresh; an Apps Script deployment runs as you and inherits your access.