Skip to main content

Data Model: open-bot-framework

Domain objects owned and used by this service. This service is a standalone DirectLine 3.0 gateway with its own PostgreSQL database (obf). It does not read hbf-core MongoDB objects directly. It has no dependency on hbf-core-api. Full platform schemas: docs/domain-model.md

Local Entities (TypeORM, PostgreSQL — obf database)

EntityTableKey fields
OpenBotopen_botid (uuid PK), handle (unique), endpoint, schemaVersion
OpenBotSecretopen_bot_secretid (uuid PK), openBotId (FK → OpenBot), secretHash, plainReducted, expiresAt
WebChatChannelweb_chat_channelid (string PK), openBotId (FK → OpenBot), name, secret1, secret2

OpenBot

A registered bot: its handle (human-readable identifier) and HTTP endpoint where activities are forwarded.

FieldTypeRequiredConstraintsNotes
iduuidyesPK, auto-generated
handlestringyesUnique index (IDX_OpenBot_handle)Pattern: /^[a-zA-Z][a-zA-Z0-9-]{2,62}[a-zA-Z0-9]$/
endpointstringyesHTTP URL of the bot backend
schemaVersionstringyesDefault: 'v1.3'Bot Framework schema version
createdAttimestamptzyesAuto-set
updatedAttimestamptzyesAuto-updated

DTO (API response): OpenBotDto — same fields, all exposed.


OpenBotSecret

A SHA-256 hashed API secret for a bot. Used for bot-to-gateway OAuth2 client credentials auth.

FieldTypeRequiredConstraintsNotes
iduuidyesPK, auto-generated
openBotOpenBotyesFK, CASCADE deleteOwner bot
descriptionstringyesHuman label for the secret
createdAttimestamptzyesAuto-set
expiresAttimestamptznoNullableOptional expiry
secretHashstringyesSHA-256 hash of the secret value
plainReductedstringyesRedacted plain version shown in UI (e.g. abc...xyz)

DTO (API response): OpenBotSecretDto — exposes secretId, description, createdAt, expiresAt, secret (plain on creation only, otherwise plainReducted).


WebChatChannel

A webchat site/channel linked to a bot. Holds two rotating secrets used to generate DirectLine tokens.

FieldTypeRequiredConstraintsNotes
idstringyesPK (caller-supplied, not auto)Site ID
openBotOpenBotyesFK, CASCADE deleteOwner bot
namestringyesDisplay name
secret1stringyesIndexedPrimary webchat secret
secret2stringyesIndexedSecondary webchat secret (rotation)
createdAttimestamptzyesAuto-set

DTO (API response): WebChatChannelDto — exposes id, name, createdAt, secret1, secret2.


Runtime / In-Memory Objects (not persisted)

These objects are transient — they live only in memory or as JWT tokens. There is no database table for conversations or activities.

Conversation (runtime state)

FieldSourceNotes
conversationIdstringGenerated as <12-char-random>-<region>
tokenJWT stringDirectLine JWT (see below)
streamUrlstringWebSocket URL: ws://<DIRECTLINE_SOCKET_URL>/v3/directline/conversations/:id/stream?watermark=...&t=<token>
watermarkintegerActivity counter, stored in Redis or in-memory via AtomicOperationsService

Conversations are not stored in the DB. State is fully represented by the signed JWT token held by the client.

DirectLine JWT payload (DirectLineTokenPayload)

FieldTypeNotes
botstringBot handle (OpenBot.handle)
sitestringWebChat channel ID (WebChatChannel.id)
convstringConversation ID
userstring (optional)User ID provided at token generate/conversation create
issstringhttps://<DIRECTLINE_HOST>/
audstringhttps://<DIRECTLINE_HOST>/
nbfnumberNot-before (Unix timestamp)
expnumberExpiration (Unix timestamp, default +3600s)

Bot Access Token payload (OAuth2 client credentials)

Used for bot-to-gateway server calls (/oauth2/v2.0/token). Signed with the same JWT_SECRET.

FieldTypeNotes
audstringscope param or https://api.botframework.com/.default
issstringDIRECTLINE_HOST
substringclient_id (OpenBotSecret.id)
expnumberExpiration (Unix timestamp)

Activity (runtime, from botframework-schema)

Activities are the core message objects forwarded between clients and bots. Not stored in DB. Fields set by this service at creation time:

FieldNotes
id`
timestampSet to new Date() at creation
serviceUrlSet to DIRECTLINE_HOST env value
conversation{ id: conversationId, isGroup: false, conversationType: '', name: '' }
recipientSet by gateway when routing user activity: { id: '<handle>@<siteId>', name: handle }
replyToIdSet on bot-reply activities

All other Activity fields (e.g. type, text, attachments, from) come from the client or bot verbatim.


Pagination Wrapper

All list endpoints use PaginatedTransform<S, T>:

FieldTypeNotes
itemsT[]Page of results
totalnumberTotal record count
pagenumberCurrent page (1-based)
pageSizenumberRecords per page

Notes

  • synchronize: true in TypeORM config — schema auto-syncs from entities on startup. Disable in production.
  • WebChatChannel.id is caller-supplied (not auto-generated UUID). The caller is responsible for uniqueness.
  • OpenBotSecret.secretHash is never returned by the API. The plain secret is returned once at creation, then only plainReducted is accessible.
  • The watermark counter key in Redis/memory is the conversationId. It increments per non-typing activity.
  • secret1 and secret2 on WebChatChannel are both independently valid for token generation (key rotation pattern). Both are indexed for fast lookup.