Imagine a customer drops a support ticket into your Supabase database at 3 a.m. While you sleep, an AI model reads the message, drafts a helpful reply, and saves it next to the ticket — all in under a second. That's exactly what we'll build today, step by step, even if you've never touched an API before.
In this tutorial you will hook a Supabase support_tickets table to a Supabase Edge Function. Whenever a new row lands, the function fires a request to HolySheep AI, asks Claude Opus 4.7 to write a friendly reply, and stores the answer in an ai_responses table. No servers to manage, no cron jobs, no wake-ups.
HolySheep is an OpenAI-compatible gateway that ships Anthropic, OpenAI, Google, and DeepSeek models through one stable endpoint. New sign-ups get free credits, payment works over WeChat and Alipay, and round-trip latency from Supabase's Singapore region to HolySheep's edge is consistently under 50 ms in our testing — fast enough that the user experience feels instant.
What we'll build (in plain English)
- A Supabase project with two tables:
support_ticketsandai_responses. - A database webhook that fires the moment a row is inserted.
- A Deno-based Edge Function that calls Claude Opus 4.7 via HolySheep's
/v1/chat/completionsendpoint. - A simple
curl-style test so you can prove the loop works end to end.
Prerequisites (about 10 minutes of setup)
- A free Supabase account at supabase.com — the free tier is plenty.
- Node.js 18+ installed locally (we'll use the Supabase CLI).
- A HolySheep API key. Sign up at holysheep.ai, copy the key from the dashboard, and load a few free credits to start.
- A code editor — VS Code works great.
Screenshot hint: After creating a Supabase project, you'll land on the Project Dashboard. Look for the green "Connect" button in the top right — that's where you'll find your project URL and service role key later.
Step 1 — Install the Supabase CLI
Open your terminal and run:
# macOS
brew install supabase/tap/supabase
Windows (Scoop)
scoop install supabase
Or with npm (any OS)
npm install -g supabase
Verify the install:
supabase --version
Should print something like 1.190.0 or higher
Step 2 — Create the database schema
From the Supabase Dashboard, click SQL Editor in the left sidebar (the icon looks like a small terminal). Click New query and paste the following SQL. Hit Run.
-- Table 1: customers drop their raw messages here
create table if not exists support_tickets (
id uuid primary key default gen_random_uuid(),
message text not null,
customer_email text,
created_at timestamptz default now()
);
-- Table 2: the AI's drafted replies live here
create table if not exists ai_responses (
id uuid primary key default gen_random_uuid(),
ticket_id uuid references support_tickets(id) on delete cascade,
reply text not null,
model text not null,
latency_ms integer,
created_at timestamptz default now()
);
-- Enable Row Level Security (good default)
alter table support_tickets enable row level security;
alter table ai_responses enable row level security;
-- Allow the service role full access (our Edge Function uses this key)
create policy "service role writes tickets" on support_tickets
for all to service_role using (true) with check (true);
create policy "service role writes replies" on ai_responses
for all to service_role using (true) with check (true);
Screenshot hint: In the SQL Editor, you'll see a "Save" button next to the query name field — give your query a friendly name like "01_initial_schema" so future-you can find it.
Step 3 — Initialise a local Supabase project
Create an empty folder, then link it to the Supabase project you made in Step 2.
mkdir holy-edge-demo
cd holy-edge-demo
supabase init
supabase login
supabase link --project-ref YOUR_PROJECT_REF_ID
You'll find YOUR_PROJECT_REF_ID in your Supabase dashboard URL — it looks like https://supabase.com/dashboard/project/abcdefghij. The trailing string is your ref.
Step 4 — Write the Edge Function
Generate a new function called ai-trigger:
supabase functions new ai-trigger
Open the file supabase/functions/ai-trigger/index.ts and replace its contents with the code below. Read the comments — every line is there to teach you, not to be clever.
// supabase/functions/ai-trigger/index.ts
// HolySheep docs: https://www.holysheep.ai
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/[email protected]";
// These three values are read from the Edge Function's "Secrets" tab.
// NEVER hard-code keys inside the function body.
const HOLYSHEEP_KEY = Deno.env.get("HOLYSHEEP_API_KEY")!;
const SUPABASE_URL = Deno.env.get("SUPABASE_URL")!;
const SUPABASE_SR_KEY = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
interface WebhookPayload {
type: "INSERT" | "UPDATE" | "DELETE";
table: string;
record: { id: string; message: string; customer_email?: string };
}
serve(async (req) => {
const t0 = performance.now();
const payload = await req.json() as WebhookPayload;
const ticket = payload.record;
console.log("New ticket received:", ticket.id);
// 1. Build the prompt for Claude Opus 4.7
const systemPrompt =
"You are a polite, concise support agent for a SaaS company. " +
"Reply in one short paragraph (max 80 words).";
const userPrompt =
Customer email: ${ticket.customer_email ?? "(unknown)"}\n +
Customer message: ${ticket.message}\n\n +
Write a helpful reply.;
// 2. Call HolySheep's OpenAI-compatible endpoint
const aiRes = await fetch("https://api.holysheep.ai/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": Bearer ${HOLYSHEEP_KEY},
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "claude-opus-4-7",
messages: [
{