Every 10 minutes
Reply to quote requests with prices from your Supabase products
Quote requests in your inbox get a reply priced from your Supabase product table, and every quote is logged.
- Runs
- Every 10 minutes
- Apps
- Gmail, Supabase
- AI
- Yes, uses the built-in AI allowance
- Access
- Gmail send+read; Supabase read+write
Send this to your assistant
Create a ClickRuntime automation: every 10 minutes, find new quote-request emails, work out the products and quantities with AI, look up prices in my Supabase products table, save the quote as a Gmail draft reply and log it in my quotes table.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
A wholesaler gets quote requests by email all day: '200 of the blue mugs and 50 totes, what's the price?'. Each one means checking the price list, doing the maths and writing it up. Slow quotes lose orders to faster competitors.
Reading the request, pricing it from your own product table and preparing the reply cuts the turnaround from hours to minutes, while you still check each quote before it's sent.
What you get out of it
Quote in minutes
Speed often decides who wins the order. A ready reply lets you answer while the buyer is still comparing.
Prices always current
Quotes use the prices in your product table, not an old PDF price list.
Fewer maths mistakes
Line totals and the grand total are calculated, not typed.
Every quote logged
The quotes table records what was offered, to whom and when, ready for follow-up.
How it works
What happens, step by step
Every 10 minutes, ClickRuntime checks your sales inbox for new emails.
AI decides whether each is a quote request and lists the products and quantities asked for.
It looks up each product's price in your Supabase products table and calculates the totals.
It saves a reply with the quote as a Gmail draft in the same thread and logs the quote in your quotes table.
Unknown products are flagged in Slack, and handled emails are remembered.
Before it runs live
- Connect Google through your own Google app (a one-time, 10-minute setup), so it works with your own Gmail
- Connect Supabase
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Act only on the items that match your own rules, and skip the rest
- Change what the AI looks for, or how it writes the result
- Add another app, for example also send it to Slack
- Combine it with other Gmail and Supabase steps into one automation
Under the hood
The code that runs this automation
import base64
from email.message import EmailMessage
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, credentials, http, state, notify, ai, report_fetched
SUPABASE = "https://your-project.supabase.co/rest/v1"
def sb(method, path, **kw):
key = credentials.secret("SUPABASE_KEY")
r = http.request(method, f"{SUPABASE}/{path}", **kw, headers={"apikey": key, "Authorization": f"Bearer {key}", "Prefer": "return=representation,resolution=merge-duplicates"})
return r.raise_for_status() or (r.json() if r.content else None)
SCHEMA = {"type": "object", "properties": {"is_quote": {"type": "boolean"}, "items": {"type": "array", "items": {"type": "object",
"properties": {"product": {"type": "string"}, "qty": {"type": "integer"}}}}}}
@on_trigger
def run(event):
gmail, done = build("gmail", "v1", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False), set(state.get("done") or [])
msgs = [m for m in gmail.users().messages().list(userId="me", q="to:sales@northwind.com newer_than:1d").execute().get("messages", []) if m["id"] not in done]
report_fetched(len(msgs))
if not msgs:
return {"summary": "Nothing new"}
prices = {p["name"].lower(): p["price"] for p in sb("GET", "products?select=name,price")}
for m in msgs:
full = gmail.users().messages().get(userId="me", id=m["id"]).execute()
h, done = {x["name"]: x["value"] for x in full["payload"]["headers"]}, done | {m["id"]}
req = ai.generate(f"Is this a quote request? List products and quantities.\n{full['snippet']}", json_schema=SCHEMA, max_output_tokens=200).json
if not req["is_quote"]:
continue
lines = [(i["product"], i["qty"], prices.get(i["product"].lower())) for i in req["items"]]
total = sum(q * p for _, q, p in lines if p)
body = "\n".join(f"{n}: {q} x {p:.2f} = {q * p:,.2f}" if p else f"{n}: {q} – price on request" for n, q, p in lines)
msg = EmailMessage()
msg["To"], msg["Subject"] = h["From"], "Re: " + h.get("Subject", "Your quote")
msg.set_content(f"Thanks for your request. Here's your quote:\n\n{body}\n\nTotal: {total:,.2f}")
gmail.users().drafts().create(userId="me", body={"message": {"threadId": full["threadId"], "raw": base64.urlsafe_b64encode(msg.as_bytes()).decode()}}).execute()
sb("POST", "quotes", json={"email": h["From"], "total": total, "lines": body, "message_id": m["id"]})
if any(p is None for *_, p in lines):
notify.slack(f"Quote for {h['From']} has unpriced items", channel="#sales")
state.set("done", list(done)[-1000:])
return {"emails": len(msgs)}FAQ
Common questions
Is the quote sent automatically?
What if a product isn't in my table?
How does it know an email is a quote request?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Draft support replies in Gmail from your Supabase knowledge base
New support emails get a draft reply in Gmail based on answers stored in your Supabase knowledge table, and replies you send are saved back as new knowledge.
See how it worksTurn action items in your email into Supabase tasks
Every 15 minutes, tasks mentioned in your new emails, with owners and due dates, are added as rows in your Supabase tasks table.
See how it worksScreen emailed CVs into a Supabase candidates table
CVs sent to your hiring inbox are read, summarised and scored against the role, and each candidate is added to your Supabase table.
See how it worksKeep exploring
Set up “Reply to quote requests with prices from your Supabase products” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.