Auto-response
Overview
Auto Response defines rules of the form "when a user types this keyword, reply with this message", bound to a pre-authored rich message. Architecturally, cms-api owns only the configuration side; the actual reply is dispatched by the webhook service when a message arrives from LINE.
A key constraint is that keywords must be unique within an OA. The module therefore exposes a
dedicated duplicate-check endpoint the form can call before saving, and it maintains a Redis
cache (AUTO_RESPONSE:*) so the webhook can match rules without querying the database on
every inbound message.
Business Flow
GET /api/auto-responselists rules with pagination as{data, total}, joined against the linked rich message so the reply's name can be displayed.- As the user types a keyword into the form, the UI calls
POST /api/auto-response/check-keyword-existswith a{keyword}body, surfacing duplicates immediately instead of failing at submit time. POST /api/auto-response(multipart/form-data) creates a rule, specifying the keyword or match pattern together with the rich message used to reply. On success the service writes the Redis cache and performs an HSET on theLINE_OA_IDkey as a side effect, so the webhook can resolve the OA quickly.- Details are read via
GET /api/auto-response/:idand edited viaPUT /api/auto-response/:id. PUT /api/auto-response/:id/statustoggles a rule on or off independently of its content, allowing temporary deactivation without deletion.DELETE /api/auto-response/:idperforms a soft delete, whileDELETE /api/auto-response/:id/hardwithconfirm=trueremoves the record permanently — an operation reserved for super admins.- At runtime the webhook service receives an inbound message, reads the
AUTO_RESPONSE:*cache, matches the keyword, and sends the rich message back, subject to the OA's message handling configuration.
Key Files & Functions
Core code lives in internal/modules/autoresponse/, comprising controller.go, service.go,
and dto.go.
| Method | Route | Handler | Policy (metadata) |
|---|---|---|---|
| GET | /api/auto-response | ct.findAll | readAll auto-response |
| GET | /api/auto-response/:id | ct.findById | read auto-response |
| POST | /api/auto-response | ct.create | create auto-response |
| POST | /api/auto-response/check-keyword-exists | ct.isKeywordExists | readAll auto-response |
| PUT | /api/auto-response/:id | ct.update | update auto-response |
| PUT | /api/auto-response/:id/status | ct.updateStatus | update auto-response |
| DELETE | /api/auto-response/:id | ct.delete | delete auto-response |
| DELETE | /api/auto-response/:id/hard | ct.hardDelete | auth.SuperAdmin() |
Every route is wrapped by modulegate.ModuleGate(d, "auto-response").
Connections to Other Services
- Access control — requests must pass
ModuleGate("auto-response"), withPolicyModuleAutoResponseas metadata; hard delete additionally requiresSuperAdmin(). - Tables —
auto_response,rich_message,line_oa - Redis — keys under
AUTO_RESPONSE:*with a TTL, plus an HSET on theLINE_OA_IDkey. - Consumers — line-management-webhook-go, a separate service, reads this cache to produce replies.
- Cross-module note — the Go implementation queries
entities.RichMessagedirectly inside this module rather than injecting a repository as the original TypeScript version did. - Related modules — Rich Message, Quick Reply, and Workflow, which offer alternative ways to respond to inbound messages.