Audience Management
Overview
An audience is a target group used to aim campaign messages, bind a rich menu, or act as a trigger condition. The defining design decision is that audience members are stored as CSV files in object storage rather than as database rows, so an audience can scale to very large memberships. Reading the member list back therefore goes through the CSV Engine.
The module also runs a cron every minute to auto-refresh audiences configured for it, and keeps
an audit log of members joining and leaving in the audience_member_log table.
Business Flow
Creating and viewing
GET /api/audienceslists audiences with pagination.POST /api/audiences(multipart/form-data) creates an audience. The service first checks the plan'smaxSegmentsquota; a duplicate name returns errorAUD_001. The user either uploads a CSV or specifies filter criteria, after which the job is published to thecreate_audiencequeue for a worker to build the member file.GET /api/audiences/:idreturns details — member count, criteria, and current status.GET /api/audiences/:id/memberreturns members with pagination, reading the CSV through the CSV Engine with a 30-second cache.PUT /api/audiences/:idupdates an audience and publishes to theupdate_audiencequeue.DELETE /api/audiences/:iddeletes one and publishes to thedelete_audiencequeue.
Exporting
GET /api/audiences/:id/exportexports the member list as CSV, streamed directly into the response.GET /api/audiences/:id/export-detailexports with per-member detail. A failed export returnsAUD_004; no members found returnsAUD_005.
Auto-refresh
PATCH /api/audiences/:id/auto-refreshenables or disables auto-refresh per audience. The organisation's plan must also grant theautoRefreshentitlement.- The
AudienceRefreshSchedulercron runs every minute on the* * * * *schedule, using a Redis lock so multiple replicas do not overlap. Audiences that are due are published to theaudience_refreshqueue. POST /api/audiences/:id/refreshtriggers a manual refresh immediately, without waiting for the cron.
Tracking membership changes
GET /api/audiences/:id/member-logsshows the history of members joining and leaving, drawn fromaudience_member_log.- Those same joins and leaves are published as events to the
audience_membership_triggerqueue so Trigger Rule can act on them.
Key Files & Functions
Core code lives in internal/modules/audience/, comprising controller.go, service.go,
scheduler.go, helpers.go, types.go, and dto.go, registered on the
authed.Group("/audiences") group with modulegate.ModuleGate(d, "audiences").
| Method | Route | Handler | Policy (metadata) |
|---|---|---|---|
| GET | /api/audiences | svc.getListHandler | readAll audiences |
| GET | /api/audiences/:id | svc.getByIDHandler | read audiences |
| GET | /api/audiences/:id/member | svc.getMemberByAudienceIDHandler | read audiences |
| GET | /api/audiences/:id/member-logs | svc.getMemberLogsHandler | read audiences |
| GET | /api/audiences/:id/export | svc.getExportReportAllFriendHandler | export audiences |
| GET | /api/audiences/:id/export-detail | svc.exportMembersDetailHandler | export audiences |
| POST | /api/audiences | svc.createHandler | create audiences |
| PUT | /api/audiences/:id | svc.updateHandler | update audiences |
| PATCH | /api/audiences/:id/auto-refresh | svc.updateAutoRefreshHandler | update audiences |
| POST | /api/audiences/:id/refresh | svc.triggerManualRefreshHandler | update audiences |
| DELETE | /api/audiences/:id | svc.deleteByIDHandler | delete audiences |
The scheduler is registered through audience.RegisterScheduler(d), which calls
d.Scheduler.Register("* * * * *", "AudienceRefreshScheduler", s.handleAudienceRefresh). It is
invoked both from RegisterRoutes and from registerSchedulers in cmd/api/modules.go.
Connections to Other Services
- Access control — requests must pass
ModuleGate("audiences"), withPolicyModuleAudiencesas metadata. - Tables —
audience,audience_member_log,line_user,line_oa,api_client,organization - RabbitMQ — the
create_audience,update_audience,delete_audience,audience_refresh, andaudience_membership_triggerqueues. - Redis — provides the refresh cron's lock, preventing overlapping runs across replicas.
- Storage and CSV Engine — member files live on MinIO or S3 and are read back through the CSV Engine.
- Cross-module —
planlimitsfor themaxSegmentsquota and theautoRefreshentitlement, plus theapiclientmodule. - Error codes —
AUD_001duplicate name,AUD_002not an audience,AUD_003invalid CSV,AUD_004export failed, andAUD_005LINE user not found. - Related modules — Audience Filter (which builds audiences from criteria), Campaign Management, Rich Menu, and Trigger Rule.