Skip to main content

Flow: Broadcast Campaign

End-to-end sequence for a broadcast campaign from creation to delivery. Services: hbf-console, hbf-core, hbf-broadcast, Facebook/Teams/Slack/Viber/SMTP

Sequence Diagram

Step-by-Step

  1. Campaign creation (hbf-console -> hbf-core): A user creates a broadcast campaign in the console, specifying the target audience (subscriber filters), content (message templates per channel), and schedule. The campaign is saved in hbf-core with status pending.

  2. Polling (hbf-broadcast -> hbf-core): The hbf-broadcast daemon runs an infinite loop, polling hbf-core every 60 seconds for broadcasts with status: pending and sendBefore less than or equal to the current time.

  3. Subscriber resolution (hbf-broadcast -> hbf-core): For each pending broadcast, hbf-broadcast fetches the bot deployment configuration (channel credentials) and resolves the subscriber list via SubscribersClient.

  4. Message template resolution (hbf-broadcast -> hbf-core): hbf-broadcast fetches or creates message templates via ResponsesClient, resolving any dynamic content or variables.

  5. Batched delivery (hbf-broadcast -> channel APIs): Subscribers are grouped by channel. Each batch is sent via the appropriate channel API:

    • Facebook: POST /me/messages (individual) or /me/broadcast_messages (bulk)
    • Teams: POST /v3/conversations/{id}/activities via MS Bot Framework
    • Slack: POST chat.postMessage
    • Viber: POST broadcast_message
    • Email: nodemailer SMTP transport
  6. Progress tracking (hbf-broadcast -> hbf-core): After each batch, hbf-broadcast updates the broadcast status in hbf-core with currentBatch and totalBatches counts, allowing the console to show progress.

  7. Completion (hbf-broadcast -> hbf-core): When all batches are sent, hbf-broadcast sets the broadcast status to complete. If any batch fails irrecoverably, it sets status to error with the error details.

Contracts

hbf-broadcast -> hbf-core (polling):

BroadcastsClient.findAllBy({ status: "pending", sendBefore: Date })
-> Broadcast[]

hbf-broadcast -> hbf-core (status update):

BroadcastsClient.save(broadcastId, {
status: "in_progress" | "complete" | "error",
error: "string" | null,
currentBatch: number,
totalBatches: number
})

hbf-broadcast -> hbf-core (deployment + subscribers):

BotDeploymentClient.findByTenantId(tenantId) -> deployment config
SubscribersClient.findByHandle(handle) -> subscriber
SubscribersClient.create(subscriberData) -> subscriber
ResponsesClient.findAllBy(filters) -> Response[]
ResponsesClient.createOrUpdate(responseData) -> Response

hbf-broadcast -> Facebook:

POST /me/messages
{ "recipient": { "id": "user_id" }, "message": { "text": "..." } }

hbf-broadcast -> Teams:

POST /v3/conversations/{conversationId}/activities
{ "type": "message", "text": "..." }

hbf-broadcast -> Slack:

POST chat.postMessage
{ "channel": "channel_id", "text": "..." }

hbf-broadcast -> Viber:

POST broadcast_message
{ "broadcast_list": ["user_id"], "type": "text", "text": "..." }