Communication: hbf-bot
Inbound webhooks, outbound service calls, and message-bus usage. Full platform topology:
docs/architecture/deployment.md
Inbound Webhooks
All routes are registered by app/system/HBFEndpointSystem.ts and handled by BaseChannel.process().
No inbound auth guards on these routes -- each upstream platform validates its own payload.
| Method | Route | Channel class | Notes |
|---|---|---|---|
GET/POST | /api/fb-events | FacebookChannel | GET = hub verification; POST = events |
GET/POST | /api/instagram-events | InstagramChannel | GET = hub verification; POST = events |
POST | /api/whatsapp-events | WhatsAppChannel | Validation token check in channel |
POST | /api/viber-events/ | ViberChannel | Raw body preserved for HMAC; trailing slash required |
GET/POST | /api/slack-events | SlackChannel | GET = challenge; POST = events |
POST | /api/msteams-events | MicrosoftChannel | Teams |
POST | /api/webchat-events | MicrosoftChannel | Web Chat (OBF) |
POST | /api/livechat-events/ | LiveChatGatewayChannel | LCG agent messages |
POST | /api/unity-events | UnityChannel | Unity game channel |
POST | /api/events | ApiChannel | Generic REST channel |
POST | /api/monitoring-events | MonitoringChannel | UptimeRobot health probes |
POST | /api/post-events | PostChannel | POST channel |
POST | /api/zendesk-events | ZendeskChannel | Zendesk |
Management (shared-secret protected, see docs/auth.md):
| Method | Route | Handler |
|---|---|---|
POST | /api/tenants | TenantsController -- reload/force-reload a tenant |
DELETE | /api/tenants/cache | TenantsController -- evict one tenant or flush all |
GET | /api/status | StatusController -- loaded tenant count + list |
GET | / | Homepage -- status page (CORS-restricted by homePageAllowedOrigin) |
Outbound Calls
hbf-core (via @helvia/hbf-core-api)
Client: HBFCoreApi (instantiated in multiple places with HBFCoreAuth DI token: CORE_BASEURL / CORE_TOKEN).
| Operation | Client | Called from |
|---|---|---|
Fetch BotDeployment (full graph) | BotDeploymentClient | HBFCoreBotDeploymentStorage |
| Fetch tenant timestamp for cache validation | BotDeploymentClient.getTenantTimestampByHandle | HBFCoreBotDeploymentStorage |
Find fallback deployment via MessagingApp | MessagingAppsClient.findByAppId | HBFCoreBotDeploymentStorage |
Get/create/update Subscriber blackboard | SubscribersClient | CoreSubscribersStorage |
Create/update ChatSession, batch messages, variables | ChatSessionsClient | ChatSessionsRepository |
| Update message tags | AnalyticsClient.updateMessageTags | ChatSessionsRepository |
| NLU process (HBF_CORE pipeline mode) | NlpPipelinesClient.process | ExternalNLU |
| Group CRUD | GroupsClient | HBFCoreGroupRepository |
| Handover | HandoverClient | HandoverRepository |
hbf-nlp
Direct HTTP via HttpRequest.post (no retry wrapper at the client level).
| Endpoint | Purpose | Called from |
|---|---|---|
POST /tenants/{tenantId}/process | NLU intent detection | ExternalNLU |
POST /v2/generation | LLM generation (LLMNode) | GenerationRequestHandler |
POST /llm-request | LLM request (built-in function path) | buildInFunctions |
Auth: Bearer CORE_TOKEN on all NLP calls.
hbf-lcg (via LiveChatGatewayClient)
File: app/clients/livechat/LiveChatGatewayClient.ts
DI token: LiveChatGatewayAuth (LCG_BASEURL / LCG_TOKEN or falls back to CORE_TOKEN).
All calls are plain HttpRequest with no built-in retry. Errors are logged and re-thrown.
| Endpoint | Purpose |
|---|---|
POST /requests | Create a new live chat request |
POST /requests/{id}/close | Close a live chat request |
GET /requests/{id}/availability | Check agent availability |
GET /requests/{id}/state | Get subscriber state |
GET /requests/{id}/metrics | Get queue metrics |
POST /messages | Send message to live chat |
helvia-rag-pipelines (via RagPipelinesClient)
File: app/clients/rag/RagPipelinesClient.ts
Static class, no DI. URL and per-pipeline bearer token come from the conversation node action params at runtime.
| Endpoint | Purpose |
|---|---|
POST /pipelines/{pipelineId}:search | Semantic search in a RAG pipeline |
On failure: logs error, returns undefined (silent). See docs/resilience.md.
hbf-event-publisher (via EventPublisherClient)
File: app/util/EventPublisherClient.ts
DI token: EventPublisherOptions (env: EVENT_PUBLISHER_BASEURL).
Auth: passthrough CORE_TOKEN as Bearer.
| Endpoint | Trigger type | When |
|---|---|---|
POST /connectors/flows:trigger | automated-answer-triggered | After automated answer with an activity set |
POST /connectors/flows:trigger | livechat-request-missed | LCG missed request |
POST /connectors/flows:trigger | livechat-conversation-finished | LCG conversation closed |
POST /connectors/flows:trigger | survey-completed | Survey finished |
POST /connectors/flows:trigger | chat-session-completed | Chat session closed |
If baseUrl is empty, all publisher calls are silently skipped.
Kafka (KafkaEventPublisher)
File: app/kafka/KafkaEventPublisher.ts
DI token: KafkaConfig.
Publishes InteractionMetadata events (LLM, HTTP, SEMANTIC_SEARCH, VARIABLE, TAG actions) per inbound message.
| Config key | Env var | Default |
|---|---|---|
kafka.enabled | KAFKA_ENABLED | false |
kafka.brokers | KAFKA_BROKERS | (none) |
kafka.topic | KAFKA_TOPIC | hbf.interaction.metadata |
kafka.clientId | KAFKA_CLIENT_ID | hbf-bot |
kafka.ssl | KAFKA_SSL | false |
kafka.sasl.mechanism | KAFKA_SASL_MECHANISM | (none) |
Producer is idempotent. Connection is lazy (established on first publish attempt). Kafka errors do not bubble; they are logged and the publish is skipped.
Kafka message format:
key: sessionId
value: JSON(MetadataEvent)
headers: tenantId, organizationId, eventType
AWS S3 (AwsS3FileUploader)
File: app/util/AwsS3FileUploader.ts
DI token: AWSS3FileUploadOptions.
Used for file upload actions in conversation flows (e.g., user-submitted images). SDK: @aws-sdk/client-s3 + @aws-sdk/lib-storage.
| Config key | Env var |
|---|---|
aws.s3.region | (static config) |
aws.s3.bucketName | (static config) |
aws.s3.bucketDomain | (static config) |
aws.accessKeyID | (static config) |
aws.secretAccessKey | (static config) |
Redis
Client: ioredis (BotDeploymentCache, app/system/storage/BotDeploymentCache.ts).
DI token: RedisConfigurations.
| Env var | Default | Description |
|---|---|---|
REDIS_HOST | 127.0.0.1 | Redis hostname |
REDIS_PORT | 6379 | Redis port |
REDIS_PASSWORD | (empty) | Redis password |
REDIS_TLS | false | TLS flag |
REDIS_TENANT_TTL | 604800 (7 days) | TTL for cached BotDeployment keys |
Key Patterns
| Pattern | Type | Written by | Read by | TTL |
|---|---|---|---|---|
<deployment-handle> | String (JSON) | BotDeploymentCache.replaceCached | BotDeploymentCache.getCached | REDIS_TENANT_TTL |
BotDeploymentCache stores a serialised { data: BotDeployment, timestamp: Date } envelope. Cache validity is checked by comparing the stored timestamp against the tenant's updatedAt timestamp fetched live from hbf-core.
Subscriber blackboard state is stored in hbf-core (not Redis directly). Redis is used only for the BotDeployment config cache. There is no pub/sub usage.