A spreadsheet is where a lot of operational data lives, but it’s rarely where your team is looking. When something changes — a deal closes, stock runs low, an invoice goes overdue — the people who need to know are in Slack, a CRM, or another app. Getting the update there usually falls to someone remembering to post it, or to an Apps Script that fires on a time-driven trigger and breaks the next time a column moves.
Neither holds up well. The manual version depends on someone being at their desk. The script version means you now own code — UrlFetchApp calls, hardcoded column indexes, a trigger to debug when it stops running — for what amounts to sending a formatted message.
Sheetgo’s webhook destination removes that step. Instead of ending a workflow in another spreadsheet, you end it with an HTTP request to any endpoint you choose — a Slack channel, a CRM, an internal API, another automation tool. The workflow that filters your data pushes it straight out, on whatever schedule you set.
It’s a reversal of how webhooks have worked in Sheetgo so far. A webhook as a source pushes data into a spreadsheet from an outside app; the webhook destination sends data out. To show how it works, this guide builds one end to end using Slack as the example — posting a weekly “closed won” sales digest to a channel. You’ll set up the source sheet, filters, a Slack app, and the request body template, which is where most of the configuration time goes (and where one rule fails silently, with no error in Slack or the Sheetgo run log). The webhook destination is currently in beta.
Test Sheetgo Workflows for free and build your first webhook destination.
What the Google Sheets to Slack automation does
Every run, Sheetgo reads a sales pipeline sheet, keeps only the deals marked Closed Won in the last seven days, and posts them to #sales-wins as a single formatted digest:
Four components: the source spreadsheet, two Sheetgo filter processors, a Slack app that provides the receiving URL, and the webhook destination that makes the call.
Step 1: The source spreadsheet
We start with a spreadsheet named Sales_Pipeline, holding deals across a mix of stages. It has five deals, with the deal name, amount, assigned rep, status, and close date.
Alongside those five columns, the sheet has two more — Send and Digest. Both are formulas rather than typed data, and they’re what turn a static pipeline sheet into something the automation can act on.
The Send column: choosing which deals get pushed
The Send column decides which deals reach Slack. In F2, enter this formula and fill it down:
=IF(AND($D2="Closed Won", $E2>=TODAY()-7), "YES", "")A deal is marked YES only when the status is Closed Won and the close date falls within the last seven days. Everything else stays blank.
The obvious alternative is to mark deals as Notified by hand once they’ve been announced. That breaks down as soon as the automation runs on a schedule, because Sheetgo doesn’t write back to the source sheet — you would be editing rows manually after every run to stop the same deals posting twice.
A rolling date window handles it on its own: each run picks up only what has closed since the last one. Seven days is what this tutorial uses because we’re sending a weekly report, but the number should match how often you run the automation. Sales teams that want to know about wins immediately would use TODAY()-1 and a daily schedule instead.
This is also why Sales_Pipeline includes Fabrikam, a Closed Won deal that closed on 2026-07-02. It sits outside the seven-day window, so it stays blank while the two recent wins are marked YES. Without a row like that, you can’t tell whether the filter is genuinely working or simply passing everything through.
The Digest column: building the Slack message in the sheet
The Digest column assembles the message itself. In G2, enter:
=ARRAYFORMULA(TEXTJOIN(CHAR(10),TRUE,IF($F$2:$F="YES","*"&$A$2:$A&"* · "&TEXT($B$2:$B,"$#,##0")&" · "&$C$2:$C,"")))This is a single cell — leave G3 and below empty. It scans every row, keeps the ones marked YES, formats each into one line, and joins them with CHAR(10) line breaks. The result looks like this:
*Acme Corp* · $5,000 · Sarah
*Vertex Labs* · $12,500 · Miguel
The asterisks are Slack’s markdown for bold, so *Acme Corp* renders as Acme Corp once it reaches the channel. TEXT($B$2:$B,"$#,##0") handles the currency, because the formula reads the raw cell value rather than the formatted one you see in column B — without it, $5,000.00 ends up in the digest as 5000.
Building the message in the spreadsheet rather than in the webhook request body is a deliberate choice — it keeps the JSON template down to a single placeholder and sidesteps the part of the syntax that causes the most trouble.
One heads-up: because the digest formula sits in G2, the webhook pulls it from the first row that passes your filters. If that row ever changes — someone sorts the sheet, or a deal ages out of the window — the digest could move. To make this production-ready, move the formula to its own single-row tab and point the workflow at that instead.
Step 2: Create the Slack app and generate the webhook URL
Before building anything in Sheetgo, Slack needs somewhere to receive the message: a Slack app with incoming webhooks enabled, which gives you a single URL that accepts a JSON payload and posts it to one channel.
Start by creating the channel if it doesn’t already exist — here, #sales-wins. It has to exist first, because Slack asks you to pick one during setup.
1. Create the app. Go to Slack API: Your Apps and click Create an App. Slack offers a few starting points — AI agent, Starter app, From a manifest, and Blank app. Choose Blank app.
Give it a name (Sheetgo Alerts Testing works) and pick your workspace.
2. Turn on incoming webhooks. In the left sidebar under Features, click Incoming Webhooks, then switch Activate Incoming Webhooks to On. You can skip OAuth & Permissions entirely — flipping this toggle handles the permission, and Slack adds a bot user automatically if the app doesn’t have one.
3. Add a webhook to the workspace. Scroll to Webhook URLs for Your Workspace and click Add New Webhook. Slack asks which channel to post to — select #sales-wins and click Allow.
4. Copy the URL. You land back on the Incoming Webhooks page with a new row showing the URL, the channel, and who added it. Click Copy.
The URL is locked to one channel — you can’t redirect it by adding a channel field to the payload, since Slack dropped that for modern apps. To post to a second channel, generate a second webhook and add a second Sheetgo connection. Treat this URL as a credential: anyone who has it can post to your channel as your app, with no further authentication.
Step 3: Build the Google Sheets to Slack workflow
1. Create a new workflow. In your Sheetgo Workflows app, click + New → New Automation → Create a workflow.
2. Select the source. On the Select source screen, choose Google Sheets, find Sales_Pipeline, and select the tab holding your data — here, Sheet1. Click Next step.
The data processor step is optional in most workflows. Here it does real work — without it, every row gets pushed, including deals still in negotiation and deals that were lost. We add two processors, and the order matters.
3. Add Filter rows. Set the condition to Column F : Send | Text is exactly | YES, click Confirm on the condition card, then Next step.
This reduces five deals to two. Northwind is still in negotiation, Contoso was lost, and Fabrikam closed outside the seven-day window — none are marked YES, so none reach Slack.
4. Add Filter columns. On the next processor screen, click Filter columns and select Deal Name, Amount, Rep Name, and Digest. Leave Status, Close Date, and Send unticked.
Send is scaffolding — it drives the row filter, it isn’t meant to be sent anywhere. Status is redundant, since every surviving row is Closed Won by definition, and Close Date doesn’t appear in the digest message. Dropping them keeps the payload small and readable when you inspect it in the next step. Order matters: the row filter reads the Send column, so if you filtered columns first and dropped Send, the row filter would have nothing to match on.
One practical note: if you add the Digest column to your sheet after configuring this step, Sheetgo won’t know about it. Click Sync columns to refresh the list, then tick it. Skipping this is a common cause of an empty message later. Click Next step.
Step 4: Configure the webhook destination
On the destination screen, select Webhook. The configuration panel has three parts: the request URL, the headers, and the request body.
1. Set the request URL. Leave the method as POST and paste your Slack webhook URL. The dropdown also offers PUT, PATCH, and DELETE for other endpoints, but Slack’s incoming webhooks only accept POST.
2. Check the headers. Content-Type: application/json is set by default, which is what Slack requires.
3. Write the request body. The note above the body field explains the basics: the body is a template rendered when the connection runs, and you reference the workflow’s output with DATA for the full table or ROWS for one object per record. Placeholders go in double curly braces, so a template that sends every surviving record looks like this:
{"rows": {{ROWS}}}The braces are easy to leave out, and doing so causes a failure that’s hard to diagnose. Writing ROWS without them isn’t a placeholder, it’s invalid JSON — and instead of reporting an error, Sheetgo sends the request with an empty body. Slack rejects it, nothing appears in the channel, and there’s no message explaining why. The same applies to quotes: {{ROWS}} renders a complete JSON array including its brackets, so writing "rows": "{{ROWS}}" would give you a quoted string containing JSON rather than the array itself. The panel says it directly — don’t wrap placeholders in extra quotes.
Inspecting the payload before sending it to Slack
Slack rejects malformed payloads with a bare invalid_payload response and shows you nothing about what it received, which makes it a hard place to work out a template you’re still figuring out. A request inspector is easier. There are several; this tutorial uses Webhook.site.
Open webhook.site, copy the unique URL it generates, and paste it into the REQUEST URL field in place of your Slack URL. It accepts any payload and displays the raw body as it arrived.
With {"rows": {{ROWS}}} in the body, click Review automation and Finish and run. The payload arrives as a rows array — one object per surviving record, each key matching a column header exactly as written in the sheet, spaces and all:
{ "rows": [ { "Deal Name": "Acme Corp", "Amount": "$5,000.00", "Rep Name": "Sarah", "Digest": "*Acme Corp* · $5,000 · Sarah\n*Vertex Labs* · $12,500 · Miguel" }, { "Deal Name": "Vertex Labs", "Amount": "$12,500.00", "Rep Name": "Miguel", "Digest": "" } ]}Two records instead of five, with Status and Send stripped out. Notice the full digest lands in the first row’s Digest field — that exact header spelling is how you’ll reach it next, so it has to be “Digest”, not “digest” or “Message”.
Build the Slack message and run it
Point the REQUEST URL back at your Slack webhook and replace the body with this Slack Block Kit template:
{ "text": "Closed Won this week", "blocks": [ { "type": "header", "text": {"type": "plain_text", "text": "🏆 Closed Won this week"} }, { "type": "section", "text": {"type": "mrkdwn", "text": {{ROWS[0]["Digest"]}}} }, { "type": "context", "elements": [{"type": "mrkdwn", "text": "Pushed by Sheetgo"}] } ]}
The {{ROWS[0]["Digest"]}} placeholder pulls the whole formatted digest from the first row — and, following the panel’s rule, it isn’t wrapped in quotes, because it renders as a quoted JSON string on its own.
Schedule the automation
To run this on a schedule rather than by hand, turn on Enable automation triggers on the review screen and switch Run automatically to On. Under Trigger options you get four choices, and which one you pick depends on how your team works:
- Based on a schedule runs the automation at a fixed time — hourly, daily, or weekly, on the days you choose, in your timezone. This is the right fit for a digest, where the point is a regular summary rather than an instant alert.
- On form submission runs it whenever a Sheetgo form is submitted — useful when the sheet is fed by a form and you want the alert to follow the entry.
- On workflow run chains this automation after another one, so it fires when an upstream automation completes. This is how you build a sequence — one automation cleans and merges the data, and this one sends the result.
- On webhook event runs the automation when an inbound webhook arrives, letting an external system decide when to push — for example, a payment provider recording a new sale in the sheet.
These last three don’t fit this particular digest, but they show the setup can flex to whatever arrangement your workflow needs. For a Google Sheets to Slack digest, choose Based on a schedule, set the frequency to weekly to match the seven-day window, and pick your time and days.
Click Finish and run. The message appears in #sales-wins:
What else you can send with a webhook destination
Sending Google Sheets to Slack is the easiest example to demo, but the webhook destination sends an HTTP request to any endpoint that accepts one, so the same setup works well beyond chat notifications.
- Low stock alerts: filter an inventory sheet to items below their reorder point and send the list to your purchasing channel on a daily schedule.
- Overdue invoice summaries: filter to unpaid invoices past their due date and push a weekly digest to finance, with the wording controlled from the spreadsheet.
- Other APIs and tools: the destination supports POST, PUT, PATCH, and DELETE with custom headers, so you can update records in a CRM, call an internal API, or trigger a run in another tool.
Conclusion
The webhook destination is the last step in a Sheetgo workflow, which means everything else in the platform is still available before it. In a single automation you might merge several regional spreadsheets into one, remove duplicates, run the data through the AI Data Processor, filter out test records, and then push the result to Slack.
You can also pair it with the inbound direction, using two separate automations. A webhook as a source lets an outside app push data into a spreadsheet without the Google Sheets API. A second automation reads that spreadsheet, processes it, and sends the result out through a webhook destination. The spreadsheet sits between the two as a processing layer your team can read and edit.
Ready to send Google Sheets to Slack where your team already works? Sign up for Sheetgo and build your first webhook destination today.
