Skip to main content

Rich Menu

Overview

A rich menu is the image-based menu shown at the bottom of a LINE chat. The system supports multiple menus per channel and can swap the menu a user sees based on audience membership, a time window, or a tap inside the menu itself (switch / alias).

A key design point is the twin tables: rich_menu holds the current menu, while rich_menu_archive holds snapshots of menus that were previously live. The two share almost identical columns, so tracking log entries that reference an older menu version can still be interpreted correctly even after the current menu has been edited.

Core Data Structure

rich_menu (model RichMenu)

  • line_rich_menu_id — the identifier LINE returns after the menu is uploaded
  • title, custom_label, thumbnail, layout (the tile-template number)
  • type enum RichMenuTypeguest / member / custom / default / switch
  • audience_idaudience.id (nullable) and parent_id (the parent menu for switches)
  • status (CommonStatus, default processing), complete_link_user, total
  • the active window start_date / end_date
  • container_original JSONB (the raw menu layout), rich_menu_actions JSONB, template_tracking JSONB, and is_for_automation

It has 1 : N relations to rich_menu_action, rich_menu_member, line_user, and tracking_log.

rich_menu_action

Each row is one tappable area in the menu.

  • rich_menu_id, index (tile order), and type (enum RichMenuActionType: message / uri / tel / postback / datetimepicker / camera / cameraroll / location / richmenu / no_action / alias)
  • label, link, boundary JSONB (tile coordinates), rich_menu_alias
  • tracking_key and is_tracking, used to build the tracking link
  • rich_menu_archive_id (nullable) for rows attached to an archived menu instead

rich_menu_member

Pairs a menu with a list of users. line_user_id is stored as JSONB — a set of user IDs rather than one row per person.

rich_menu_archive

Structurally identical to rich_menu, with the same set of relations (rich_menu_action, rich_menu_member, line_user, tracking_log).

On the user side, line_user.rich_menu_id and line_user.rich_menu_archive_id record which menu a given user is currently seeing.

  • prisma/schema.prisma:535 — model RichMenu
  • prisma/schema.prisma:575 — model RichMenuAction
  • prisma/schema.prisma:597 — model RichMenuMember
  • prisma/schema.prisma:654 — model RichMenuArchive
  • seed-data/09.rich_menu.sql
  • schema-dumps/2026-07-24/schema.sql:2490, :2523, :2562, :2635

Connections to Other Services

  • cms-api-go — menu design, uploading images to LINE, publish/unpublish, audience binding
  • worker-go — bulk link/unlink of menus to users, since the LINE API must be called per user
  • webhook-go — handles postbacks and menu switching, including moving a user from the guest menu to the member menu once they register
  • client-api-go — forms configured to change the rich menu after a successful submission

Related domains: Forms, Audience, LINE Friends, Click Tracking