- Published on
Trigger a Cloudflare Worker from Google Form Submit (2025 Guide)
- Authors
- Name
- Ahmed Farid
- @
TIP
Google Forms still lacks native webhooks, but Apps Script can bridge the gap in 20 lines.
We’ll:
- Attach an Apps Script trigger to a Form.
- Send JSON payload to a Cloudflare Worker endpoint.
- Process the data—e.g., queue in KV, send Telegram, etc.
Total cost: $0.
Table of Contents
- Table of Contents
- 1. Prerequisites
- 2. Create the Cloudflare Worker Endpoint
- 3. Prepare the Google Form
- 4. Apps Script Webhook
- 5. Test End-to-End
- 6. Common Extensions
- 7. Security & Limits
- 8. Conclusion
1. Prerequisites
- Google account with Forms & Apps Script access.
- Cloudflare account with Workers (free plan).
2. Create the Cloudflare Worker Endpoint
2.1 Scaffold
npm create cloudflare@latest form-hook
cd form-hook
Choose TypeScript.
src/index.ts
)
2.2 Worker Code (export interface Env {
STORE: KVNamespace
}
export default {
async fetch(req: Request, env: Env, ctx: ExecutionContext) {
if (req.method !== 'POST') return new Response('Method Not Allowed', { status: 405 })
const body = await req.json()
// Example: save latest response to KV
await env.STORE.put(`resp:${Date.now()}`, JSON.stringify(body))
return new Response('ok')
},
}
Add KV in wrangler.toml
:
[[kv_namespaces]]
binding = "STORE"
id = "<id>"
preview_id = "<preview_id>"
Deploy:
wrangler deploy --minify
Note the URL https://form-hook.<sub>.workers.dev
.
3. Prepare the Google Form
- Create Form → Settings → Responses → Enable.
- Click Script Editor.
4. Apps Script Webhook
Replace default Code.gs
:
const WORKER_URL = 'https://form-hook.<sub>.workers.dev'
function onFormSubmit(e) {
const responses = e.response.getItemResponses().map((r) => ({
question: r.getItem().getTitle(),
answer: r.getResponse(),
}))
const payload = JSON.stringify({
formTitle: FormApp.getActiveForm().getTitle(),
timestamp: new Date().toISOString(),
responses,
})
UrlFetchApp.fetch(WORKER_URL, {
method: 'post',
contentType: 'application/json',
payload,
muteHttpExceptions: true,
})
}
function setupTrigger() {
ScriptApp.newTrigger('onFormSubmit').forForm(FormApp.getActiveForm()).onFormSubmit().create()
}
Run setupTrigger
once → authorize.
5. Test End-to-End
Submit the form → kv:namespace list | head
should show new key.
6. Common Extensions
- Validate reCAPTCHA in Worker.
- Forward to Zapier or Slack.
- Store in R2 as CSV.
7. Security & Limits
- Apps Script daily quota: 20k requests (free).
- Add secret token header and verify in Worker.
if (req.headers.get('x-hook') !== env.SECRET) return new Response('unauth', { status: 403 })
Store SECRET
with wrangler secret
and set in UrlFetchApp
headers.
8. Conclusion
With a tiny Apps Script and Cloudflare Worker, you’ve built a serverless pipeline reacting to Google Form submissions—scalable, free, and maintainable. 🎉