- Difficulty:
- beginner
- Tools:
- google-forms, google-sheets, google-apps-script, slack
Problem
A form writes a row and nobody sees it. The team either checks the sheet out of habit or finds out days later that someone was waiting on them.
Trigger
A form submission, through the spreadsheet's on form submit trigger.
Prerequisites
- 01A Google Form whose responses go to a spreadsheet.
- 02An incoming webhook URL from the chat tool.
- 03Permission to authorize a script on the account that owns the form.
Steps
- 01
Open the responses spreadsheet, then Extensions > Apps Script google-apps-script
- 02
Paste the script and save google-apps-script
- 03
Add SLACK_WEBHOOK_URL under Project Settings > Script properties slack
Script properties keep the webhook out of the code and out of version control.
- 04
Add the trigger google-apps-script
Triggers > Add trigger > function onFormSubmit > event source From spreadsheet > event type On form submit. Authorize when prompted.
- 05
Submit the form once as a test google-forms
Executions in the Apps Script sidebar shows the run and any error.
Payload · javascript
/**
* Google Apps Script, bound to the form's responses spreadsheet.
* Extensions > Apps Script, paste this, then add a trigger:
* Triggers > Add trigger > onFormSubmit > From spreadsheet > On form submit.
* Put the webhook in Project Settings > Script properties as SLACK_WEBHOOK_URL.
*/
function onFormSubmit(e) {
const webhook = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK_URL');
if (!webhook) throw new Error('Script property SLACK_WEBHOOK_URL is not set');
const answers = e.namedValues;
const lines = Object.keys(answers)
.filter(function (question) { return String(answers[question]).trim() !== ''; })
.map(function (question) { return '*' + question + '*: ' + answers[question]; });
const body = {
text: 'New form response',
blocks: [{ type: 'section', text: { type: 'mrkdwn', text: lines.join('\n') } }]
};
UrlFetchApp.fetch(webhook, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(body),
muteHttpExceptions: true
});
}Failure modes
- !The trigger is attached to the form instead of the spreadsheet and e.namedValues is empty. It must be From spreadsheet.
- !A long free text answer makes the message unreadable in chat. Post the questions that matter rather than all of them.
- !The webhook is revoked and every run fails quietly. muteHttpExceptions keeps the row from being lost, so check Executions occasionally.
- !Apps Script has daily quotas on UrlFetchApp. A form taking thousands of responses a day needs a different approach.
JSON-LD · HowTo
{
"@context": "https://schema.org",
"@type": "HowTo",
"name": "Post every form response to a chat channel",
"description": "An Apps Script trigger on the responses spreadsheet posts each new form submission to a chat channel as a readable message, so the people who act on it never open the sheet.",
"url": "https://automationsanonymous.com/automations/post-every-form-response-to-chat",
"tool": [
{
"@type": "HowToTool",
"name": "google-forms",
"url": "https://automationsanonymous.com/tools/google-forms"
},
{
"@type": "HowToTool",
"name": "google-sheets",
"url": "https://automationsanonymous.com/tools/google-sheets"
},
{
"@type": "HowToTool",
"name": "google-apps-script",
"url": "https://automationsanonymous.com/tools/google-apps-script"
},
{
"@type": "HowToTool",
"name": "slack",
"url": "https://automationsanonymous.com/tools/slack"
}
],
"step": [
{
"@type": "HowToStep",
"position": 1,
"name": "Open the responses spreadsheet, then Extensions > Apps Script",
"text": "Open the responses spreadsheet, then Extensions > Apps Script",
"url": "https://automationsanonymous.com/tools/google-apps-script"
},
{
"@type": "HowToStep",
"position": 2,
"name": "Paste the script and save",
"text": "Paste the script and save",
"url": "https://automationsanonymous.com/tools/google-apps-script"
},
{
"@type": "HowToStep",
"position": 3,
"name": "Add SLACK_WEBHOOK_URL under Project Settings > Script properties",
"text": "Script properties keep the webhook out of the code and out of version control.",
"url": "https://automationsanonymous.com/tools/slack"
},
{
"@type": "HowToStep",
"position": 4,
"name": "Add the trigger",
"text": "Triggers > Add trigger > function onFormSubmit > event source From spreadsheet > event type On form submit. Authorize when prompted.",
"url": "https://automationsanonymous.com/tools/google-apps-script"
},
{
"@type": "HowToStep",
"position": 5,
"name": "Submit the form once as a test",
"text": "Executions in the Apps Script sidebar shows the run and any error.",
"url": "https://automationsanonymous.com/tools/google-forms"
}
],
"datePublished": "2026-09-05T16:53:37.448Z"
}