Every 15 minutes
Draft replies to refund requests with the order details
Refund request emails get a Gmail draft reply that already knows the order, its date and whether it is inside your return window.
- Runs
- Every 15 minutes
- Apps
- Gmail, Shopify
- AI
- Yes, uses the built-in AI allowance
- Access
- gmail.compose, gmail.readonly; read_orders
Send this to your assistant
Create a ClickRuntime automation: every 15 minutes, look for refund request emails; find the order in Shopify, check it's within 30 days, and save a draft reply in Gmail for me to send.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
An online clothing shop gets a handful of refund requests a day. Each one means finding the order, checking the date against the 30-day policy, and writing a polite reply that explains what happens next. Customers often forget the order number, which adds another round of searching.
Drafting the reply with the order already found and the policy already checked turns each request into a quick read and send. Customers hear back faster, and every reply follows the same policy.
What you get out of it
Replies already know the order
The draft names the order, the items and the date. You do not need to search Shopify before replying.
The policy is applied the same way
Each request is checked against your return window. Customers get consistent answers whoever handles the inbox.
You still decide
Every reply is a draft. You read it, change anything, and send it yourself, so nothing goes out without your approval.
Faster answers for customers
A quick, specific reply calms an unhappy customer. It also cuts follow-up emails asking whether anyone saw the first one.
How it works
What happens, step by step
Every 15 minutes, ClickRuntime looks in your Gmail for new emails asking for a refund.
AI reads each email and picks out the order number and the reason given.
It finds the order in Shopify, using the order number or the sender's email address, and checks whether it is within your return window.
AI writes a reply that fits your policy, which is saved as a draft in the same Gmail thread.
Each email is handled once, so no duplicate drafts appear.
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 Shopify
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 Shopify steps into one automation
Under the hood
The code that runs this automation
import base64
from email.mime.text import MIMEText
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, credentials, http, state, ai, report_fetched
STORE = "your-store.myshopify.com"
def gql(query, variables=None):
resp = http.post(f"https://{STORE}/admin/api/2025-07/graphql.json", json={"query": query, "variables": variables or {}},
headers={"X-Shopify-Access-Token": credentials.connection("shopify", "store")})
return resp.raise_for_status() or resp.json()["data"]
SCHEMA = {"type": "object", "properties": {"order": {"type": "string"}, "reason": {"type": "string"}}}
@on_trigger
def run(event):
gmail = build("gmail", "v1", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False).users()
seen = set(state.get("seen") or [])
msgs = [m for m in gmail.messages().list(userId="me", q="refund newer_than:2d -from:me").execute().get("messages", []) if m["id"] not in seen]
report_fetched(len(msgs))
if not msgs:
return {"drafts": 0}
for m in msgs:
msg = gmail.messages().get(userId="me", id=m["id"], format="metadata", metadataHeaders=["From", "Subject"]).execute()
h = {x["name"]: x["value"] for x in msg["payload"]["headers"]}
sender = h["From"].split("<")[-1].strip(">")
ask = ai.generate(msg["snippet"], system="Extract the order number (or empty) and refund reason.", json_schema=SCHEMA, max_output_tokens=60).json
q = f"name:{ask['order']}" if ask["order"] else f"email:{sender}"
found = gql(f'{{ orders(first: 1, reverse: true, query: "{q}") {{ nodes {{ name createdAt }} }} }}')["orders"]["nodes"]
facts = f"Order {found[0]['name']} placed {found[0]['createdAt'][:10]}, return window 30 days" if found else "No order found; ask for the order number"
body = ai.generate(f"Customer wrote: {msg['snippet']}\nFacts: {facts}", system="Write a short, kind reply following the facts. Sign off as the Store team.", max_output_tokens=300).text
raw = MIMEText(body)
raw["To"], raw["Subject"] = sender, "Re: " + h.get("Subject", "")
gmail.drafts().create(userId="me", body={"message": {"threadId": msg["threadId"], "raw": base64.urlsafe_b64encode(raw.as_bytes()).decode()}}).execute()
seen.add(m["id"])
state.set("seen", sorted(seen)[-500:])
return {"drafts": len(msgs)}FAQ
Common questions
What if the customer does not give an order number?
Does it issue the refund in Shopify?
Can I change the wording of the replies?
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
Turn new Shopify products into blog drafts
Each time you add a product to Shopify, a blog draft about it is waiting in your store and an email tells you it is ready.
See how it worksCatch Shopify pricing and discount mistakes
Each morning you get an email if any price dropped below your floor, changed sharply, or a discount code is larger than your rules allow.
See how it worksGet a daily email about low Shopify stock
Each morning you get an email listing products that will run out soon at their current pace, plus any that are not selling.
See how it worksKeep exploring
Set up “Draft replies to refund requests with the order details” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.