Skip to main content

Quick Reply

Overview

Quick Reply is the row of chips LINE displays above the keyboard after a user receives a message from the OA. Tapping a chip performs whatever action the button was configured for — sending a message back into the chat, opening a link, launching the camera, or sharing a location.

The feature lets admins build reusable "quick reply sets" that are stored centrally and then attached by reference from Rich Messages and Template Messages, so the same set of shortcut buttons does not have to be recreated for every message. It suits teams who send many different messages but want to offer one consistent set of shortcuts.

Each set holds the following data:

FieldDescription
Set nameThe label shown in the list and in other features' selectors, up to 255 characters
ItemsThe buttons in the set — up to 13, each with a label of at most 20 characters
StatusActive / inactive; an inactive set never sends its chips

Button types available from the UI:

TypeAdditional inputBehaviour when tapped
Message (message)The text to sendSends that text into the chat on the user's behalf
Link (uri)URLOpens the given link
Date/time picker (datetimepicker)Reference data, mode (date / time / datetime), initial, min and max valuesOpens a date or time picker
Camera (camera)-Opens the camera
Camera roll (cameraRoll)-Opens the device photo library
Location (location)-Opens the location-sharing screen

Note: the postback type is deliberately excluded from the UI because the API rejects it. Existing records that already use it are still read and displayed correctly.

Key points to be aware of:

  • Sets that are still in use are protected. Attempting to deactivate or delete a set that a Rich Message or Template Message still references produces a warning listing every reference.
  • For deactivation, the user can confirm and proceed (the save is retried in forced mode). For deletion there is no way forward — the referencing messages must be updated first.
  • The button count and label length are LINE Messaging API limits and cannot be raised.

Business Flow

Managing the list of sets

  1. Opening the list checks the user's access rights first (the VIEW permission on the quick-reply module).
  2. The system restores the most recent filter from the session; if there is none, it starts at page one with 10 rows per page.
  3. The table shows the row number, set name (sortable), the number of buttons in the set, status, and action buttons.
  4. Sets can be searched by name and filtered by status. Searching resets to the first page and stores the criteria; the clear action resets the form and drops all remembered filters.
  5. Status can be toggled straight from the switch in the table, and the change is saved immediately.
  6. If the set being deactivated is still referenced, a confirmation dialog lists every reference and the user can confirm to proceed. Cancelling re-fetches the real status from the server so the switch never sits on an unsaved value.
  7. Deletion always requires confirmation. On success the result is reported and the table refreshes. If the set is still referenced, the dialog lists the references and offers only a close button — deletion cannot be forced.

Creating and editing a set

  1. The form runs in three modes — create, edit, and view-only — with the page title and breadcrumb adapting accordingly. There is no duplicate mode.
  2. Edit mode loads the existing set and its "used by" list in parallel, so the impact of a change is visible before editing. Create mode defaults the status to active.
  3. The user enters a set name and then adds buttons one at a time. New buttons always start as the message type, and the add button is disabled once 13 items are reached.
  4. Each item can be moved up or down or removed. The on-screen order is the order in which the chips appear in LINE.
  5. Changing an item's type clears the fields specific to the previous type and keeps only the label, so stale data from the old type is never saved.
  6. The right-hand column renders a live chips preview as the set is edited, and in edit mode a card summarises which messages currently use the set.
  7. Before saving, the system validates in order: at least one item, no more than 13, every item has a non-blank label, no label exceeds 20 characters, and the type-specific requirement is met (message needs text, link needs a URL, date/time picker needs reference data).
  8. On a successful save, create mode shows a result dialog and returns to the list, while edit mode reports the result briefly and navigates back immediately.
  9. If the edit deactivates a set that is still referenced, a confirmation dialog lists the references; confirming retries the save in forced mode, and cancelling restores the status switch to the real server-side value.
  10. Field-level errors returned by the server are displayed inline beneath the relevant field; any other failure surfaces as an error dialog.

Reusing a set in other messages

  1. The Rich Message form offers a quick reply selector that loads only active sets (up to 100, without pagination) and places a "none" option at the top of the list.
  2. If a message is bound to a set that has since been deactivated or deleted, the selector resolves the set individually so a readable name is shown instead of a raw reference id.
    • If the set still exists but is inactive, a warning tag explains that an inactive set will not send its chips.
    • If the set cannot be resolved at all, it is shown as unavailable with an accompanying warning.
  3. Once a set is selected, the labels of all its buttons are listed beneath the selector as confirmation that the right set was chosen.
  4. Chat preview panels across the messaging features render the chips exactly as the end user sees them in LINE.

Key Screens & Components

List page (/quick-reply)

  • Filter bar — a set-name search box and a status selector, with search and clear actions.
  • Set table — row number, set name, item count, status switch, and edit/delete buttons, with name sorting and pagination.
  • In-use guard dialog — lists the messages referencing the set; deactivation offers a confirm button, deletion offers only close.

Primary files: src/app/quick-reply/page.tsx, src/components/quick-reply/list/quick-reply.container.tsx

Form page (/quick-reply/form)

  • Set name field — required, capped at 255 characters.
  • Items editor — one card per button holding the label, the type selector, the type-specific fields, and move/remove controls, with a counter showing usage against the 13-item ceiling.
  • Message text field — an AutoComplete that suggests active Auto Response keywords, because this text is sent into the chat and may trigger an Auto Response rule.
  • Status switch — controls whether the set is available for use.
  • Chips preview panel — pinned while scrolling and updated live as the set is edited.
  • "Used by" card — edit mode only, listing the Rich Messages and Template Messages that reference the set.
  • In view-only mode all fields are disabled and the save/cancel buttons are hidden.

Primary files: src/app/quick-reply/form/page.tsx, src/components/quick-reply/form/quick-reply-form.container.tsx, src/components/quick-reply/form/quick-reply-form.tsx, src/components/quick-reply/form/quick-reply-items-editor.tsx

Shared components

  • src/components/quick-reply/QuickReplyPicker.tsx — the quick reply selector used in the Rich Message form, including the handling of sets that were deactivated or deleted after being linked.
  • src/components/quick-reply/QuickReplyChipsPreview.tsx — the LINE-style chips renderer, shared by the quick reply form and the chat previews of other messaging features.
  • src/components/quick-reply/QuickReplyReferenceList.tsx — the "used by" renderer, shared between directly fetched reference data and the reference data attached to an in-use error.

API service

All calls live in src/services/quick-reply.service.ts under the quick-reply base path.

CapabilityEndpoint
List setsGET /quick-reply
Get a single setGET /quick-reply/{id}
List referencesGET /quick-reply/{id}/references
Create a setPOST /quick-reply
Update a set (including status changes)PUT /quick-reply/{id}
Delete a setDELETE /quick-reply/{id}

Note: there is no dedicated status endpoint, so toggling the switch in the table sends the full record back together with the new status. A force flag can be attached to bypass the in-use guard when deactivating; deletion has no such escape hatch.

Dependencies

  • Permissions — both the list and the form are gated by the quick-reply module permission, which is bound to the same backend module as Auto Response; granting Auto Response therefore unlocks the Quick Reply menu as well.
  • Rich Message Management — the primary consumer of quick reply sets through the selector in its form, and the main reason a set becomes protected against deactivation or deletion.
  • Template Message — another source that appears in the "used by" list.
  • Auto Response — supplies active keywords as suggestions for message-type buttons, keeping the text pushed back into the chat aligned with rules that actually exist.
  • Shared chat preview — the CMS chat preview component reuses the same chips renderer, keeping previews consistent across features.
  • 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 sessionStorage-based filter persistence, all shared with other list pages in the CMS.

Backend Details (CMS API)

The backend lives in internal/modules/quickreply/. It is a newly written module rather than a port of an older system, so its structure follows the simple modules already present in the codebase (content category, Template Message). What sets it apart is the dedicated references endpoint used to check usage before a delete.

Required permissions

  • Every route requires the global authentication check (JWT), and the token must carry a selected LINE OA; requests without one are rejected.
  • The module's policy name is pre-registered to match the module name used by the CMS front end (quick-reply), so per-module enforcement can be switched on later without renaming anything.
  • Security note — unlike Auto Response, this module is not wrapped in a module gate, and the declared policy is still only metadata that is not actually enforced. Menu visibility based on permissions therefore happens mainly on the front end: any signed-in user with an OA selected can still call these endpoints directly. A hidden menu should not be mistaken for real access control here.

Validation and business rules enforced by the backend

  • Every query is scoped to the currently selected LINE OA; data belonging to another OA is never returned, even when its id is supplied directly.
  • Fetching a single record with an id that does not exist — or an id belonging to another OA — returns an explicit "not found" rather than an empty value, which lets the UI distinguish "not permitted to see" from a genuine data error.
  • GET /api/quick-reply/:id/references exists purely to answer where a set is referenced; the UI feeds that answer into the warning dialog shown before deactivating or deleting.
  • There is no separate status endpoint, so enabling and disabling goes through the normal update endpoint (PUT /api/quick-reply/:id) with the full record.

What gets stored, and the side effects

  • Data lives in a single table, quick_reply. This module writes no cache and publishes no queue messages.
  • Deletion is a soft delete that stamps the deletion time into the deleted_date column; the row itself remains in the database.
  • Saved sets are attached to the payload sent to LINE at actual send time, which happens in the messaging features' code paths rather than in this module.

Edge cases worth knowing

  • This table does not use the ORM's automatic soft-delete mechanism, so every query has to spell out the "not deleted" condition itself. Any query that forgets it will surface deleted sets in its results — something to watch for when adding new queries to this module.
  • Because deletion is soft, a set the user deleted can still be referenced by messages that were bound to it earlier. That is precisely why the form needs logic to fetch a deleted set and render a readable name instead of a raw reference id.
  • The guard that prevents deleting an in-use set relies on the references endpoint together with the backend's own check at delete time. Any new feature that references quick reply sets must therefore teach that endpoint about the new reference source, or the warning will be incomplete.