Skip to main content

Automatic Audience Refresh

Overview

An "automated" audience is defined by filter conditions rather than a fixed member list, so its membership must be recomputed periodically to stay current.

The filter-builder logic lives in cms-api, which is where the actual computation happens. This worker acts purely as a durable dispatcher: it consumes a message from the queue and issues an HTTP call to an internal cms-api endpoint.

That split buys two things. RabbitMQ's retry and DLQ semantics come for free, and a computation that may run for several minutes never ties up a user-facing HTTP request.

Business Flow

  1. Receive an AudienceRefreshPayload containing audienceId plus whatever other fields the producer supplied.
  2. Read the base URL from CMS_API_BASE_URL (falling back to http://localhost:3000) and the key from INTERNAL_API_KEY.
  3. Issue a POST to /api/audiences-filter/internal/refresh on cms-api.
    • Headers: x-internal-key carrying the value of INTERNAL_API_KEY, and Content-Type: application/json.
    • Body: the entire payload, forwarded verbatim.
    • Timeout: 5 minutes, matching the legacy axios timeout so that large audiences still complete.
  4. On a 2xx response, log success and ack the message.
  5. On a transport error or a non-2xx status, log the failure and return an error so the mq layer decides what happens next — transient failures such as 5xx or timeouts are retried at 1s, 4s, and 9s before the message lands in the DLQ.

Key Files & Functions

  • internal/audience/refresh_consumer.go
    • RefreshConsumer.OnAudienceRefresh(ctx, body) — the main handler
    • NewRefreshConsumer(cfg, log) and Register(reg, cfg)
    • Constants: refreshPath is /api/audiences-filter/internal/refresh, refreshTimeout is 5 minutes
    • logRefreshFailed()
  • internal/audience/payloads.go — defines AudienceRefreshPayload
  • cmd/worker/main.go — registers the consumer in runMain() via audience.NewRefreshConsumer(cfg, log).Register(reg, cfg)
  • Queue: audience_refresh (runtime profile main)

Connections to Other Services

  • Job source — cms-api-go, or a CMS-side cron, whenever an audience needs its membership recalculated.
  • Outbound call — the internal cms-api-go endpoint POST /api/audiences-filter/internal/refresh, protected by the x-internal-key header.
  • Environment variablesCMS_API_BASE_URL and INTERNAL_API_KEY.
  • No direct database or LINE API access — this is a pure forwarding consumer.
  • Eventual resultline_user.audience_ids and audience.info are updated by cms-api itself.