Skip to main content

Developer Guide

This guide covers the technical implementation of Assistant Routing, including data models, the webhook API, and the routing service architecture.

Architecture Overview

Assistant Routing connects incoming webhook messages to CX Assistants through a multi-step process:

Data Model

AssistantRoute

The AssistantRoute model maps message metadata to Assistants using JsonLogic expressions.

FieldTypeRequiredDescription
idintegerAutoPrimary key
assistantForeignKeyYesReference to the Assistant that handles matching messages
tagsJSONYesJsonLogic expression for matching message tags
created_atdatetimeAutoTimestamp when the route was created
updated_atdatetimeAutoTimestamp when the route was last updated

Django Model Definition:

class AssistantRoute(TimestampedModel):
assistant = models.ForeignKey(Assistant, on_delete=models.CASCADE)
tags = models.JSONField(default=dict, blank=True)

def __str__(self) -> str:
return f"{self.assistant} - {self.tags}"

ConversationAssistantThread

Tracks which Assistant is active for a given conversation.

FieldTypeRequiredDescription
idintegerAutoPrimary key
assistant_threadForeignKeyYesReference to the AssistantThread
conversationForeignKeyYesReference to the Conversation
deactivated_atdatetimeNoWhen the assistant was deactivated for this conversation
created_atdatetimeAutoTimestamp when the association was created
updated_atdatetimeAutoTimestamp when the association was last updated

Message

The internal representation of an incoming message used by the routing service.

FieldTypeDescription
external_conversation_idstringThe CX platform's conversation identifier
message_idstringUnique message identifier
timedatetimeMessage timestamp
author_idstringIdentifier of the message author
sourceMessageSourceEither visitor or agent
textstringMessage content
tagsdictMetadata key-value pairs used for routing

API Reference

Webhook Endpoint

Receives messages from the CX platform and triggers routing.

POST /api/v2/assistants/webhook
GET /api/v2/assistants/webhook

This endpoint accepts both GET and POST methods to accommodate different CX platform webhook implementations.

Request Flow

  1. Admin Service receives the webhook from the CX platform in the platform's native format
  2. Admin converts the message to the generic format
  3. Admin forwards the message to Backend via this endpoint
  4. Backend processes the message asynchronously

Response

The endpoint returns immediately with HTTP 200 OK. Processing happens asynchronously in the background.

HTTP/1.1 200 OK
info

The webhook endpoint returns immediately to prevent timeout issues with CX platforms. Message processing and Assistant evaluation happen asynchronously.

Routing Service

The AssistantRoutingService is responsible for:

  1. Finding the active Assistant for a conversation
  2. Matching message tags against configured routes
  3. Activating/deactivating Assistants for conversations
  4. Triggering Assistant evaluation for visitor messages
  5. Sending responses back to the CX platform

Key Methods

handle_message

async def handle_message(
self,
message: Message,
platform_adapter: CxPlatformAdapter
) -> None

Main entry point for processing incoming messages. Only processes messages from visitors (not agents).

_find_active_assistant

async def _find_active_assistant(
self,
conversation_id: str,
tags: dict
) -> Assistant | None

Determines which Assistant should handle the conversation:

  1. Checks for an existing active Assistant
  2. Finds a route matching the message tags
  3. Handles activation/deactivation logic based on route changes

Route Matching Logic

Routes are matched using JsonLogic expressions evaluated against message tags:

async def find_assistant_for_route(
self,
tags: dict,
include_details: bool = True
) -> Assistant | None:
orm_assistant_routes = orm.AssistantRoute.objects.filter().all()
async for orm_assistant_route in orm_assistant_routes:
if jsonLogic(orm_assistant_route.tags, tags):
return await _assistant_from_orm(orm_assistant_route.assistant)
return None

The first route that matches (in database order) is used.

Platform Adapters

Platform adapters implement the CxPlatformAdapter interface to send responses back to the CX platform:

class CxPlatformAdapter(ABC):
@abstractmethod
async def send_message(
self,
text: str,
reply_to_message: Message,
agent_id: str | None = None
) -> None:
pass

@abstractmethod
async def transfer_to_human(
self,
external_conversation_id: str
) -> None:
pass

Each supported CX platform has its own adapter implementation that handles:

  • Authentication with the platform API
  • Message formatting specific to the platform
  • Error handling and retries

Implementation Details

Activation and Deactivation

When a route matches for the first time:

  1. An AssistantThread is created or retrieved for the conversation
  2. A ConversationAssistantThread record links the thread to the conversation
  3. The Assistant is now "active" for this conversation

When the route no longer matches (tags changed):

  1. The ConversationAssistantThread.deactivated_at field is set
  2. The Assistant stops processing messages for this conversation
  3. If a different route matches, the new Assistant is activated

Message Processing

Only visitor messages trigger Assistant evaluation. Agent messages are ignored by the routing service but are still ingested and stored for conversation context.

Impersonation

Assistants can be configured with an impersonation_agent_id to send messages as a specific agent in the CX platform. This is useful for:

  • Making bot messages appear to come from a specific team member
  • Maintaining consistent identity across automated responses

Source Code References

ComponentLocation
AssistantRoute modelassistants/models.py:369-374
AssistantRoutingServicebackend/domains/assistants/services/routing.py
AssistantRepositorybackend/domains/assistants/repositories/assistant.py
WebhookServicebackend/domains/assistants/services/webhook.py
Webhook endpointbackend/domains/assistants/routes.py:172-185
Platform adaptersbackend/domains/assistants/services/platforms/