Google Sheets to a Slack webhook: the DIY route, where it stops being fun, and what to do then
Apps Script plus a Slack incoming webhook is the obvious way to bridge Sheets and Slack. It even works. We will walk you through it, and then through the three moments it stops being fun.
Google Sheets to a Slack webhook: the DIY route, where it stops being fun, and what to do then
Every engineer who has ever needed to get a number from a spreadsheet into Slack has, within twenty minutes, found this path:
- Create a Slack app, turn on incoming webhooks, grab the URL.
- Open Apps Script in the sheet.
- Write a function. Set a time-driven trigger. Walk away.
It works. It even feels good. There is a tiny dopamine hit the first morning the message shows up on its own. We respect this path. We have walked it. We have also been the person three months later trying to remember why it stopped working.
The minimum-viable script
For the four people on the internet who haven't done this yet:
function postToSlack() {
const webhook = 'https://hooks.slack.com/services/...'
const sheet =
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Summary')
const value = sheet.getRange('B2').getValue()
const payload = {
text: `Today's revenue: $${value.toLocaleString()}`,
}
UrlFetchApp.fetch(webhook, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload),
})
}
Then in Apps Script: Triggers → Add Trigger → time-driven, daily, 9–10am. Done. The number appears in Slack every morning. The first person to see it sends a thumbs up. You're a hero.
The three moments it stops being fun
Moment one: someone asks for the chart
Slack messages are text or Block Kit. Neither renders a chart. To get an image in, you need to:
- Render the chart somehow (you can use the Sheets
EmbeddedChart.getBlob()API, or generate one yourself). - Save the image somewhere Slack can fetch.
- Either include a public URL in your payload or upgrade from an incoming webhook to a proper bot token and use
files.upload.
This is several hours of work and a new attack surface to think about (public image URLs, expiring tokens, file permissions). All to do something Chartcastr does in three clicks.
Moment two: there are ten of these scripts
The first script is fine. The second is fine. The fifth one breaks silently because the underlying sheet got renamed, and nobody notices until the CEO asks why the Friday revenue ping didn't show up. There's no inventory. There's no monitoring. There's just a dozen sheets, each with a function called something like postToSlack2 written by someone who left in 2024.
This is the moment most teams type "google sheets slack integration" into a search bar and find this post.
Moment three: Apps Script eats your lunch
Apps Script has limits: per-execution time (six minutes on consumer accounts), per-day URL fetch quotas, per-day trigger executions. If your script does anything ambitious — pulling a range, formatting it, doing a comparison, hitting an API — you will eventually trip one of them. The failure mode is usually "the trigger silently stops firing", which you discover three weeks later.
What to do then
The honest answer: if you only ever needed a single number once a day, the Apps Script + webhook path is fine. Don't overthink it. Don't reach for a tool. Some problems just want six lines of JavaScript.
If you need a chart, or you have more than three of these, or you want anyone to be able to manage them without reading code: switch to a tool that was built for this. We're biased, but Chartcastr exists specifically for the recurring-chart-into-Slack job. OAuth into the sheet, pick the chart, pick the channel, pick the schedule. The script disappears.
The mental model is the same: "this chart, this channel, this cadence." The maintenance burden is not.
Related reading
- Google Sheets, Apps Script, and Slack — the longer walkthrough of the DIY path.
- Slack and Google Sheets integration explained — the four-flavour cheat sheet.
- Why we don't recommend screenshotting — for the third option you might have been considering.
- Chartcastr vs Zapier — for the "but I already pay for a Zap" question.






