How to send Slack alerts from Supabase
Turn a SQL query on your Supabase database into Slack messages or Zendesk tickets, with no database password, no triggers in your schema, and no repeats.
- Supabase
- Slack
- Zendesk
- how-to
- sql
- slack
- supabase
Your product’s data lives in Supabase, and you want a Slack message when something in it becomes true: a free workspace is close to its quota, a big customer signs up, a payment fails. Rowfire, which is open source, does that with a SQL query. It reads your Supabase project through Supabase’s own read-only endpoint, so it needs no database password and installs nothing in your schema.
Connect without a password
Rowfire sends each query to Supabase’s read-only query endpoint, which runs it
as supabase_read_only_user. Two ways to authorize it:
- OAuth. Register an OAuth app in your Supabase organization with Projects: Read and Database: Read and nothing else, then pick Connect Supabase in Rowfire, approve, and choose a project.
- A personal access token, for the CLI or an install without an OAuth app.
The endpoint runs nothing but reads, and Rowfire’s own checker still refuses
anything but a single SELECT. Tables without a schema are read as
public.<table>; name other schemas yourself, such as auth.users.
Write the event as a query
This trigger comes with Rowfire’s sample SaaS project, whose usage data lives in Supabase: a free workspace has used 80% of this month’s API quota.
SELECT w.id AS workspace_id,
w.name,
w.owner_email,
w.monthly_quota,
c.month,
MIN(c.recorded_at) AS crossed_at
FROM workspaces w
JOIN (
SELECT u.workspace_id,
u.recorded_at,
date_trunc('month', u.recorded_at) AS month,
SUM(u.calls) OVER (
PARTITION BY u.workspace_id, date_trunc('month', u.recorded_at)
ORDER BY u.recorded_at
) AS used
FROM api_usage u
) c ON c.workspace_id = w.id
WHERE w.plan = 'free'
AND c.used >= 0.8 * w.monthly_quota
GROUP BY w.id, w.name, w.owner_email, w.monthly_quota, c.month
The clock is crossed_at, the moment the running total passed 80%. The key is
workspace_id and month together, so each workspace can fire once a month
and never twice in the same one. A running total like this is a condition no
single row change describes, which is why it’s a query and not a row trigger.
Say how often, then where
A rule subscribes to the trigger and decides how often one key may fire:
once ever, once per day, week or month, or every nth time. Then it gets an
action: a Slack message to #growth, a Zendesk ticket for customer success,
a Braze event, or a call to any REST API.
Message templates take any column from the row:
{{ name }} has used 80% of its {{ monthly_quota }} monthly calls. Owner: {{ owner_email }}
Check it before it posts
A backtest replays the rule over past days and shows how many messages it would have sent, with example rows. Shadow mode then renders every message against live data without sending it. Promote the rule when the messages look right. A new trigger starts at now, so switching it on never posts last month’s rows.
Rowfire or Supabase Database Webhooks
Supabase’s Database Webhooks call a URL when a row is inserted, updated or deleted. For “tell me the moment this row appears”, where the row is the whole event, they are the simpler choice and they fire straight away.
Rowfire is polled, within a minute by default. It fits when:
- the event is a condition a query works out: a running total, a count across tables, the third failure this month;
- the event is an absence: a trial that never activated, a ticket with no reply (more on those);
- the same row keeps matching and must not repeat: one message per workspace per month, not one per poll;
- you want to see what it would send before it sends, and keep your schema free of triggers.
For the same steps on any database, see how to send a Slack alert from a SQL query, or try a rule on sample data in the demo.
Questions
Does Rowfire need my Supabase database password?
No. It sends each query to Supabase's read-only query endpoint, which runs it as Supabase's read-only user. You connect with OAuth (Projects: Read and Database: Read) or a personal access token.
Do I need to add triggers or functions to my Supabase database?
No. A Rowfire trigger is a SELECT that Rowfire polls, within a minute by default. Nothing is installed in your schema and nothing is written to your database.
Can I alert on something across several tables, or something that didn't happen?
Yes. The trigger is any single SELECT in Postgres SQL, so it can join tables, use window functions, or look for rows that are missing, such as a trial that never activated.
When are Supabase Database Webhooks the better fit?
When you want a call the moment a row is inserted, updated or deleted, and that one row is the whole event. Rowfire suits conditions a query has to work out, alerts that must not repeat, and checking what a rule would send before it sends.