Start with a dumb but workable FAQ trigger
So the first time I set this up, I overcomplicated the Zendesk trigger and it just did nothing. Like, I’d submit a test ticket, and poof — no response, no logs, as if I hadn’t even written the trigger. Turns out, starting with the dumbest, simplest version is the way to go.
Create a new trigger in Zendesk and name it something like “GPT Auto Reply – Test Only.” Don’t try to filter by ticket content yet. Just set it to fire when a ticket is created and the subject contains any word at all (I literally used condition “Ticket subject text contains: ‘?’”).
In the Actions section, use the “Notify active Webhook” action. If you haven’t made one yet, create a new Webhook that points to your GPT-powered backend (we’ll handle that in the next section). For now, just set the trigger to reliably fire.
If this doesn’t work — check that Zendesk automation is enabled and that the webhook looks like it’s being hit. You can check webhook history under Admin > Webhooks. Don’t trust the logs though — sometimes it says “Success” when it straight up didn’t POST anything. ¯\_(ツ)_/¯
Hook up the GPT response endpoint
For this part, you’ll need something that listens to the webhook POST from Zendesk, parses the ticket content, and sends a reply prediction via GPT. You can do this in several ways — I’ve used both Pipedream and bare NodeJS on a Cloudflare Worker (Pipedream is easier but sometimes it delays outbound calls randomly during high load — so…test often).
Here’s a basic JSON payload Zendesk sends:
“`json
{
“ticket”: {
“id”: 12345,
“subject”: “How do I reset my password?”,
“description”: “I’m trying to reset my login but I didn’t get any email.”
},
“requester”: {
“name”: “Jane Doe”,
“email”: “jane@example.com”
}
}
“`
Once you’ve got that captured, use OpenAI’s API (or anything similar — Claude works too) to send the subject + description and ask it to predict an appropriate response. Don’t overoptimize yet — just do something like:
“You are a helpful support agent. Based on the customer’s question, write a polite and helpful email reply.”
Then POST the answer back to Zendesk. To do that, you’ll call their API with the ticket ID and create a public comment. Example API call:
“`http
POST https://yourdomain.zendesk.com/api/v2/tickets/12345/comments.json
Authorization: Basic BASE64_ENCODED
Content-type: application/json
{
“ticket”: {
“comment”: {
“body”: “Hi Jane, thanks for reaching out! You can reset your password…”,
“public”: true
}
}
}
“`
When this round-trips correctly, you’ll see the GPT-generated reply show up on the ticket almost instantly. That’s when you know you’ve got the basic loop working 🙂
Add topic filters to avoid wrong matches
Okay now — here’s what completely broke my first real deployment. I turned on the live GPT responder trigger expecting it to only reply to FAQs, but didn’t set any filter on the kinds of tickets. So someone sent in a ticket about a billing issue with sensitive info, and boom — GPT replied with a cheerful password reset guide. Not great 😬
So we need a rule to avoid tickets where an agent reply is definitely better. Two ways to do this:
1. Use ticket tags or custom fields. For example, mark incoming tickets with a ‘faq_candidate’ tag if they seem chatbot-worthy (some teams use Zapier or a classification tool to auto-tag based on contents).
2. Trigger only on certain words or patterns. I did this in Zendesk trigger conditions using “Ticket subject contains” like “how do I,” “reset,” “cancel my subscription,” etc. Keep this list short and test it.
Pro tip: GPT hates vague questions — stuff like “I need help” will generate junk filler. Better to skip those entirely. I set a rule where if the question text is shorter than 10 words, it won’t fire the GPT reply. That cut down a LOT of garbage answers.
Handle followup replies like a human would
The moment you think it’s working — it won’t. A user replies to your AI-generated answer saying “That didn’t help”… and then GPT happily responds *again* with the exact same sentence but reworded. Cue angry user. 😑
What I did to stop that:
– If a ticket already has a GPT-generated comment, skip it unless the user added new info.
– Keep a flag in metadata (e.g., in a ticket field or hidden tag like `gpt_attempted`) so I don’t reprocess the same ticket twice.
– Sometimes we store the last 3 messages (agent + user) and compare them inside the GPT prompt — helps it craft better followups but it’s not magic. Still messes up occasionally.
Another trick: prepend the new message into GPT’s context like this:
“Customer replied: ‘That didn’t work, I still can’t find the email.’ Here’s the original ticket:…”
This gets GPT into followup mode instead of treating everything like a new question.
Inject your exact knowledge base into the answers
The biggest upgrade (and time sink) I added was using our real FAQ text directly. Instead of having GPT invent answers, I pulled the top 20 real answers and stuffed them into the GPT context dynamically.
I built a quick system that:
– Parses ticket subject
– Matches it to a topic (by fuzzy keyword match or embedding similarity)
– Injects the matching FAQ into the GPT prompt like:
“You are a support rep. Here’s the official answer to this question: [markdown of the real FAQ]. Quote from it as-is when responding.”
This dropped our hallucinated answer rate by a ton. All the fake refund policies? Gone. GPT just stops guessing when you give it the real data up front.
But it made the response slower — expect 1 to 3 extra seconds per call depending on context size. Worth it, but yeah, feels sluggish sometimes when you’re watching it live. 😛
Fallback to agents when GPT is unsure
At one point I built retry logic where if GPT replied with “I’m not sure” or used hedgy language (“you might try…”), it would skip the automated comment entirely and ping an agent with a trigger.
You can detect this by checking for certain keywords in GPT output — I built a crude regex-based validator that rejects low-confidence replies based on phrases like:
– “may need to check”
– “I think it could be”
– “It’s recommended that”
When these appear, don’t post the comment. Instead, tag the ticket with something like `gpt_failed` and send a private comment like:
“GPT skipped a reply — confidence too low. Please assist manually.”
This significantly cut down weird off-topic responses. But now I get agents blaming “the bot” for skipping stuff that actually should’ve worked… so experiment with thresholds.
Work around GPT latency and duplication glitches
This is where it *really* drove me nuts. After running fine for a week, suddenly responses were duplicating — the same GPT comment posted twice within seconds. No change on the trigger logic, same system, but two identical replies every time a ticket came in.
After some debugging, I found:
– Zendesk was retrying the webhook POSTs after a delay if GPT didn’t reply fast enough.
– My GPT handler had no idempotency — so it replied every time it was hit, blindly.
Fix: create a hash of `ticket_id + description + timestamp` and store it for 5 minutes. If a new request comes in with the same hash, drop it.
Also added a mutex like lock per `ticket_id` in memory (I used Pipedream’s `steps.memory`) so I wouldn’t trigger more than one flow at once.
Still, during heavy load hours (like around noon), GPT takes longer and sometimes fails altogether. I’d say about 5% of runs still timeout or get skipped. Not perfect.
Welcome to rebuilding the same thing over and over again.