跳至主要内容

用戶進線 Session 過程規格說明書

版本: v1.0
最後更新: 2026-06-13
服務範圍: aile-service-tenant(核心)、aile-service-room(協同)


1. 概述

用戶進線 Session(ServiceSession)是 Aile 客服系統的核心會話管理機制。每當客戶透過 LINE 私聊或其他渠道向服務號發起對話時,系統會建立一條 ServiceSession 記錄,追蹤從機器人接待到人工服務的完整生命週期。

1.1 核心概念

概念說明
ServiceSession一次客戶進線的完整會話記錄
Session 狀態9 種狀態:RobotActive → DistributeActive → AgentActive → ... → End
機器人接待客戶進線後首先由機器人(AI 助手)接待
轉人工客戶請求或系統判定需要轉接人工客服
分配策略基於員工權重(RoomWeight)的自動分配

2. ServiceSessionModel(會話持久化模型)

2.1 資料結構

MongoDB 集合:aile.tenant.servicenumber.session

// aile-api/aile-tenant-api/.../model/servicenumber/ServiceSessionModel.java
@Document("aile.tenant.servicenumber.session")
@CompoundIndexes({
@CompoundIndex(name = "serviceNumberId", def = "{'serviceNumberId': 1}"),
@CompoundIndex(name = "roomId_1_updateTime_1", def = "{'roomId': 1, 'updateTime': 1}"),
@CompoundIndex(name = "roomId_1_channel_1_updateTime_1", def = "{'roomId': 1, 'channel': 1, 'updateTime': 1}"),
@CompoundIndex(name = "gwSessionId_1", def = "{'gwSessionId': 1}"),
@CompoundIndex(name = "serviceNumberId_1_status_1", def = "{'serviceNumberId': 1, 'status': 1}"),
@CompoundIndex(name = "serviceNumberId_1_status_1_agentId_1", def = "{'serviceNumberId': 1, 'status': 1, 'agentId': 1}"),
@CompoundIndex(name = "agentId_1_status_1", def = "{'agentId': 1, 'status': 1}"),
@CompoundIndex(name = "serviceNumberId_1_scopeId_1", def = "{'serviceNumberId': 1, 'scopeId': 1}"),
@CompoundIndex(name = "status_1_activeTime_1", def = "{'status': 1, 'activeTime': 1}"),
@CompoundIndex(name = "status_1_distributeTime_1", def = "{'status': 1, 'distributeTime': 1}"),
@CompoundIndex(name = "serviceNumberId_1_startTime_1", def = "{'serviceNumberId': 1, 'startTime': 1}")
})
public class ServiceSessionModel extends BaseModel {
String tenantId; // 租戶 ID
String serviceNumberId; // 服務號 ID
ServiceNumberType serviceNumberType; // 服務號類型
String roomId; // 聊天室 ID
String accountId; // 帳號 ID
String customerId; // 客戶(聯繫人)ID
String scopeId; // 客戶渠道 scopeId
String agentId; // 接待客服的 memberId
String gwSessionId; // Gateway 側的 session ID
ServiceSessionStatus status; // 會話狀態
Channel channel; // 進線渠道(Line / WhatsApp 等)
Long startTime; // 會話開始時間
Long activeTime; // 最近活躍時間
Long endTime; // 會話結束時間
Long distributeTime; // 人工分配時間
Long robotActiveTime; // 機器人開始接待時間
Long robotStopTime; // 機器人接待結束時間
Long timeoutTime; // 超時時間
// 滿意度
Integer satisfactionScore; // 滿意度評分
String satisfactionComment; // 滿意度備註
}

3. Session 生命週期狀態機

3.1 狀態定義

// aile-api/aile-tenant-api/.../enums/ServiceSessionStatus.java
public enum ServiceSessionStatus {
RobotActive, // 機器人服務中
RobotStop, // 機器人服務結束
DistributeActive, // 轉人工,剛進件(等待分配)
AgentActive, // 客服人員服務中
AgentStop, // 客服人員服務結束
CustomerStop, // 客戶主動結束
Timeout, // 服務超時結束
NoWorkTimeStop, // 非上班時間結束
Deleted // 標記刪除
}

3.2 狀態轉換圖

客戶進線


RobotActive ──────────────────────────────────────┐
│ │
├──→ RobotStop(機器人主動結束) │
│ │
├──→ DistributeActive(轉人工) │
│ │ │
│ ├──→ AgentActive(分配成功) │
│ │ │ │
│ │ ├──→ AgentStop(客服結束) │
│ │ ├──→ CustomerStop(客戶結束) │
│ │ └──→ Timeout(超時) │
│ │ │
│ └──→ NoWorkTimeStop(非工作時間) │
│ │
├──→ CustomerStop(客戶主動結束) │
├──→ Timeout(超時) │
└──→ NoWorkTimeStop(非工作時間) │

(所有結束狀態可被標記為 Deleted) ◄──────────────────┘

3.3 活躍狀態判斷

// 以下三個狀態為「活躍中」
activeStatus = [RobotActive, DistributeActive, AgentActive]

// 「主要活躍」(人工相關)
isMainActive() → DistributeActive || AgentActive

// 「已離線」
isOffline() → RobotStop || AgentStop || CustomerStop || Timeout || NoWorkTimeStop || Deleted

4. ServiceSessionService(會話服務接口)

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

4.1 核心方法

方法說明狀態變更
start(dto)客戶進線,開始新會話→ RobotActive
startRobotActive(model)啟動機器人接待→ RobotActive
stopRobotService(model)停止機器人接待RobotActive → RobotStop
warningRobotService(model)機器人接待預警RobotActive(不變)
startDistributeService(model, context)轉人工分配→ DistributeActive
agentStartService(dto, employeeId)客服接起DistributeActive → AgentActive
agentStopService(dto)客服結束AgentActive → AgentStop
customerStopService(dto)客戶結束RobotActive/AgentActive → CustomerStop
timeout(model)超時結束活躍狀態 → Timeout
agentSwitchRobot(dto)客服轉機器人AgentActive → RobotActive
transfer(model, memberId)轉接給其他客服AgentActive → AgentActive(更換 agentId)
refreshSession(dto)刷新會話活躍時間更新 activeTime
ownerStopService(model)管理員強制結束任意活躍 → AgentStop
getLastSession(roomId)查詢最近一次會話-

4.2 分配上下文

// aile-service/aile-service-tenant/.../service/servicenumber/dto/ServiceSessionDistributeContext.java
public class ServiceSessionDistributeContext {
String serviceNumberId;
String roomId;
String employeeId; // 指定客服(選填,不指定則自動分配)
RoomWeightEventCode eventCode; // 分配事件碼
boolean checkWorkTime; // 是否檢查工作時間
}

5. 會話啟動流程

5.1 客戶進線

Gateway Webhook(LINE 私聊消息)

└── aile-service-tenant (GatewayController)

├── 解析 Webhook:提取 sender.code、to.code、message
├── 查找/建立 TenantContactModel(聯繫人)
├── 查找/建立 ServiceNumberScopeModel(渠道關聯)
├── 查找/建立 Services Room(私聊聊天室)

├── ServiceSessionService.start(startDto)
│ ├── 檢查是否已有活躍會話(同一 roomId + channel)
│ │ ├── 有 → 刷新現有會話(refreshSession)
│ │ └── 無 → 建立新會話
│ ├── status = RobotActive
│ └── 記錄 startTime、robotActiveTime

├── 消息寫入 Services Room

└── 觸發助手管線(AssistantTriggerPublishService)
└── 若無助手或助手不匹配 → 直接轉人工

5.2 機器人接待結束

客戶發送特定關鍵詞(如「轉人工」)或系統規則觸發

└── ServiceSessionService.stopRobotService(session)
├── status: RobotActive → RobotStop
├── 記錄 robotStopTime
└── 可選:自動觸發 startDistributeService

6. 轉人工分配流程

6.1 分配觸發

轉人工有三種觸發方式:

方式觸發條件
客戶請求客戶發送「轉人工」等關鍵詞
機器人無法處理AI 助手判斷需轉人工(返回特定信號)
系統規則無助手配置的服務號,直接轉人工

6.2 分配邏輯

ServiceSessionService.startDistributeService(session, context)

├── 檢查工作時間(context.checkWorkTime = true)
│ ├── 非工作時間 → status = NoWorkTimeStop → return null
│ └── 工作時間 → 繼續

├── 若指定 employeeId(指定客服)
│ └── 查詢該客服是否在線且可接待

├── 若未指定(自動分配)
│ └── 基於 RoomWeight 系統自動選擇最合適的客服
│ ├── 查詢該服務號的在線客服列表
│ ├── 依權重排序(空閒度、技能匹配、接待數量等)
│ └── 選擇權重最高的客服

├── status: RobotActive → DistributeActive(若需等待)或直接 → AgentActive
├── 記錄 distributeTime

└── 發送分配通知(Socket.IO / PubSub)

6.3 客服接起

ServiceSessionService.agentStartService(dto, employeeId)

├── 驗證 employeeId 是否為分配目標
├── status: DistributeActive → AgentActive
├── 記錄 agentId
└── 發送會話開始消息(AgentStartMessageEvent)

7. 會話結束流程

7.1 客服結束

客服點擊「結束會話」

└── ServiceSessionService.agentStopService(dto)
├── status: AgentActive → AgentStop
├── 記錄 endTime
└── 發送 AgentStopMessageEvent

7.2 客戶結束

客戶發送結束信號或 Gateway 推送 ServiceEnd 事件

└── ServiceSessionService.customerStopService(dto)
├── status: RobotActive/AgentActive → CustomerStop
├── 記錄 endTime
└── 清除活躍會話緩存

7.3 超時結束

SessionTimeoutScheduleTask(定時掃描)

└── 掃描 activeTime 超過配置閾值的活躍會話
├── status → Timeout
└── 發送 SessionTimeoutEvent

8. 定時任務

8.1 會話超時

任務位置說明
SessionTimeoutScheduleTaskaile-service-tenant/.../task/定時掃描超時會話
OnceSessionTimeoutTaskaile-service-tenant/.../task/單次超時處理

8.2 會話空閒

任務位置說明
SessionIdleScheduleTaskaile-service-tenant/.../task/掃描空閒過久的會話
OnceSessionIdleTaskaile-service-tenant/.../task/單次空閒處理

8.3 自動轉接

任務位置說明
OwnerAutoTransferScheduleTaskaile-service-tenant/.../task/客服離線自動轉接
OnceOwnerAutoTransferTaskaile-service-tenant/.../task/單次自動轉接處理

8.4 自動結束

任務位置說明
OwnerAutoStopScheduleTaskaile-service-tenant/.../task/客服離線自動結束會話
OnceOwnerAutoStopTaskaile-service-tenant/.../task/單次自動結束處理

9. 會話統計

9.1 統計接口

路由:/servicenumber/session/statistics

維度說明
按服務號每個服務號的會話總數、活躍數、結束數
按時間按月/按日統計會話趨勢
按客服每個客服的接待量、平均處理時間
按機器人機器人接待比例、轉人工率

9.2 統計資料結構

// aile-api/aile-tenant-api/.../vo/servicenumber/statistics/ServiceSessionStatisticsVO.java
public class ServiceSessionStatisticsVO {
long totalCount; // 總會話數
long activeCount; // 活躍會話數
long robotActiveCount; // 機器人接待數
long agentActiveCount; // 人工接待數
long endedCount; // 已結束數
long timeoutCount; // 超時數
double avgHandleTime; // 平均處理時間(秒)
double robotRatio; // 機器人處理比例
double transferRatio; // 轉人工比例
}

10. 會話通知機制

10.1 通知事件

位置:aile-service/aile-service-tenant/.../notice/session/

事件類觸發時機
SessionRobotActiveEvent機器人開始接待
SessionRobotStopEvent機器人接待結束
SessionRobotWarningEvent機器人接待預警
SessionDistributeActiveEvent進入分配佇列
SessionAgentActiveEvent客服接起
SessionAgentStopEvent客服結束
SessionTimeoutEvent會話超時

10.2 會話消息

位置:aile-service/aile-service-tenant/.../session/message/

事件說明
SessionStartMessageEvent會話開始卡片消息
RobotActiveMessageEvent機器人接待中卡片消息
RobotStopMessageEvent機器人接待結束消息
AgentStartMessageEvent人工客服接入消息
AgentStopMessageEvent人工客服結束消息
TimeoutMessageEvent會話超時消息

11. 滿意度評價

11.1 評價服務

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

會話結束(AgentStop / CustomerStop)

└── SatisfactionSurveyService.sendSurvey(session)
├── 向客戶推送滿意度評價卡片
├── 客戶評分 → 記錄 satisfactionScore
└── 客戶可選填評論 → 記錄 satisfactionComment

12. 與其他模組的協作

模組互動方式說明
Room 服務Feign(ServiceSessionFeign刷新會話、檢查房間狀態
GatewayWebhook 事件接收 ServiceStart/ServiceEnd 事件
助手PubSub + Feign機器人接待階段的助手觸發
配額配額檢查會話建立時檢查配額
進線原因ServiceInboundReasonSessionService會話關聯進線原因
SagaProcessServiceSessionMergeStep客戶合併時的會話處理

13. 關鍵檔案索引

層級檔案說明
API Modelaile-api/aile-tenant-api/.../model/servicenumber/ServiceSessionModel.java會話持久化模型
API Enumaile-api/aile-tenant-api/.../enums/ServiceSessionStatus.java會話狀態枚舉
Serviceaile-service/aile-service-tenant/.../service/servicenumber/ServiceSessionService.java會話服務接口
Service Implaile-service/aile-service-tenant/.../service/servicenumber/impl/ServiceSessionServiceImpl.java會話服務實現
Controlleraile-service/aile-service-tenant/.../controller/servicenumber/ServiceSessionController.java會話 API
DTOaile-service/aile-service-tenant/.../service/servicenumber/dto/ServiceSessionDistributeContext.java分配上下文
通知aile-service/aile-service-tenant/.../notice/session/SessionNoticeUtil.java會話通知工具
通知事件aile-service/aile-service-tenant/.../notice/session/event/*.java各類通知事件
消息事件aile-service/aile-service-tenant/.../session/message/*.java會話消息事件
消息工具aile-service/aile-service-tenant/.../session/SessionMessageUtil.java會話消息工具
定時任務aile-service/aile-service-tenant/.../task/SessionTimeoutScheduleTask.java超時掃描
定時任務aile-service/aile-service-tenant/.../task/SessionIdleScheduleTask.java空閒掃描
定時任務aile-service/aile-service-tenant/.../task/OwnerAutoTransferScheduleTask.java自動轉接
定時任務aile-service/aile-service-tenant/.../task/OwnerAutoStopScheduleTask.java自動結束
滿意度aile-service/aile-service-tenant/.../service/servicenumber/SatisfactionSurveyService.java滿意度評價
Sagaaile-service/aile-service-tenant/.../saga/step/ProcessServiceSessionMergeStep.javaSaga 會話合併
Gateway 事件aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/ServiceStartEventImpl.javaGateway 開始事件
Gateway 事件aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/ServiceEndEventImpl.javaGateway 結束事件