Generate a WordPress plugin that syncs forms to Google Sheets
Pushing form submissions straight into a Google Sheet is a surprisingly common ask. Marketing wants to see leads in a spreadsheet without logging into WordPress. Operations wants a live dashboard pivoted off form data. And the developer wants a pattern that does not break the form UX when the Sheets API is slow or throttled.
The cleanest way is a plugin that listens to the form submission hook, serialises the row, and queues it for async write to Sheets. We build this with the Google Sheets REST v4 API and a service account so the shop owner never has to OAuth their own Google account, and the write happens via WP Cron so a slow Sheets call never blocks the visitor.
Why generate it instead of installing an existing plugin?
Zapier and Make can do this in 5 minutes of clicking, but they start at around €20/month and every submission runs through their infrastructure. For a shop that processes hundreds of submissions per day this gets expensive, and privacy-conscious clients prefer the data path to stay between their WordPress and their Google account.
Uncanny Automator and similar WP-native automation plugins also handle it but are licensed per-site and carry lifetime fees once you need any extensibility. If your only use case is "form → sheet", you are buying a Swiss Army knife to open one letter.
A generated plugin shaped around your exact form and your exact sheet headers is about 150 lines of PHP. It fails gracefully when Sheets is down (writes to a local queue, retries), logs errors somewhere reasonable, and never sends the submitter waiting longer because of an external API.
Example prompt
This is the kind of description that generates this plugin. You can start from it and tweak whatever you need before hitting generate.
Plugin name: Acme Form to Sheets
Source: Gravity Forms form ID 3 (contact form).
Destination: Google Sheet ID "1abc...xyz", tab "Leads".
Authentication: service account JSON stored in an option (paste the whole JSON in the settings).
Mapping:
- Column A: submission timestamp (ISO 8601)
- Column B: field "name" (input_1)
- Column C: field "email" (input_2)
- Column D: field "company" (input_3)
- Column E: field "message" (input_4)
- Column F: referrer URL (from $_SERVER['HTTP_REFERER'])
- Column G: user agent
On submission hook gform_after_submission: queue the row in a transient-backed list.
A WP Cron event every 5 minutes reads the queue and appends rows via Sheets API v4 spreadsheets.values.append with valueInputOption=RAW.
On API error: leave the row in the queue; after 5 failed retries (1h, 2h, 4h, 8h, 16h backoff) send admin email with the payload.
Admin: settings page with service account JSON, Sheet ID, tab name, test button ("append a dummy row").
HPOS-agnostic (does not touch WC). No DB tables needed.What the generated plugin typically includes
- Google API client via Composer bundled in vendor/ (or direct wp_remote_post if you prefer zero deps)
- Service account OAuth 2 JWT flow cached in a transient for 50 minutes
- Submission handler hooked to the form plugin's "after save" action
- Async queue using a single option storing an array of pending rows (small volume) or a DB table (high volume)
- WP Cron event draining the queue every 5 minutes with an idempotent write (uses row hash as idempotency key)
- Settings page with a test append button to verify credentials before going live
- Admin notice if the queue grows beyond a threshold (signals broken Sheets auth)
Swap Gravity Forms for Contact Form 7 / WPForms / Fluent Forms / a native WP REST endpoint. Swap Google Sheets for Airtable or Notion. The pattern is the same; the adapter changes.
Frequently asked questions
Does the submitter wait for the Google API call?
No. The submission returns immediately; the row is queued locally and written to Sheets by a background cron. That way slow Sheets responses never leak into the user experience.
What if the Sheets API is down?
The row stays in the local queue and the cron retries on an exponential backoff (1h, 2h, 4h, 8h, 16h). After 5 failures the admin is emailed with the payload so nothing is lost.
Can I map multiple forms to different sheets?
Yes. Describe each form → sheet mapping in the prompt and the admin UI will list them. Each mapping has its own column layout.
What about GDPR?
Only the fields you map get sent to Sheets. The plugin can also strip IP/User Agent by default, and add a suppression list for email addresses that have exercised their erasure rights.