Skip to main content

Architecture: hbf-lcm

C4 Component Diagram

Key Flows

Livechat Request (end-user requests human agent)

  1. hbf-bot sends POST /livechat-requests (LCM JWT token) with the end-user and organization details.
  2. LivechatCoreController.postRequest() calls LivechatCoreService.getOrganizationCluster(orgId) to resolve the mode (PUBLIC or SEMI-PRIVATE).
  3. The appropriate RestService.saveAndSendRequest() persists the LivechatRequest to MySQL.
  4. OutgoingService emits a sendEvent event via EventEmitter, which SocketsGateway forwards to the organization room — all connected agents for that org receive the new request notification.

Agent Accepts Request and Starts Conversation

  1. Agent's hbf-console socket sends an event with type ACCEPT_REQUEST and the request id.
  2. SocketsGateway.receiveEvent() delegates to IncomingService.onReceiveEventFromAgent().
  3. The IncomingService transitions the request to ACCEPTED, creates a LivechatConversation, and saves the agent as a participant.
  4. Both the bot (via BotClientService) and connected agents (via sendEvent through the gateway) are notified of the conversation start.

Message Flow (agent to end-user)

  1. Agent sends message socket event with livechatConversation.id and text.
  2. SocketsGateway.receiveMessage() calls IncomingService.onReceiveMessageFromAgent().
  3. The service persists the LivechatMessage, then calls BotClientService to push the message to hbf-bot.
  4. The gateway also emits message to the conversation's agent rooms so all participants see the message.

Message Flow (end-user to agent, via hbf-bot)

  1. hbf-bot sends POST /organizations/:orgId/livechat-messages (LCM JWT token).
  2. LivechatCoreController.postMessage() calls RestService.saveAndSendMessage().
  3. The message is persisted, then a sendMessage event is emitted via EventEmitter.
  4. SocketsGateway.sendMessage() delivers it to the agent room.

Monitor: Request Expiry

  1. MonitorService runs on MONITOR_INTERVAL_SECONDS interval.
  2. It acquires a pessimistic DB lock via LivechatEnvironment to prevent duplicate runs in multi-instance deploys.
  3. For each NEW livechat request, it checks the per-tenant plugin expiration threshold (from hbf-core, with fallback to MONITOR_REQUEST_EXPIRATION_FALLBACK_SECONDS).
  4. If now - requestedDate > threshold, it calls handleRequestMissed() which sets the request to MISSED and notifies both the bot and agents.

Socket Room Model

Each connected agent socket joins three room types on authentication:

  • Personal room: orgId:userId — targeted events for this agent only.
  • Organization room: orgId — broadcasts to all agents in the org.
  • Group rooms: one per group the agent belongs to in this org.

Outbound events use server.to(room).emit(channel, data). This room model scales horizontally via the Redis adapter when REDIS_ENABLE=true.