How a ticket gets read
The router can only sort what reaches it. So the first job is turning every way a customer can ask for help into one clean ticket. There are three ways a ticket gets in: a customer emails your support address, fills in the form on your site, or sends a chat message. The first is the most common. The other two exist because customers reach for whatever’s in front of them — and the same person will often try all three about the same problem. Once a ticket is in, one small model call reads it: what’s it about, how urgent is it, and how does the customer sound?
Key takeaways
- Three intake lanes feed one queue: an email inbox, a web form, and a chat lane.
- Each new ticket is written once, given an id, and checked against recent tickets so duplicates merge.
- One Bedrock Haiku 4.5 call reads each ticket and returns topic, urgency, and tone.
- The model only reads. It never writes a reply — that stays with a person.
- A burst of tickets queues up in SQS so nothing is dropped when a busy hour hits.
Three lanes into one queue
Lane 1: the email inbox (the lane most teams live in)
Set up a dedicated inbound address — something like support@your-company.com — via Amazon SES. SES is Amazon’s email service; here it’s receiving mail, not sending it. When a customer emails that address, SES writes the raw email to s3://tr-raw-mail/. The S3 PUT triggers an intake Lambda. The Lambda reads the email, pulls out the sender, the subject, and the body (and strips the long quoted history off replies so the router reads the new message, not the whole thread), and creates one ticket with an id.
This lane covers the bulk of real support. People email. They reply to their own ticket. They forward something a colleague sent. The intake treats a reply to an existing ticket as part of that ticket, not a brand-new one, by matching the email’s thread headers against tickets already in flight.
Lane 2: the web form
The “Contact support” form on your site posts straight to a Lambda Function URL — a plain web address that runs a Lambda, with no API Gateway in front of it. The form sends the customer’s name, email, a subject, and a message. The intake reads those fields and creates a ticket in exactly the same shape as the email lane, so everything downstream treats the two identically. A simple shared secret on the form post keeps random internet traffic from creating junk tickets.
The form lane is worth having because a customer on your pricing page who hits a problem will use the form in front of them rather than hunt for an email address. Catching them there means the ticket arrives with the page they were on already attached.
Lane 3: the chat lane
If you run a chat widget, finished conversations can become tickets too. When a chat ends without resolution — the visitor left, or the chat tool couldn’t answer — the tool posts the conversation to another Function URL. The intake folds the back-and-forth into one ticket body so the router reads it like any other message. This is the most optional of the three lanes; a team without chat loses nothing.
Reading the ticket: one small model call
However a ticket arrived, it lands on an SQS queue. SQS is a simple waiting line for work; if a hundred tickets arrive in a minute, they line up instead of overwhelming anything. A read Lambda takes tickets off the queue one at a time and makes a single Bedrock Haiku 4.5 call. The prompt is short: “Read this support ticket. Return JSON only. Give the topic from this list, an urgency of low, medium, or high, and a tone of calm, confused, or angry. If you are unsure of the topic, say unsure.” The list of topics comes from the rules sheet, and a handful of labelled examples are included so the model has a few real tickets to pattern-match against.
That one call is the only place a model touches a ticket. It reads — topic, urgency, tone — and writes those three tags back onto the ticket. It does not draft a reply, suggest an answer, or message the customer. Everything after this point is plain Python working from those three tags, which is what the next post covers.
Why everything funnels to one queue
Three lanes in, but only one queue the router reads from. That’s deliberate. If each lane routed on its own, “why did this ticket go there?” would mean checking three code paths. Funneling everything to one queue means there is exactly one ticket per request, in one shape, read by one model call, sorted by one set of rules. The lanes are first-class for getting tickets in, but they all become the same ticket on the way.
Next post: how the router takes the topic, urgency, and tone and turns them into one of four moves.
All posts