How-To Guides

Omnichannel Support Ticket Triage with AI Routing

Triage support tickets from Zendesk and HubSpot — classify intent and sentiment with a ReAct Agent, reply on the right CRM, and notify the owning developer in Google Chat.

Automatically triage support tickets from Zendesk and HubSpot: a ReAct Agent classifies intent and sentiment, a second agent posts a reply to the correct CRM, and a third notifies the owning developer in Google Chat — all from one workflow.

What you'll build

An always-on workflow with two ingestion paths (Zendesk + HubSpot) that converge into an AI triage → reply → notify pipeline.

End-state preview of the completed omnichannel triage workflow on the canvas

Architecture at a glance

Architecture: Zendesk and HubSpot triggers feed an enrich step, then an Intent & Sentiment ReAct agent, a Ticket Commentator agent, and a Notify Developer agent that posts to Google Chat
#NodeTypePurpose
1Zendesk TriggerApp Event TriggerFires when a Zendesk ticket is created or updated
2Zendesk Ticket DetailsHTTP RequestFetches the full Zendesk ticket by ID
3Zendesk User DetailsHTTP RequestRetrieves the Zendesk requester / assignee profile
4HubSpot TriggerApp Event TriggerFires when a HubSpot ticket is created or updated
5HubSpot Ticket DetailsHTTP RequestFetches the full HubSpot ticket by ID
6HubSpot User DetailsHTTP RequestRetrieves the HubSpot contact for the ticket
7Intent & SentimentReAct AgentClassifies intent, sentiment, priority, churn risk
8Ticket CommentatorReAct AgentWrites a reply and posts to Zendesk and/or HubSpot
9Notify DeveloperReAct AgentSends a routed notification to Google Chat

Before you begin

  • A FlowGenX account with access to Design → Flow Designer → Workflow Canvas.
  • Zendesk and HubSpot connectors authorized (API token / OAuth).
  • An LLM provider API key (OpenAI, Anthropic, Gemini) for the ReAct agents.
  • A Google Chat connector authorized, with access to the target space.

First time on the platform? Start with the Platform Tour quickstart — it covers navigation, the left-hand menu, and where to find Workflow Canvas, Integration Studio, and the Playground.


Step 1 — Add the Zendesk & HubSpot triggers

Goal: set up the two entry points that subscribe to ticket events from each platform. (~4 min)

  1. Drag an App Event Trigger onto the canvas and select Zendesk as the application.
  2. Under Credentials / Auth, select your Zendesk connector and add its API key to authenticate the subscription.
  3. Choose the ticket event(s) to subscribe to (e.g. ticket.created, ticket.updated), then apply.
  4. Drag a second App Event Trigger and repeat for HubSpot, subscribing to its ticket events.
  5. Switch each trigger to Listen / test mode and create a test ticket on each platform to confirm a live event arrives.
App Event Trigger configured for Zendesk ticket events

Step 2 — Fetch ticket details with HTTP Request

Goal: retrieve the full ticket record — subject, body, priority, tags — from each platform's API. (~4 min)

  1. Drag an HTTP Request node after the Zendesk trigger and connect the edges.
  2. Configure it to call GET /api/v2/tickets/{ticket_id}, mapping ticket_id from the trigger event with a JEXL expression.
  3. Add your Zendesk auth in the headers, then click Apply.
  4. Drag a second HTTP Request after the HubSpot trigger, calling GET /crm/v3/objects/tickets/{ticket_id}.
  5. Map the HubSpot ticket ID from its trigger event, add HubSpot auth, then click Apply.
Zendesk ticket-details HTTP Request endpoint configuration HubSpot ticket-details HTTP Request endpoint configuration

Tip — key fields to capture. Zendesk returns subject, description, priority, status, tags; HubSpot returns subject, content, hs_ticket_priority, hs_pipeline_stage. The agents use these downstream.

Verify: a test run returns the complete ticket object (subject and body included) in each HTTP node's output.

Step 3 — Fetch the requester's user profile

Goal: look up the person who submitted or is assigned to the ticket so the reply can be personalized. (~3 min)

  1. Drag an HTTP Request node after the Zendesk ticket-details node and connect the edges.
  2. Call GET /api/v2/users/{user_id}, mapping requester_id from the ticket-details output.
  3. Repeat on the HubSpot path with GET /crm/v3/objects/contacts/{contact_id}, mapping the contact ID from the ticket associations.
  4. Add the matching auth headers on each node and apply.
Zendesk user-details HTTP Request endpoint HubSpot contact-details HTTP Request endpoint

Verify: a test run returns the requester's profile — name, email, organization — in the node output.

Step 4 — Configure the Intent & Sentiment ReAct Agent

Goal: classify the ticket and assign a priority — forcing a mandatory classify_intent tool call first. (~7 min)

  1. Drag a ReAct Agent onto the canvas after the HTTP nodes, and connect both paths (Zendesk and HubSpot) into it so they converge here.
  2. Under Models → LLM Model, choose or create a model.
  3. Under Tools, attach the classify_intent tool so the agent returns a structured classification.
  4. Under Prompts, paste a system prompt that forces the tool call first (see below).
  5. Under Schema → Input, define zendesk_subject, zendesk_description, hubspot_subject, hubspot_description and map them from the HTTP outputs (leave the unused platform's fields empty).
  6. Under Schema → Output, define the JSON fields the agent returns (see below), then click Apply.
Intent & Sentiment ReAct Agent configuration with the classify_intent tool

System prompt — mandatory tool call (excerpt):

STEP 0 — MANDATORY: Call classify_intent before any analysis. No exceptions.
STEP A — Analyze: intent, sentiment, churn_risk, urgency_signals, error_codes,
         affected_features, summary, source.
STEP B — Priority (evaluated most-critical first):
  P0  outage / security_incident / legal / contract signals
  P1  churn_risk=true | angry or panicked | executive escalation
  P2  bug / billing / account_access (no P0–P1 trigger)
  P3  feature_request, single user
  P4  how_to, informational
No CRM/telemetry connected — score from ticket text only; say so in reasoning.

Output JSON schema:

{
  "intent": "bug_report | feature_request | billing | ...",
  "confidence": 0.0,
  "sentiment": "calm | frustrated | angry | urgent_panicked",
  "churn_risk": false,
  "urgency_signals": ["exact phrase from ticket"],
  "error_codes": ["codes found in ticket"],
  "product_hint": "product name or null",
  "affected_features": ["feature names"],
  "summary": "25-word max summary",
  "source": "zendesk | hubspot | both",
  "priority": "P0 | P1 | P2 | P3 | P4",
  "reasoning": "brief explanation of priority"
}

Intent categories:

IntentCategoryDescription
bug_reportBug / ErrorA defect or unexpected behavior
feature_requestImprovementRequest for new functionality
billingFinancialBilling errors, invoice disputes, charges
account_accessAuthCan't log in, password reset, locked account
how_toInformationalHow-to or onboarding guidance
outage_reportCriticalPlatform outage or service unavailability
security_incidentCriticalData breach, unauthorized access, threat
churn_riskRetentionSignaling intent to cancel or leave
otherGeneralDoesn't fit any category above

Priority matrix:

PriorityTrigger
P0 — CriticalOutage, security incident, legal or contract signals
P1 — Highchurn_risk=true, angry / panicked sentiment, executive escalation
P2 — MediumBug, billing, account access — no P0/P1 trigger
P3 — LowFeature request from a single user
P4 — MinimalHow-to, informational questions

Map only the populated source. A given ticket comes from one platform; leave the other platform's input fields empty. The agent sets source from whichever fields are present.

Verify: a test ticket returns the full JSON with intent, priority, and a reasoning string.

Step 5 — Configure the Ticket Commentator ReAct Agent

Goal: compose a customer reply and post it to the correct CRM with source-based routing. (~6 min)

  1. Drag a ReAct Agent after the Intent & Sentiment agent and connect the edges.

  2. Under Tools, attach both comment tools: Add a comment to a Zendesk ticket and Add comment to ticket (HubSpot).

  3. Under Schema → Input, define source, intent, sentiment, priority, summary, customer_signals, reasoning, zendesk_ticket, hubspot_ticket and map them from the previous agent and the triggers.

  4. Under Prompts, paste a reply-writing prompt with the routing logic:

    • source = zendesk → post the reply only to the Zendesk ticket.
    • source = hubspot → post the reply only to the HubSpot ticket.
    • source = both → post to both platforms using their respective ticket IDs.
  5. Under Schema → Output, define the confirmation JSON, then click Apply.

Reply-writing rules: max 3–5 sentences; tone follows sentiment (angry/panicked = extra empathy, calm = direct); P0/P1 use escalation language; address contract/churn/legal signals directly; no jargon or placeholders like [NAME]; always end with a clear next step or ETA.

{
  "reply_body": "The composed customer reply text",
  "source": "zendesk | hubspot | both",
  "zendesk_comment_posted": true,
  "hubspot_comment_posted": false,
  "suggested_status": "open | pending | solved | closed"
}

HubSpot comment association. HubSpot ticket comments are created as Notes associated to the ticket (association type 0-27 / definition 0-216). If the tool returns invalid from object type 0-46, the connector is sending the wrong object type — check the connector config.

Verify: a source=zendesk ticket shows the comment in Zendesk; source=both posts to both, reflected by the two boolean flags.

Step 6 — Configure the Notify Developer ReAct Agent

Goal: infer the issue owner from the reply and post a routed message to Google Chat. (~5 min)

  1. Drag a ReAct Agent after the Ticket Commentator and connect the edges.
  2. Under Tools, attach Create a message in a space — the agent's only tool.
  3. Under Schema → Input, define source, suggested_status, zendesk_ticket, hubspot_ticket, reply_body mapped from the previous agent.
  4. Under Prompts, paste a prompt that infers the owner from reply_body, forces the tool call, and targets your Google Chat space.
  5. Under Schema → Output, define the success / failure JSON, then click Apply.

Owner routing table (customize the mentions to your team):

Issue typeMentionResponsibility
workflow@…Automation workflow logic / node routing
hitl@…Tickets needing manual human review
io@…Data input/output and integration problems
http node@…API call failures, timeouts, bad responses
knowledgebase@…KB content gaps or retrieval failures
unclearLLM decidesNo mention match; no owner assigned
Message format:
Hey <@mention>, there is a new ticket in <zendesk|hubspot|both> — can you look into it?
Ticket: <#id | Zendesk #X & HubSpot #Y for both>
Issue:  <one-line summary from reply_body>
Status: <suggested_status>

Force the tool call. Make the prompt explicit: the agent MUST call Create a message in a space before returning any output. Otherwise a ReAct agent may answer in text and skip the post entirely.

Step 7 — Save and publish

Goal: persist your work and promote it so the triggers can fire it. (~2 min)

  1. Click Save (bottom-left of the canvas) — the workflow is saved as a draft.
  2. Click Publish (or Republish on later edits).
  3. Wait for the success toast: "Workflow published successfully."
Saving and publishing the workflow

Always re-publish after edits. Saved-but-unpublished changes won't run when an event fires. If the workflow looks correct but isn't executing, confirm the latest version is published.

Step 8 — Trigger and test with a real ticket

Goal: create a ticket on each platform and watch the agents reason and act. (~3 min)

  1. Create a test ticket in Zendesk with a clear subject and body (e.g. a billing question).
  2. Confirm the Zendesk trigger fires, both HTTP nodes enrich the ticket, and the Intent & Sentiment agent calls classify_intent.
  3. Confirm the Ticket Commentator posts a reply on the Zendesk ticket and the Notify Developer agent posts to Google Chat.
  4. Repeat with a HubSpot ticket to verify the second ingestion path end-to-end.
Agent comment posted on the ticket Notify Developer message posted to Google Chat

Tip — test multiple intents. Send one calm how_to (expect P4) and one outage_report or angry churn signal (expect P0/P1) to verify priority and owner routing both behave.

Step 9 — Monitor the execution

Goal: review run history, trace the path, and inspect node-level inputs and outputs. (~2 min)

  1. Go to Monitor → Workflow Runs.
  2. Select your omnichannel triage workflow to see its execution history.
  3. Click the run ID for the test you just executed.
  4. Review the end-to-end trace — node_name, node_type, and each node's captured input/output.
  5. Click the Intent & Sentiment agent to confirm classify_intent ran and the priority resolved as expected.
Workflow run trace in Monitor Workflow Runs

Verify: you can drill into each ReAct Agent to view its structured output — the classification JSON and the posted reply.

You're done — what's next

You've built an omnichannel support workflow that triages tickets from two platforms, replies on the right CRM, and notifies the owning developer. Keep going:

Troubleshooting

SymptomLikely causeResolution
Agent node shows a red dotModel not configured or invalid API keyOpen the node → Models → verify the key and test the connection
Agent inputs are all empty / nullJEXL expression not bound to upstream outputOpen the agent's input schema and re-map each field from the correct node
classify_intent never calledPrompt doesn't force the tool callAdd an explicit "STEP 0 — MANDATORY" instruction to call the tool first
HubSpot comment fails (0-46 error)Connector sends wrong object typeComment must be a Note (type 0-27); fix the connector or call the Notes API
No Google Chat message postedNotify agent answered in text onlyForce the tool call; confirm the Google Chat connector is authorized
Trigger never firesEvent subscription inactive or not publishedRe-check the connector subscription and click Republish

Glossary

  • App Event Trigger — an entry point that subscribes to events from an app (Zendesk, HubSpot) and starts the workflow when an event arrives.
  • HTTP Request — a node that calls an external REST API to fetch or send data (here, ticket and user details).
  • ReAct Agent — a Reasoning-and-Acting agent that calls tools to take real actions while it works through a task.
  • classify_intent — the tool the Intent & Sentiment agent calls to return a structured intent / sentiment / priority classification.
  • Source routing — logic that posts a reply to Zendesk, HubSpot, or both based on the ticket's origin.

Ask AI

FlowGenX Documentation

How can I help you?

Ask me anything about FlowGenX AI - workflows, agents, integrations, and more.

AI responses based on FlowGenX docs