Now opens a blank article editor modal with the category pre-selected (stored in localStorage). You can fill in the article details and create a new article directly from the folder view without navigating away.
alps

QUESTION_ROUTING_GUIDE

5 min readInvalid Date6 views

Chat Message → Question → Inbox Routing Guide

Overview

This guide shows how to set up a workflow that:

  1. Listens for customer messages via the chat widget
  2. Asks the customer a follow-up question
  3. Routes the conversation to different inboxes based on their answer

Real Inbox IDs

  • <strong>Billing:</strong> <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">0zCg6Hso9i1MW38hHCA7</code>
  • <strong>Technical Support:</strong> <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">TF7K19mYx9cg3xFrCevu</code>

Workflow Setup

Step 1: Create Workflow Structure

Create a workflow with these nodes in sequence:

plaintext
ask_question → condition → route_to_inbox (billing or technical)

Step 2: Configure ask_question Node

json
{
  "nodeId": "ask-node",
  "type": "ask_question",
  "data": {
    "question": "Which category does your issue fall into?\n1. Technical Support\n2. Billing\n3. General Inquiry",
    "variableName": "issue_category"
  },
  "nextNodeId": "condition-node"
}

<strong>What this does:</strong>

  • Shows a question to the customer in the widget
  • Pauses the workflow waiting for their response
  • Stores their answer in <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">issue_category</code> variable

Step 3: Configure Condition Node

json
{
  "nodeId": "condition-node",
  "type": "condition",
  "data": {
    "field": "issue_category",
    "operator": "contains",
    "value": "2",
    "truePath": "route-billing",
    "falsePath": "route-tech"
  },
  "nextNodeId": null
}

<strong>What this does:</strong>

  • Checks if the answer contains "2"
  • If yes (contains "2") → goes to <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">route-billing</code>
  • If no (doesn't contain "2") → goes to <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">route-tech</code>

Step 4: Configure Route Nodes

<strong>Route to Billing:</strong>

json
{
  "nodeId": "route-billing",
  "type": "route_to_inbox",
  "data": {
    "inboxId": "0zCg6Hso9i1MW38hHCA7"
  },
  "nextNodeId": null
}

<strong>Route to Technical Support:</strong>

json
{
  "nodeId": "route-tech",
  "type": "route_to_inbox",
  "data": {
    "inboxId": "TF7K19mYx9cg3xFrCevu"
  },
  "nextNodeId": null
}

Testing the Workflow

Test Steps

  1. <strong>Create the workflow</strong> - Add all 4 nodes as shown above
  2. <strong>Activate the workflow</strong> - Toggle it on in settings
  3. <strong>Send a test message</strong> - Use the test widget or real widget

- Click "Chat with us"<br> - Enter your name and email<br> - Send any message

  1. <strong>Answer the question</strong> - A question should appear in the widget

- Answer with "2" to test Billing routing<br> - Answer with "1" to test Technical Support routing

  1. <strong>Check the inbox</strong> - Open the inbox app

- The conversation should appear in the selected inbox

Test Conversation Flow

plaintext
Customer → Widget: "I need help"
         ↓
Workflow: Questions appears
         ↓
Customer: Answers "2" (Billing)
         ↓
Workflow: Routes to Billing inbox
         ↓
Agent: Sees conversation in Billing inbox

How It Works (Behind the Scenes)

plaintext
1. Customer sends message to widget
   POST /api/v1/message/customer
   
2. Conversation created in Firestore
   
3. Workflow triggered by middleware
   triggerWorkflowOnNewConversation
   
4. ask_question node executes
   - Sends question via Pusher
   - Updates conversation: awaitingQuestion = true
   - Returns null (pauses workflow)
   
5. Widget receives question via Pusher
   - Displays question to customer
   - Listens for answer
   
6. Customer answers question
   POST /api/v1/workflow/question/answer
   { conversationId, answer: "2" }
   
7. Backend resumes workflow
   - Updates conversation with answer
   - Continues from questionNextNodeId
   
8. Condition node executes
   - Checks: answer contains "2"?
   - Routes to route-billing or route-tech
   
9. route_to_inbox node executes
   - Updates conversation.inboxId
   - Sends Pusher event: conversation:updated
   - Triggers activity log
   
10. Inbox app receives update via Pusher
    - Conversation appears in selected inbox
    - Agent can see it and respond

Customization

Change the Question

In the <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">ask_question</code> node data:

json
{
  "question": "What's your issue?\n1. Account\n2. Billing\n3. Technical",
  "variableName": "issue_type"
}

Change the Routing Condition

To route based on different answers:

json
{
  "field": "issue_category",
  "operator": "contains",
  "value": "billing",  // Route if answer contains "billing"
  "truePath": "route-billing",
  "falsePath": "route-tech"
}

Add More Than 2 Routes

Use a send_message node to tell customer they'll be routed:

json
{
  "nodeId": "send-node",
  "type": "send_message",
  "data": {
    "message": "Thank you! Routing you to the {{issue_category}} team..."
  },
  "nextNodeId": "route-node"
}

Routing Operators

The condition node supports:

  • <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">equals</code> - Exact match
  • <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">not_equals</code> - Not exact match
  • <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">contains</code> - Substring match (recommended for answers like "2")
  • <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">starts_with</code> - Beginning match

Real-World Examples

Example 1: Simple Yes/No Routing

plaintext
Question: "Is this a billing issue? (yes/no)"
├─ Answer: "yes" → Billing inbox
└─ Answer: "no" → Technical Support inbox

Example 2: Multi-Option Routing

plaintext
Question: "Choose: 1=Sales, 2=Support, 3=Billing"
├─ Answer contains "1" → Sales inbox
├─ Answer contains "2" → Support inbox
└─ Answer contains "3" → Billing inbox

Example 3: Free-Form Routing

plaintext
Question: "What's your main concern?"
├─ Answer contains "payment" → Billing inbox
├─ Answer contains "error" → Tech Support inbox
└─ Default → General inbox

Test Results

All routing scenarios tested and passing:

plaintext
✅ ask_question pauses workflow
✅ condition routes when answer contains "2"
✅ condition routes to tech support when answer doesn't contain "2"
✅ complete flow with send_message, ask_question, condition, routing
✅ partial text match works ("2" in version "2.5")
✅ multiple numeric answers route correctly

Troubleshooting

Question doesn't appear in widget

<strong>Check:</strong>

  1. Is the workflow activated? (toggle in settings)
  2. Is the ask_question node in the correct position in the flow?
  3. Do the <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">nodeId</code> and <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">nextNodeId</code> values match the flow?

<strong>Test:</strong>

bash
npm test -- --testNamePattern="ask_question pauses"

Answer doesn't route correctly

<strong>Check:</strong>

  1. Is the condition field name correct? (matches variableName in ask_question)
  2. Is the operator correct? (should be "contains" for "2")
  3. Are the paths correct? (truePath and falsePath match nodeIds)

<strong>Test:</strong>

bash
npm test -- --testNamePattern="condition routes"

Conversation appears in wrong inbox

<strong>Check:</strong>

  1. Did the condition actually match?
  2. Is the inboxId in route<em>to</em>inbox node correct?
  3. Is the inbox ID a real inbox in the workspace?

<strong>Verify:</strong>

bash
node test-inboxes.js
# Should show both Billing and Technical Support inboxes

Files & Documentation

  • Test file: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">backend/tests/integration/question-answer-routing.test.js</code>
  • Routing guide: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">INBOX<em>ROUTING</em>GUIDE.md</code>
  • Test results: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">WIDGET<em>ROUTING</em>TEST_RESULTS.md</code>
  • Implementation: <code style="font-family:ui-monospace,monospace;background:#f1f5f9;color:#dc2626;padding:0.1em 0.35em;border-radius:3px;font-size:0.875em">backend/services/workflowEngine.js</code>

Next Steps

  1. ✅ Create workflow with ask_question
  2. ✅ Add condition for routing logic
  3. ✅ Configure route<em>to</em>inbox nodes
  4. ✅ Activate workflow
  5. ✅ Test via widget
  6. ✅ Monitor routing accuracy
  7. ⬜ Refine question based on real usage
  8. ⬜ Add more workflow nodes (send messages, delays, etc.)

Summary

You now have a complete workflow system that:

  • Listens for messages
  • Asks qualifying questions
  • Routes conversations to the right inbox
  • All in real-time via Pusher

This is production-ready and tested with 6 passing integration tests.

Did this answer your question?