Audience Management
Overview
An audience is a list of LINE users that other modules reference to decide who receives a message or sees a piece of content — Campaign, Rich Menu, Content Management, Trigger Rule, Workflow, and Bulletin all consume audiences.
The feature serves marketing teams that need to segment customers by real behaviour (campaign clicks, menu taps, form answers, loyalty tier) as well as teams that already hold a customer list and simply want to import it.
Three audience modes are supported:
| Mode | Menu / route | Source of the member list |
|---|---|---|
| CSV upload | /audience/csv | A user-uploaded CSV file containing a Line UserID column |
| Single-source filter | /audience/filter/form | One condition type: campaign, Rich Menu, activity tag, Auto Response, or form |
| Multi-source filter | /audience/filter/multi-source/form | Several sources combined into groups, with AND/OR both inside and between groups |
Key points to be aware of:
- The CSV and filter list pages share the same screen, swapping columns and row actions based on the active mode.
- Filter-based audiences support scheduled recalculation (auto refresh) as well as an on-demand refresh; the refresh interval is configured at the LINE OA level.
- Audiences created by an external system have all row actions and the auto-refresh switch hidden, preventing cross-system edits.
- The detail page is shared by all modes and shows the filter rules used to build the audience, any linked Trigger Rules, the member table, and export actions.
- The create button on the filter list page opens the multi-source form by default. The single-source form remains reachable from the Form Builder response page.
Business Flow
1. The list page (shared by CSV and filter modes)
- Opening either list page selects the appropriate column set and row actions automatically.
- In filter mode the LINE OA refresh settings are also loaded, and a tag next to the page title shows whether auto refresh is enabled and at what interval.
- Records can be filtered by keyword and status (
completed/processing); the search is debounced to reduce requests, and a clear button resets the form. - Columns shared by both modes: row number, audience name (linking to the detail page), source system, member count (successful versus total), status, creation date, and actions.
- CSV mode adds description and file name columns.
- Filter mode adds an auto-refresh switch and a last-synced column, which shows a processing indicator or "never" when no run has happened yet.
- Row actions differ by mode:
- CSV: edit and delete.
- Filter: refresh now, copy into the multi-source form, and delete (available only once the audience has finished computing).
- Toggling auto refresh saves immediately from the switch; deletion requires confirmation in a dialog.
2. CSV upload mode
- The form opens either to create a new audience or to edit an existing one; edit mode preloads the name, description, and previous file details.
- The user enters a name and description (both required) and drops a CSV file into the upload area (required only when creating). The page includes five preparation guidelines, a sample image, and a template download button.
- The file is validated in the browser before submission: the system confirms it is a genuine CSV, then reads it line by line looking for blank rows, duplicate user ids, and malformed user ids (they must start with
Uand be 33 characters long; the header row is skipped). - If problems are found, a dialog lists each offending row with an explanation and the file is rejected — it must be corrected and uploaded again.
- Once validation passes, a confirmation dialog reports how many user ids were parsed. In edit mode it also asks the user to confirm that the existing member list will be replaced.
- On confirmation the file and its metadata are uploaded and the user is returned to the list page.
- If the backend finds additional problems in the file, they are converted back into per-row errors and shown in the same dialog used for client-side validation.
Edit mode is designed around replacing the existing file, so saving without attaching a new file should be avoided.
3. Single-source filter mode
- Enter an audience name and choose one of five condition types: campaign, Rich Menu, activity tag, Auto Response, or form. Switching type clears the values entered for the previous one.
- Each type renders its own configuration section and loads the options it needs:
- Campaign — pick a campaign, then tick the tracking spots to include, separated into reach (image/video) and click (link/button) spots, with an AND/OR relationship between them.
- Rich Menu — choose the menu type first (guest, member, custom, or switch), then the menu and its spots.
- Activity tag — tick one or more activity windows, from active today through inactive for over 30 days.
- Auto Response — select one or more auto-response rules.
- Form — select a form, then build up to five condition groups from its questions.
- A live preview of matching users is shown before the audience is created. Most types recalculate automatically when the conditions change; the form type requires pressing the search button in its section.
- The preview lists the row number, user id, display name, and user type, with a summary of the selected conditions above it.
- The create button stays disabled until the preview returns at least one member.
- A successful create returns the user to the list page. Field-level errors reported by the server are mapped back under the relevant form fields.
4. Multi-source filter mode
- The data model is a set of groups, each containing a set of sources, with configurable AND/OR joins both between groups and between the sources inside a group.
- Seven source types can be added: campaign, Rich Menu, activity tag, Auto Response, form, custom attribute, and loyalty — each with its own default configuration.
- Every source renders as a collapsible card with an enable/disable switch and a delete button, loading its own options only when that type is actually in use.
- Campaign — tick reach and select spots in bulk, with an AND/OR join inside the source; spots that cannot be tracked are disabled.
- Rich Menu — pick the menu type, then the menu and its spots.
- Activity tag — tick activity windows with an AND/OR join.
- Auto Response — select multiple rules, capped at five per source.
- Form — select a form and build conditions from its questions; questions that cannot be filtered are excluded, and the value input adapts to the question type (date, number, single or multiple choice, text), including two-field range conditions.
- Custom attribute — choose from filterable attributes, grouped into user profile fields and custom attributes; the available operators depend on the data type (string, number, date, boolean).
- Loyalty — one metric per source, such as point balance, points earned, points redeemed, amount spent, tier rank, completed cards, or days since the last earn, together with a comparison operator.
- The right-hand panel renders a Venn diagram that redraws instantly as the structure changes, making the set semantics of the chosen AND/OR joins obvious.
- Pressing preview computes the result, returning the total count, the first ten members, and a per-source breakdown.
- The preview table shows the avatar, display name, a copyable LINE user id, tags marking which sources matched, and the user type. When an enabled form source exists, an extra column opens that user's most recent form answers.
- The create button unlocks only after a successful preview, and creation requires an audience name plus at least one enabled source.
- The form can also be opened with a preset condition set handed over from another page (currently the Loyalty Segments page). A banner confirms when a preset loads successfully, and an empty form is shown if the preset data is invalid.
5. Audience detail page
- Opened from the audience name in the list. Three things load in parallel: the audience record, the Trigger Rules that reference it, and the member list.
- Filter-built audiences show a "Filter rules" card that renders the conditions as readable text. Multi-source audiences are shown group by group with the join between groups, and a button opens the same condition set in the filter builder.
- If any Trigger Rules reference the audience, a card lists them with links plus tags for the action type and active state.
- The member table shows the row number, user id (linking to the friend detail report), display name with avatar, first and last name, and friend status, filterable by keyword and status.
- Two export options are available: a basic member export, and an export that includes each member's attributes as a CSV file.
6. Selecting audiences from other modules
- Consuming modules fetch the full audience list through the same shared service, so every mode is visible everywhere.
- A shared multi-select component (
src/components/common/audience-select.tsx) is available for reuse; the caller supplies its own placeholder because "nothing selected" means different things in different contexts. - Modules that need paginated search — Campaign Management, for example — use their own service instead.
Key Screens & Components
List page (/audience/csv, /audience/filter)
- Filter bar — a name search box and status selector with search and clear actions.
- Auto-refresh tag — displayed beside the title in filter mode, indicating whether scheduled recalculation is on.
- Audience table — the shared columns plus mode-specific columns and row actions.
Primary files: src/app/audience/csv/page.tsx, src/app/audience/filter/page.tsx, src/components/audience/csv/csv-table.container.tsx
CSV upload form (/audience/csv/form)
- Main fields — name and description.
- File drop area — accepts CSV only, alongside the guideline section and template download.
- File error dialog — a table of offending rows and reasons.
- Pre-save confirmation dialog — the number of user ids parsed from the file.
Primary files: src/components/audience/csv/csv-form.container.tsx, src/components/audience/csv/csv-form.tsx
Single-source filter form (/audience/filter/form)
- Form header — audience name and condition type selector.
- Type-specific sections — one component per type (
section-campaign.tsx,section-rich-menu.tsx,section-activity-tag.tsx,section-auto-response.tsx,section-form-builder.tsx). - Preview table — matching members plus a summary of the selected conditions.
Primary files: src/components/audience/filter/filter-form.container.tsx, src/components/audience/filter/filter-table.tsx
Multi-source filter form (/audience/filter/multi-source/form)
- Condition builder (left) — audience name, the join between groups, group cards, and the add-source menu.
- Source cards — sub-forms that change per source type (
source-entry-card.tsx). - Venn diagram (right) — an SVG set illustration that updates live with the conditions.
- Preview table — per-source breakdown, the first ten members, and the form-answer dialog.
Primary files: src/components/audience/filter/multi-source-filter-form.container.tsx, src/components/audience/filter/multi-source-filter-table.tsx, src/components/audience/filter/components/multi-source-visualizer.tsx
Detail page (/audience/csv/detail)
- Filter rules card — the conditions summarised as text, with a button to reopen them in the builder.
- Trigger Rule card — the rules that reference this audience.
- Member table — with filters and the two export buttons.
Primary file: src/components/audience/csv-detail-table/filter-detail-table.container.tsx
API services
src/services/audience.service.ts — manages the audience records themselves.
| Capability | Endpoint |
|---|---|
| List audiences | GET /audiences |
| Get a single audience | GET /audiences/{id} |
| Create / update / delete | POST /audiences, PUT /audiences/{id}, DELETE /audiences/{id} |
| Toggle auto refresh | PATCH /audiences/{id}/auto-refresh |
| Trigger a manual refresh | POST /audiences/{id}/refresh |
| Read the LINE OA refresh settings | GET /line-oa/{lineOaId}/audience-refresh-settings |
| List members | GET /audiences/{id}/member |
| Export members with attributes | GET /audiences/{id}/export-detail |
src/services/audience-filter.service.ts — builds and previews filter conditions.
| Capability | Endpoint |
|---|---|
| Campaign / Rich Menu / Auto Response / form options | GET /audiences-filter/list-dropdown-campaign, .../list-dropdown-richmenu, .../list-dropdown-auto-response, .../list-dropdown-form-builder |
| Preview a form-based filter | POST /audiences-filter/preview-form-filter |
| Create a single-source filter | POST /audiences-filter/create-filter |
| Create a form-based filter | POST /audiences-filter/create-form-filter |
| Preview a multi-source filter | POST /audiences-filter/preview-multi-source-filter |
| Create a multi-source filter | POST /audiences-filter/create-multi-source-filter |
| View a user's form answers | GET /audiences-filter/form-response |
The module also calls other services for supporting data: the single-source member preview (POST /tracking-line-users), filterable attributes (GET /attribute-master/filterable), loyalty tiers (GET /loyalty/tiers), and the Trigger Rules bound to an audience (GET /trigger-rule/by-audience/{audienceId}).
Dependencies
- Permissions — the Audience menu and all three sub-menus unlock together from the backend
audiencesmodule permission, which the side menu and Quick Access entries check before rendering. - Upstream features (used to build audiences)
- Campaign and Rich Message — provide tracking spots for both reach and click events.
- Rich Menu — provides menus and spots grouped by menu type.
- Auto Response — provides the rules usable as a condition.
- Form Builder — provides questions and answers for conditions, and links into the filter form from the form response page.
- Attribute Setup — provides the custom attributes marked as filterable.
- Loyalty — provides metrics and tiers, and hands over preset conditions from the Segments page.
- Downstream consumers — Campaign Management, Trigger Rule, Workflow Automation, Rich Menu (default menu), Content Management, Content Links, Menu Builder, Bulletin categories, and the all-friends report.
- Trigger Rule — the audience detail page surfaces the rules referencing an audience so the impact of editing or deleting it is visible up front.
- Shared infrastructure — the CMS authentication and HTTP client (automatic sign-out on token expiry), the breadcrumb and side-menu system, the standard modal set, and the user profile used to resolve the current LINE OA.
- Static assets — the CSV template at
/template/audiences_template.csvand the sample image used in the upload guidelines.
Backend Details (CMS API)
The backend splits into two cooperating modules: internal/modules/audience/ (the audience records and their members) and internal/modules/audiencefilter/ (the tooling that builds audiences from conditions).
The most important detail — members are not database rows
An audience's member list is stored as a CSV file on object storage (MinIO/S3) rather than as rows in a table, so that very large audiences do not bloat the database. The consequences are significant:
- Viewing members on the detail page (
GET /api/audiences/:id/member) reads the CSV file back and paginates it through the system's CSV engine rather than querying the database, and the result is cached for about 30 seconds — refreshing rapidly can therefore return the same numbers. - Exports (
GET /api/audiences/:id/exportandexport-detail) stream straight into the HTTP response; no file is prepared in advance for later download. - The member count shown in the table comes from summary data recorded at computation time; it is not recounted each time the page opens.
Required permissions
- Every route in the audience module is wrapped in the module gate for the
audiencesmodule. - Policies are split by action, and
exportis a distinct permission fromread— being able to view the member list does not imply being able to export it. - Toggling auto refresh and triggering a manual refresh both require
update, since they count as modifying the audience. - Note — the audience filter routes only require the global JWT and are not wrapped in a module gate, with their declared policy still unenforced metadata. On top of that, the endpoint that creates an audience from form conditions declares a
readpolicy even though its outcome is new data, unlike the multi-source create endpoint which usescreate. That inconsistency is worth knowing about.
Validation and business rules enforced by the backend
- The audience quota is always checked before creation (the plan's
maxSegmentsvalue), for both CSV uploads and filter-built audiences, so creation can be refused even when the data is perfectly valid. - Audience names must be unique. Duplicates come back with a dedicated error code (
AUD_001). - Enabling auto refresh also requires the plan entitlement, not merely the edit permission; if the plan does not include the capability, the switch cannot be turned on.
- The create endpoint accepts
multipart/form-databecause the CSV file arrives alongside the form fields. - Dedicated error codes let the UI distinguish the cases: duplicate name, the referenced record is not an audience, the CSV file is invalid, the export is not possible, and the LINE user was not found.
What gets stored, and the side effects
- Creating, updating, and deleting an audience do not complete inline. Each publishes work onto a queue (
create_audience,update_audience,delete_audience) forline-management-worker-goto actually build or adjust the member file. That is why audiences have a "processing" status and why records still computing cannot be deleted. - A scheduled job runs every single minute to find audiences due for auto refresh and publish them onto the
audience_refreshqueue. That job takes a Redis lock so multiple running replicas do not duplicate the work. - Member additions and removals are recorded as an audit log in the
audience_member_logtable and are also published as events onto theaudience_membership_triggerqueue for Trigger Rule and Workflow to act on. Editing audience membership can therefore indirectly cause messages to be sent. - The main tables involved are
audience,audience_member_log,line_user,line_oa, andorganization. - On the filter side, computed results are written out as a CSV file to storage and then become an ordinary audience managed by the audience module, auto refresh included.
An internal path that bypasses login
- The audience filter module exposes
POST /api/audiences-filter/internal/refreshfor other services rather than users — for example when a worker or the webhook needs to recompute the members of a filter-built audience. - This endpoint is not protected by JWT. It authenticates with a shared secret sent in a header (
X-Internal-Key) and compared against an environment variable. - Security note — because this is single-shared-key authentication, anyone who obtains the key can trigger recomputation for any organisation's audiences without logging in. The endpoint should never be exposed to the public internet.
Edge cases worth knowing
- Because creation and updates run through a queue, a successful save does not mean the member list is ready. Modules that go on to send messages to an audience should verify that computation has finished.
- If the worker is down or the queue is backed up, an audience stays in the processing state indefinitely with no visible error on the CMS side.
- The auto-refresh job runs every minute for the whole system, not per audience — a large number of audiences on very frequent intervals will compete for resources in the same cycle.
- The audience filter module reaches Form Builder data through a purpose-declared interface to avoid a circular dependency between modules, so any new capability needing more form data must extend that interface as well.