LineGroup 規格說明書

項目名稱: Aile\ 範圍: Gateway Line 群組事件 → tenant → room(lineGroup)\ 最後更新: 2026-06-13\ 版本: v2.0 — 結合代碼實現的完整規格


1. 概述

LineGroup 是 Aile 針對 LINE 渠道「群組聊天」場景設計的專用聊天室類型。與私聊 services 聊天室不同,LineGroup 以群為單位管理 LINE 群組內的成員、消息和外發路由。

1.1 設計目標

目標說明
一個群一個房一個 serviceNumberId + chat.code 只對應一個啟用中的 lineGroup 聊天室
真實發言人群消息顯示真實發言人頭像/暱稱,不是「群本身」
群級路由對外回發消息只向群發一次,不按成員逐個外發
持久化關係持久化群成員與聊天室的關係,支援成員展示與歸屬追蹤

1.2 非目標


2. 資料模型

2.1 聊天室類型


    
    
    
  // aile-api/aile-room-api/.../constant/RoomType.java
public
 static final String LineGroup = "lineGroup";

RoomModel 中的關鍵字段(用於 LineGroup):

字段來源說明
type固定 "lineGroup"聊天室類型標識
serviceNumberIdwebhook.to.code歸屬服務號
namewebhook.chat.name群組名稱
avatarwebhook.chat.pictureUrl群組頭像
externalRoomIdwebhook.chat.codeLINE 群組唯一 ID
channel"Line"來源渠道

2.2 LineGroupContactRelationModel

MongoDB 集合:aile.tenant.contact.linegroup.relation

此模型記錄「LINE 群組 ↔ 客戶(聯繫人)」的多對多關聯。


    
    
    
  // aile-api/aile-tenant-api/.../model/servicenumber/LineGroupContactRelationModel.java
@Document("aile.tenant.contact.linegroup.relation")

@CompoundIndexes({
    @CompoundIndex(name = "serviceNumberId_1_lineGroupId_1_scopeId_1", 
        def = "{'serviceNumberId': 1, 'lineGroupId': 1, 'scopeId': 1}"),
    @CompoundIndex(name = "roomId_1_status_1", def = "{'roomId': 1, 'status': 1}"),
    @CompoundIndex(name = "contactId_1_status_1", def = "{'contactId': 1, 'status': 1}"),
    @CompoundIndex(name = "tenantId_1_lineGroupId_1_status_1", 
        def = "{'tenantId': 1, 'lineGroupId': 1, 'status': 1}")
})

public
 class LineGroupContactRelationModel extends BaseModel {
    String tenantId;          // 租戶 ID
    String serviceNumberId;   // 服務號 ID
    String lineGroupId;       // LINE 群組 ID(即 chat.code)
    String roomId;            // Aile 聊天室 ID
    String scopeId;           // LINE 用戶 scopeId(即 sender.code)
    String contactId;         // Aile 聯繫人 ID
    String status;            // 狀態(Enable / Disable)
}

3. 核心服務與實現

3.1 LineGroupRoomImpl(聊天室工廠策略)

位置:aile-service/aile-service-room/.../factory/strategy/impl/LineGroupRoomImpl.java

繼承 CommonRoomImpl,覆寫關鍵方法以適應群組場景:

方法行為
checkMessage()識別系統帳號消息,設置發送人名稱
createRoom()基於 LineGroupRoomCreateDto 建立聊天室
消息分發roomMessageDispatchBatchWorkerExecutor 批量分發

3.2 Gateway 事件處理(tenant 服務)

位置:aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/

事件實現類處理邏輯
JoinAbstractEventImpl (共用)建立/恢復群級 scope + lineGroup 聊天室
LeaveAbstractEventImpl (共用)停用 lineGroup + 群級 scope + 外部成員關係
MemberJoinMemberJoinEventImpl建立聯繫人 + 成員級 scope + 房間成員
MemberLeaveMemberLeaveEventImpl停用房間成員關係
MessagingMessagingEventImpl懶建立群/成員 → 寫入消息

3.3 LineGroupContactRelationService

位置:aile-service/aile-service-tenant/.../service/servicenumber/

提供 Line 群組與客戶關聯的 CRUD 及查詢能力:


    
    
    
  public interface LineGroupContactRelationService extends BaseMongoService<LineGroupContactRelationModel> {
    // 依 lineGroupId + scopeId 查找關聯

    // 依 roomId 查詢成員列表

    // 批量啟用/停用關聯

}

對應 Controller:LineGroupContactRelationController(路由:/servicenumber/linegroup-contact-relation

3.4 Saga 整合

在租戶資料歸戶/清理流程中,LineGroup 關聯資料也納入 Saga 步驟:


4. 事件處理完整流程

4.1 Join(LINE OA 被拉入群)


    
    
    
  Gateway ──→ aile-service-tenant (GatewayController)
  │
  ├── 解析 webhook:提取 chat.code、chat.name、chat.pictureUrl、to.code
  │
  ├── 建立/恢復群級 scope
  │     scopeId = chat.code
  │     code = from.code
  │     channel = Line
  │     serviceNumberId = to.code
  │
  ├── 建立/恢復 lineGroup 聊天室(透過 RoomFeign 呼叫 room 服務)
  │     type = lineGroup
  │     serviceNumberId = to.code
  │     externalRoomId = chat.code
  │     name = chat.name
  │     avatar = chat.pictureUrl
  │
  └── 加入服務號為房間成員

4.2 MemberJoin(新成員加入)


    
    
    
  Gateway ──→ aile-service-tenant
  │
  ├── 解析 members[]:提取每個 member 的 code、name、pictureUrl
  │
  ├── 確保群級 scope 和 lineGroup 存在(不存在則補建)
  │
  └── 對每個 member:
        ├── 建立/更新 TenantContactModel(聯繫人資料)
        ├── 建立/更新成員級 scope(scopeId = member.code)
        ├── 建立 LineGroupContactRelationModel
        └── 加入 lineGroup 房間成員

4.3 Messaging(群消息)


    
    
    
  Gateway ──→ aile-service-tenant ──→ aile-service-room
  │
  ├── 確保群級 scope 和 lineGroup 存在
  │
  ├── 依 sender.code 懶建立聯繫人/成員級 scope/房間成員
  │     (若此前未收到 MemberJoin)
  │
  ├── 消息寫入 lineGroup 聊天室
  │     senderId = 實際成員聯繫人 ID(非 chat.code)
  │     senderName = 聯繫人名稱
  │
  └── 不創建 ServiceSession,不走機器人流程

4.4 Leave(LINE OA 被移出群)


    
    
    
  Gateway ──→ aile-service-tenant
  │
  ├── 停用 lineGroup 聊天室(軟刪除)
  ├── 停用群級 scope
  └── 批量停用房間成員關係

5. 發送規則詳解

5.1 群級路由

LINE 群組消息外發使用 群級 scopescopeId = chat.code),而非成員級 scope。


    
    
    
  對外發送目標:scopeId = chat.code
路由方式:GatewayFeign → Gateway 群級路由
發送次數:一條內部消息 → 一次外部發送

5.2 發送者展示

展示元素取值來源
senderId實際成員對應的聯繫人 ID
senderName成員聯繫人名稱
senderAvatar成員聯繫人頭像

禁止使用 chat.code 或群級 scope 作為消息發送者。

5.3 與 Services Room 的關鍵差異

維度Services RoomLineGroup Room
會話模型每客戶一個 ServiceSession無 ServiceSession
外發目標成員級 scope(單個客戶)群級 scope(整個群)
機器人流程支援(歡迎語/自動接待/超時)不支援
消息發送者客戶本人群內實際發言人
房間類型serviceslineGroup

6. 冪等性與一致性


7. 關鍵檔案索引

層級檔案說明
API Modelaile-api/aile-room-api/.../constant/RoomType.javaLineGroup 常量
API Modelaile-api/aile-room-api/.../dto/room/LineGroupRoomCreateDto.java建立聊天室 DTO
API Modelaile-api/aile-room-api/.../dto/room/LineGroupRoomInfoSyncDto.java群資訊同步 DTO
API Modelaile-api/aile-room-api/.../dto/room/LineGroupRoomListDto.java列表查詢 DTO
API Modelaile-api/aile-tenant-api/.../model/servicenumber/LineGroupContactRelationModel.java群客戶關聯
API Modelaile-api/aile-tenant-api/.../dto/servicenumber/LineGroupContactRelationListDto.java關聯查詢 DTO
Room 服務aile-service/aile-service-room/.../factory/strategy/impl/LineGroupRoomImpl.java群組聊天室策略
Room 服務aile-service/aile-service-room/.../util/LineGroupUnreadWrite.java未讀數寫入
Room 服務aile-service/aile-service-room/.../util/LineGroupMemberRoomRedisUtil.java成員房間 Redis
Room 服務aile-service/aile-service-room/.../util/LineGroupMemberUnread.java成員未讀
Tenant 服務aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/MemberJoinEventImpl.javaMemberJoin 事件
Tenant 服務aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/MemberLeaveEventImpl.javaMemberLeave 事件
Tenant 服務aile-service/aile-service-tenant/.../service/servicenumber/impl/LineGroupContactRelationServiceImpl.java關聯服務實現
Tenant 服務aile-service/aile-service-tenant/.../controller/servicenumber/LineGroupContactRelationController.java關聯 API
Sagaaile-service/aile-service-tenant/.../saga/step/MergeLineGroupContactRelationStep.javaSaga 合併步驟

8. 驗收條件

功能驗收

資料驗收


Changelog

日期版本變更內容
2026-03-27v1.0初始 Line 群組聊天室細規格
2026-06-13v2.0結合代碼實現補充完整規格(資料模型、服務實現、事件流程、檔案索引)