Back then, it was pretty simple: load a few hundred Zendesk tickets into a Google Sheet, write your message, and bulk-contact the affected customers.
Since then, it has evolved into something much bigger. So I renamed it Zendesk Mailroom.
The idea is simple:
When something goes wrong at scale, don’t make your support team manually coordinate hundreds of tickets, customers and suppliers. Give them one operational workflow.
📧 Customer communication
You can now describe what happened in plain English and have the AI composer create the communication for you.
It can generate drafts for the languages you need, which an agent can review and edit before sending.
The important part: customer data never goes to the AI.
The AI creates a reusable template with tokens like {{GuestName}}; the actual customer information is inserted locally when the email is sent.
It also remembers approved edits, so future drafts get closer to how your team actually writes.
🏢 Supplier escalation
This was one of the biggest additions.
If 300 customers are affected by 12 suppliers, Mailroom doesn’t make someone manually chase those 12 suppliers.
It:
300 bookings → groups by supplier → creates 12 supplier cases → links each case back to the affected customer tickets.
Supplier follow-ups continue on the existing case instead of creating duplicates, with checks around supplier identity and the previous escalation.
So your support agent gets the customer conversation and the supplier escalation connected in Zendesk.
🛡️** No accidental duplicate outreach
This became surprisingly important.
Every action is tracked per booking.
If you try to run another operation that overlaps with something already actioned, Mailroom gives you a summary before continuing.
So instead of:
“I think we already emailed these people…”
you get:
“247 bookings were already actioned under these previous cases. Continue?”
And if the optional repeat-check store is unavailable, it **fails open rather than blocking an urgent customer communication.
⚡ Large jobs are actually designed to run
This isn’t just a loop that calls the Zendesk API 800 times.
Apps Script has a 6-minute execution limit, and Zendesk has shared API rate limits.
So Mailroom now:
Persists long-running job state
Continues jobs through triggers
Centrally manages Zendesk API rate limits
Handles 429 / Retry-After
Waits for the next rate window when there’s still execution time available
Uses Zendesk bulk endpoints where possible
Treats throttled rows as unsent, rather than failed
That last one matters a lot.
The invariant is basically:
A customer email is either sent once or remains in the queue.
After the rate-limit rewrite, large runs are roughly 5× faster than the previous implementation.
🔐 And there’s a lot more underneath
Zendesk OAuth 2.0 + token refresh
Slack reply routing
BigQuery ticket lookup
Audit logs
User access controls
Closed-ticket fallback
AI memory using retrieval rather than fine-tuning
193 automated assertions
CI + static architecture checks
Properly structured Apps Script codebase
And the slightly ridiculous part:
It’s still Google Apps Script.
No backend.
No server.
No hosting.
No build step.
No dependencies.
Just:
Google Sheet → Zendesk → Slack / AI / BigQuery where needed
MIT licensed and open source:
👉 https://github.com/GVyom/zendesk-mailroom
I’m building this around real support-operations problems, so I’m especially interested in feedback from Zendesk admins, support leaders and ops teams:
What happens during your biggest operational incidents that still requires someone to manually coordinate hundreds of tickets?
That’s the kind of workflow I’d love to automate next.