Google Forms to Slack Apps Script Generator
Paste a Slack incoming-webhook URL. Get a copy-paste Google Apps Script that POSTs every Google Form response to your Slack webhook with Block Kit formatting. No sign-up. Everything runs in your browser — your webhook URL never touches our servers.
Build your Apps Script
Paste a webhook URL. Slack incoming webhook, RouteForms, or any HTTPS endpoint. The script regenerates as you type.
Tip: a Slack incoming webhook gets a nicely-formatted message. Any HTTPS endpoint works too.
Override the form title shown in the payload. Leave blank to use the Google Form's own title.
Style picker is Slack-only. Generic webhooks always get flat JSON.
Leave blank to send every response. With a field + value, the script only POSTs to the main webhook when that field matches (case-insensitive).
Only used when a condition is set. If the condition doesn't match, the response posts to this fallback URL instead of being skipped. Also masked on blur.
// Google Forms → Webhook bridge
//
// Generated by https://routeforms.com/tools/google-forms-to-slack-generator
//
// Install (90 seconds):
// 1. In your Google Form, click the three-dot menu → Apps Script.
// 2. Replace the existing function myFunction() {} with the contents of
// this file, then save (Cmd+S).
// 3. In the function dropdown at the top of the editor, select
// installFormBridge and click Run.
// 4. When Google asks, click Advanced → Go to ... (unsafe) → Allow.
// (You're authorising your own script, read it first if you'd like.)
// 5. Submit a test response in your Google Form to verify end-to-end.
const WEBHOOK_URL = "PASTE_YOUR_WEBHOOK_URL_HERE";
const TEST_MODE = false;
function installFormBridge() {
var form = FormApp.getActiveForm();
if (!form) {
throw new Error(
"No active form. Open this script editor from inside your Google Form: " +
"Form → three-dot menu → Apps Script."
);
}
// Wipe any existing onFormSubmit trigger so re-running install is safe.
var existing = ScriptApp.getProjectTriggers();
for (var i = 0; i < existing.length; i++) {
if (existing[i].getHandlerFunction() === "onFormSubmit") {
ScriptApp.deleteTrigger(existing[i]);
}
}
// Create the correct form-submit trigger automatically so you can't pick
// "On open" by mistake.
ScriptApp.newTrigger("onFormSubmit").forForm(form).onFormSubmit().create();
Logger.log("\u2713 Form bridge installed. Submit a test response to verify.");
}
function collectFields(e) {
var form = FormApp.getActiveForm();
var response = e.response;
var itemResponses = response.getItemResponses();
var data = {};
for (var i = 0; i < itemResponses.length; i++) {
var ir = itemResponses[i];
var title = ir.getItem().getTitle();
var answer = ir.getResponse();
// Google Forms checkbox responses arrive as arrays; collapse to a string.
if (Array.isArray(answer)) answer = answer.join(", ");
data[title] = answer;
}
data._meta = {
formTitle: form.getTitle(),
formId: form.getId(),
responseId: response.getId ? response.getId() : null,
submittedAt: new Date().toISOString(),
};
return data;
}
function onFormSubmit(e) {
try {
var data = collectFields(e);
var payload = data;
var destinationUrl = WEBHOOK_URL;
if (TEST_MODE) {
Logger.log("TEST MODE \u2014 would have POSTed to " + destinationUrl + ":");
Logger.log(JSON.stringify(payload, null, 2));
return;
}
var res = UrlFetchApp.fetch(destinationUrl, {
method: "post",
contentType: "application/json",
payload: JSON.stringify(payload),
muteHttpExceptions: true
});
var code = res.getResponseCode();
if (code < 200 || code >= 300) {
Logger.log("Slack returned " + code + ": " + res.getContentText());
}
} catch (err) {
Logger.log("Form bridge error: " + err);
}
}
Paste a webhook URL above to enable Copy and Download.
Install it into your Google Form in 90 seconds
Whatever webhook URL you used, the install procedure is the same.
- 1Open the Apps Script editor inside your Google FormIn your Google Form, click the three-dot menu (top-right) → Apps Script. A new tab opens with a blank script template.
- 2Replace the placeholder with your generated scriptDelete the existing
function myFunction()block. Paste the generated script above. Save with⌘S. - 3Run installFormBridge onceAt the top of the editor, choose
installFormBridgefrom the function dropdown and click Run. This creates the form-submit trigger so you can't accidentally pick “On open”. - 4Authorise when Google asksClick Advanced → Go to ... (unsafe) → Allow. The warning shows because the script is unverified, it's yours, and you can read every line before running it.
- 5Submit a test responseOpen your Google Form and fill it in. If TEST_MODE is on, check the Apps Script Executions log to see the payload. If TEST_MODE is off, check the destination. Slack channel, your endpoint logs, whatever.
What the generated script actually does
The script defines two functions that Apps Script will call. There's no hidden logic and no outbound calls except the one POST to your webhook URL.
installFormBridge(), runs once when you click Run. Deletes any existingonFormSubmittrigger and creates a fresh one wired to the correct form-submit event. Re-running it is safe (idempotent on triggers).onFormSubmit(e), fires automatically on every form submission. Reads everyitemResponsesentry, collapses checkbox arrays into comma-joined strings, attaches a_metaobject (form title, form ID, response ID, ISO timestamp), and either POSTs to the webhook or logs the payload depending onTEST_MODE.- If you pasted a Slack incoming webhook, there's also a
buildSlackPayload(data)helper that wraps the fields in Slack Block Kit blocks (an inbox-tray header section, a meta section with form title and submission time, a divider, and the field list).
And when you should use RouteForms instead
This generator is honest about its job: it turns a Google Form into a one-channel firehose. That's often exactly what you want. For everything else, the script alone won't cut it.
- You want different responses in different Slack channels.The script points at a single URL. RouteForms adds rule-based routing: IF Budget ≥ 50000 send to #hot-leads, IF City = Austin send to #austin-team. See routing recipes.
- You want retries when Slack rejects a delivery.Apps Script doesn't know that Slack returned 429. RouteForms records every Slack response, lets you retry from the dashboard, and (on paid plans) emails you when a streak of failures starts.
- You want a delivery log a client can read.The Apps Script Executions log is engineer-only. RouteForms gives you a per-form delivery log with the destination, the matched rule, and Slack's HTTP response, readable, filterable, exportable.
- You want idempotent retries.Apps Script's UrlFetchApp can retry on transient errors. Without dedupe, a retry becomes two Slack posts. RouteForms enforces a partial unique index on the response ID at the database level, so no retry path can double-post.
Frequently asked questions
What does this tool do?▾
It generates a Google Apps Script you paste into your Google Form's script editor. When someone submits the form, the script collects every field and posts the data to a webhook URL you provide. If you paste a Slack incoming webhook URL, the script formats the message with Slack Block Kit so it looks clean in the channel.
Do I need to sign up to use this?▾
No. The generator runs entirely in your browser, your webhook URL and form name never touch our servers. Copy the script, paste it into your Google Form, and you're done.
Will this work with my existing Slack incoming webhook?▾
Yes. The generator detects hooks.slack.com URLs and emits Slack-formatted Block Kit messages (with the submission timestamp, form title, and each field as a labelled line). Any other HTTPS URL gets a generic JSON payload.
What is TEST MODE?▾
Test mode swaps the live POST for an Apps Script Logger.log call. Submit a test response to your form, then check the Apps Script Executions log to see exactly what the payload would have looked like. Turn TEST_MODE off in the script when you're ready to deliver for real.
Why does the generated script need authorisation?▾
Apps Script needs your permission to read form responses and make outbound HTTPS requests. Google warns you the first time because the script is unverified (it's your script, you can read every line). The script does not access anything outside the form it's attached to.
What if I want routing, retries, or a delivery log?▾
This generator gives you a one-channel firehose. RouteForms (the paid product behind this tool) adds conditional routing rules per form field, idempotent retries on transient failures, a per-form delivery log with the Slack HTTP response, and email alerts when delivery fails. Free plan covers 30 responses a month.
Can I use this with non-Slack webhooks like Discord or a custom server?▾
Yes. When you paste a non-Slack URL, the generator emits a plain JSON payload, keys are the form question titles, values are the responses, plus a _meta object with form ID, response ID, and timestamp. Any endpoint that accepts application/json will work.
What does the _meta field contain?▾
_meta includes formTitle, formId, responseId (Google Forms's response ID, useful for deduplication), and submittedAt (ISO timestamp). Keep responseId if you plan to retry-safe, using it as a dedupe key prevents Apps Script's own retries from creating duplicates downstream.
Need routing, retries, and a delivery log?
The free generator gets you to one channel. RouteForms takes you the rest of the way, free for 30 responses a month.
Keep reading
What RouteForms does on top of the script, what each plan unlocks, and the two-minute setup walkthrough.
Recipes for routing to different channels based on dropdowns, scales, free text, file uploads, and numeric answers.
If you're already on Zapier for this hop, here's the 5-minute migration path.
Other small utilities for people building Google Forms ↔ Slack pipelines.
All the real options for this hop. RouteForms, SlackQ, Form Director, Zapier, Make, Apps Script, raw webhooks, ranked by fit.