By Raj

Part of our Google Sheets Automation Expert guides. Need this built for your team? Hire a Google Apps Script developer.

Estimated reading time: 10 minutes

Send Slack Notifications from Google Sheets with Apps Script

Slack incoming webhooks let Google Sheets post channel messages when rows change, approvals complete, or inventory thresholds breach—without Zapier per-task billing.

Store webhook URLs in Script Properties, never in cells. Format messages with JSON blocks for readability; respect Slack rate limits with batched digests.

For bidirectional Slack (reading channels), use the Web API via /blog/apps-script-slack-integration instead of webhooks alone.

Incoming webhook payload

POST JSON { text: '...' } or blocks array to hooks.slack.com/services/.... Use UrlFetchApp.fetch with contentType application/json.

Include a link back to the spreadsheet row using range.getA1Notation() and SpreadsheetApp.getActive().getUrl().

Installable onEdit trigger

Detect edits on Status column only by checking e.range.getColumn() in onEditInstallable. Debounce rapid edits with Utilities.sleep only if necessary—prefer queuing.

Simple onEdit cannot call UrlFetchApp—must installable.

Batching notifications

Accumulate row changes in Script Properties queue JSON, flush every 15 minutes on a clock trigger to one Slack message.

Reduces noise and avoids Slack 429 rate limits during bulk paste events.

Error handling

If response is not ok, log body to RunLog and email admin. Rotate webhooks if leaked—Slack allows regeneration without code deploy if URL read from Properties.

Test with #sandbox channel before production #ops-alerts.

Example code

function notifySlack(text) {
  const url = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK');
  UrlFetchApp.fetch(url, {
    method: 'post',
    contentType: 'application/json',
    payload: JSON.stringify({ text: text }),
  });
}
function onEditInstallable(e) {
  if (!e || e.range.getColumn() !== 5) return;
  notifySlack('Row ' + e.range.getRow() + ' status → ' + e.range.getValue());
}
ApproachBest forTradeoff
Apps Script nativeGoogle Workspace-centric workflows6-min limit, quotas
Zapier / MakeNo-code, many connectorsPer-task cost, vendor lock-in
Python + CloudHeavy data / MLHosting cost, separate auth
Google Sheets automation expertProduction custom logicBuild cost, you own code

FAQ

Webhook vs Slack Bot token?

Webhooks are fire-and-forget posts. Bot tokens enable threads, reactions, and channel reads—see /blog/apps-script-slack-integration.

Can I @mention users?

Use <@USERID> in text if you know member IDs, or <!channel> sparingly for true incidents.

Why did Slack return invalid_payload?

Malformed JSON or missing text/blocks. Logger.log your payload length; Slack limits message size.

Will onEdit fire on script writes?

Installable onEdit fires for user edits and some script writes depending on context—design idempotent messages with row IDs.

Compare to Zapier Slack step?

Apps Script removes per-task fees for high-volume row changes—see /blog/zapier-alternative-google-apps-script.

Need this done for you? I handle this as part of my consulting work — fixed-price quote within 24 hours.

Book a call with Raj →

Get the full Send Slack Notifications from Google Sheets with Apps Script script template

I'll email you a production-ready, commented version you can deploy in 10 minutes.

Need help with this? I handle this as part of my Google Sheets Automation Expert service.

CRM, dashboards, invoices, inventory, and report automation in Sheets.

See how it works →