On a schedule
Keep a Google Sheet of your Zendesk tickets
A sheet lists your tickets with status, tags and dates, updated every hour, ready for reporting or building help articles.
- Runs
- On a schedule
- Apps
- Google Sheets, Zendesk
- AI
- Not needed
- Access
- Zendesk read; sheet editor
Send this to your assistant
Create a ClickRuntime automation: every hour, copy new and updated Zendesk tickets into the Tickets tab of my support sheet, one row per ticket, updating the row if the ticket already exists.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
An operations manager wants to report on support alongside sales and product data, all of which already live in Google Sheets. Zendesk's own reports cannot be joined with anything else, and the CSV export has to be run by hand every time. The sheet is always a week out of date.
A sheet that updates itself every hour lets anyone filter tickets by tag, count bugs per feature or pick the most common how-to questions for the help centre, using tools they already know.
What you get out of it
Reports alongside your other data
Ticket rows sit next to sales and product data in Sheets, so you can join them with a formula instead of a data project.
No manual exports
The sheet is always current, with no CSV download to remember.
Material for help articles
Filtering how-to tickets by tag shows which questions come up most, which is where a new help article saves the most time.
Share without seats
People outside support can read the sheet without a Zendesk licence.
How it works
What happens, step by step
Every hour, ClickRuntime asks Zendesk for tickets created or changed since its last check.
It reads the existing rows in your Tickets tab to see which tickets are already listed.
Tickets already in the sheet have their row updated; new ones are added at the bottom.
It remembers where it got up to, so the next run only picks up newer changes.
Before it runs live
- Connect your Google Sheets account and pick the spreadsheets it may use
- Connect Zendesk
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
- Run it at a different time, more or less often, or only on weekdays
- Add an AI step, for example to summarize, sort or draft a reply
- Add another app, for example also send it to Slack
- Combine it with other Google Sheets and Zendesk steps into one automation
Under the hood
The code that runs this automation
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
from clickruntime import on_trigger, report_fetched, http, credentials, state
ZD, AGENT = "https://yourcompany.zendesk.com/api/v2", "you@yourcompany.com"
def zd(method, path, **kw):
r = http.request(method, ZD + path, auth=(f"{AGENT}/token", credentials.secret("ZENDESK_API_TOKEN")), **kw)
return r.raise_for_status() or (r.json() if r.content else None)
sheets = lambda: build("sheets", "v4", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False).spreadsheets()
SHEET_ID = "your-spreadsheet-id"
@on_trigger
def run(event):
page = zd("GET", "/incremental/tickets/cursor.json", params={"cursor": state.get("cursor")} if state.get("cursor") else {"start_time": 0})
tickets = page["tickets"]
report_fetched(len(tickets))
if not tickets:
return {"summary": "No changes"}
s, new_rows, updates = sheets(), [], []
ids = [r[0] if r else "" for r in s.values().get(spreadsheetId=SHEET_ID, range="Tickets!A2:A").execute().get("values", [])]
for t in tickets:
row = [str(t["id"]), t["subject"], t["status"], t["priority"] or "", ", ".join(t["tags"]), t["created_at"], t["updated_at"]]
(updates.append({"range": f"Tickets!A{ids.index(row[0]) + 2}", "values": [row]}) if row[0] in ids else new_rows.append(row))
if updates:
s.values().batchUpdate(spreadsheetId=SHEET_ID, body={"valueInputOption": "RAW", "data": updates}).execute()
if new_rows:
s.values().append(spreadsheetId=SHEET_ID, range="Tickets!A:G", valueInputOption="RAW", body={"values": new_rows}).execute()
state.set("cursor", page["after_cursor"])
return {"updated": len(updates), "added": len(new_rows)}FAQ
Common questions
Does it copy the whole conversation?
Can I limit it to some tickets?
What happens when a ticket changes?
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
Track SLA risks and stuck tickets in a sheet
A sheet shows how long each open ticket has left before its deadline, Slack warns you before one breaches, and pending tickets get chased.
See how it worksLog daily support numbers and churn signals to a sheet
Every day a row of ticket numbers goes into your metrics sheet, along with any customers whose tickets hint they might leave.
See how it worksCheck payment complaints against your payments sheet
Tickets about payments are matched to your payments sheet, and the genuine problems are raised to urgent and flagged in Slack.
See how it worksKeep exploring
Set up “Keep a Google Sheet of your Zendesk tickets” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.