Skip to main content

Communication: open-bot-framework

1-hop view of how this service communicates with its siblings. For the full system view, see docs/architecture/service-communication.md.

Calls Out To

ServiceProtocolPurposeKey calls / endpoints
Bot backends (any registered OpenBot)HTTP POSTForward user activity to bot endpointPOST <OpenBot.endpoint> (configured per-bot in DB)
S3-compatible storageMinIO client (S3-compatible)Store conversation file attachmentsUpload to configured bucket
RedisioredisAtomic activity watermark counters (incr/get/set with 1-hour TTL)Key: <conversationId>
PostgreSQLTypeORMPersist bots, secrets, webchat channel registrationsOpenBot, OpenBotSecret, WebChatChannel entities

Called By

CallerProtocolHow
hbf-webchat (or any DirectLine-compatible browser widget)HTTP + WebSocketDirectLine 3.0 protocol: token generate/refresh, conversation create/get, activity send/upload; WebSocket stream for bot replies
hbf-bot (or any registered bot backend)HTTP POSTBot replies via POST /v3/conversations/:id/activities/:actId using an OAuth2 client-credentials access token
Ops / admin toolingHTTP RESTBot and webchat channel CRUD via /bots and /bots/:botId/webchat

Contracts

Inbound — webchat client

DirectLine 3.0 endpoints. All require Authorization: Bearer <token> (DirectLine token or webchat site secret).

POST /v3/directline/tokens/generate — exchange webchat site secret for a DirectLine token:

Request:  { "user": { "id": "string", "name": "string" } }
Response: { "conversationId": "string", "token": "string", "expires_in": 3600 }

POST /v3/directline/conversations — create conversation:

Request:  { "user": { "id": "string" } }
Response: { "conversationId": "string", "token": "string", "expires_in": 3600, "streamUrl": "wss://..." }

POST /v3/directline/conversations/:id/activities — user sends activity:

Request:  Bot Framework Activity (botframework-schema)
Response: { "id": "<conversationId>|0000001" }

WebSocket stream (SOCKET_PORT, default 1992): client connects to streamUrl with ?t=<token>. Server pushes Transcript objects (array of activities) as JSON strings.

Inbound — bot backend reply

POST /v3/conversations/:id/activities/:actId — bot replies:

Request headers: Authorization: Bearer <access_token>  (obtained via /oauth2/v2.0/token)
Request body: Bot Framework Activity
Response: { "id": "<conversationId>|<watermark>" }

POST /oauth2/v2.0/token — bot obtains access token (client credentials):

Request:  { "grant_type": "client_credentials", "client_id": "<botHandle>", "client_secret": "<plainSecret>" }
Response: { "access_token": "string", "token_type": "Bearer", "expires_in": 3600 }

Outbound — forwarding user activity to bot

POST <OpenBot.endpoint> — HTTP POST to bot's registered endpoint:

Content-Type: application/json
Body: Bot Framework Activity (enriched with id, timestamp, serviceUrl, conversation)
Timeout: 5000ms

Flows Involving This Service

  • Message Processing — open-bot-framework replaces the hosted Direct Line in this flow for self-hosted deployments

Confidence

  • Bot backend (HTTP forward): high (explicit httpService.post(targetBot.endpoint, ...) with 5 s timeout)
  • S3 storage: high (MinIO client, configured via STORAGE_* env vars)
  • Redis: high (ioredis, REDIS_URI env var, falls back to in-memory if unavailable)
  • PostgreSQL: high (TypeORM entities, TYPEORM_* env vars)
  • No Bull queues, no Redis pub/sub, no Socket.IO inter-service connections detected