Multi-Channel AI Support Triage System
Unified Gmail, Instagram, and web form tickets with GPT-4 classification, sentiment analysis, and token bucket rate limiting. 35% auto-resolved.
73% faster
35% auto-resolved
The Client's Problem
My Approach
The Workflow Breakdown
Gmail Trigger polls for new unread emails to support@company.com every minute, pulling full message content including headers, body, thread metadata, and label assignments.
Helpdesk Webhook receives Instagram DM tickets forwarded from the client's helpdesk platform via HTTP POST. The payload includes customer handle, conversation history, any tags applied by the helpdesk, and previous contact count.
Website Form Webhook receives contact form submissions from the client's website, capturing name, email, subject/topic selection, message body, page URL, and UTM attribution data for marketing source tracking.
Normalize Email code node parses the Gmail payload. It extracts sender name and email from the From header, handling both `"Name" <email>` and plain email formats. It strips HTML from the body if no plaintext version is available, decoding HTML entities and removing style and script blocks. Messages over 3,000 characters are truncated to control downstream token usage. Output conforms to the unified ticket schema.
Normalize Helpdesk code node maps the helpdesk JSON structure to the same unified schema. It handles field naming variations across helpdesk platforms (Gorgias uses `customer_name`, Zendesk uses `contact.name`, Freshdesk uses `sender.username`). It also pulls the previous contact count for repeat-contact detection, which feeds into priority scoring.
Normalize Form code node standardizes form submissions. It handles both single-field full names and split first/last name fields, maps topic dropdown selections to subject lines, and preserves referrer URL, user agent, IP country, and UTM source data for marketing attribution and fraud detection.
Rate Limiter code node implements a token bucket algorithm using n8n workflow static data for persistence across executions. The bucket holds 20 tokens and refills proportionally over a 60-second window. Each API request consumes one token. When the bucket is empty, the node calculates the wait time until the next token becomes available and applies exponential backoff with random jitter (up to 500ms). After 5 consecutive retries, the request passes through with a monitoring flag to prevent indefinite blocking.
Build Classification Prompt code node constructs the full OpenAI payload as a two-message conversation. The system prompt defines the AI's role as a senior support specialist, lists all eight classification categories with boundary descriptions, defines four sentiment levels with behavioral indicators, provides response-drafting rules (tone matching, word limits, category-specific instructions like "always reference the order number for order issues"), and includes three diverse few-shot examples covering urgent shipping, routine account inquiries, and angry complaints. The user prompt injects the actual ticket data. Temperature is set to 0.3 for classification consistency, and JSON response format is enforced via the `response_format` parameter.
OpenAI HTTP Request sends the constructed payload to the GPT-4 Chat Completions endpoint via authenticated POST. The Authorization header is set via the httpHeaderAuth credential. Timeout is configured at 30 seconds to handle occasional API latency without blocking the workflow.
Parse Classification code node extracts the JSON from the API response content. It validates all required fields against allowlists (8 valid categories, 4 valid sentiments, 4 valid priorities). If the AI returns an unexpected value, the node defaults gracefully rather than failing — for example, an unrecognized category defaults to `order_issue` with an internal note flagging the default. It also calculates processing time from ticket receipt to classification completion and computes estimated API cost from token usage (prompt tokens at $0.03/1K, completion tokens at $0.06/1K).
Switch Router evaluates the parsed classification output and routes to one of four output branches. The first branch catches `priority === "critical"` or `priority === "high"`. The second catches `category === "account"` or `category === "product_question"`. The third catches `category === "complaint"`. The fourth is the fallback for all remaining tickets.
Escalate Urgent (Slack) posts a rich Block Kit message to #support-urgent. The message includes a header with priority level and category, a section with customer details and contact info, the original message quoted in a block, a divider, the AI draft response, internal notes and suggested tags, and an actions block with "Claim Ticket" (primary style) and "Send AI Draft" buttons.
Auto-Respond Routine (Gmail) sends the AI-drafted response directly to the customer's email address. The subject line is prefixed with "Re:" for thread continuity in the customer's inbox. The sender name is set to "Support Team" and reply-to points to support@company.com.
Flag Complaint (Slack) posts to #support-escalations with a warning header, full complaint context including the customer message, the AI's suggested response (explicitly marked for review before sending), and internal notes giving the senior agent full context before they engage with the customer.
Standard Queue (Slack) posts a formatted text summary to #support-queue. The message includes priority badge, ticket ID, category, customer name and channel, subject line, sentiment and confidence score, and a truncated version of the AI draft (first 300 characters) for quick agent scanning.
Log to Google Sheets appends a row for every processed ticket regardless of routing path. The row captures 16 columns: timestamp, ticket ID, channel, customer name, customer email, subject, category, sentiment, priority, AI confidence, processing time in milliseconds, total tokens used, estimated API cost, tags (comma-separated), internal notes, and resolution status (defaulting to "open" for downstream tracking).
Results & Impact
- Average response time: 18 hours reduced to 3.8 minutes for urgent tickets
- Ticket resolution: Zero tickets falling through cracks — 100% of incoming messages
- Auto-resolution rate: 35% of all tickets handled without any human intervention,
- Support team capacity: Effectively doubled — the same 3-person team now handles
- Customer satisfaction (CSAT): Improved from 3.2 to 4.6 out of 5 within 90 days
- AI classification accuracy: 94% agreement with human review after a 60-day
- Cost per ticket: Approximately $0.03 for AI classification, far below the cost
Technical Highlights
- Three-channel normalization into a unified ticket schema, enabling fully channel-agnostic
- Sophisticated AI prompt engineering with eight category definitions, four sentiment tiers,
- Token bucket rate limiter using n8n workflow static data for cross-execution persistence,
- Four-tier intelligent routing: auto-respond for routine inquiries, standard queue for
- Sentiment-aware response drafting that adjusts tone from professional to empathetic based
- Comprehensive ticket logging to Google Sheets capturing 16 data points per ticket, enabling
- Structured error handling with severity classification — API failures flagged as high,
Tools Used
n8n, OpenAI GPT-4 API, Gmail API (IMAP polling), Slack API (Block Kit), Google Sheets API, Webhooks (helpdesk + contact form), JavaScript, Token Bucket Algorithm