用戶進線 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 會話超時
| 任務 | 位置 | 說明 |
|---|---|---|
SessionTimeoutScheduleTask | aile-service-tenant/.../task/ | 定時掃描超時會話 |
OnceSessionTimeoutTask | aile-service-tenant/.../task/ | 單次超時處理 |
8.2 會話空閒
| 任務 | 位置 | 說明 |
|---|---|---|
SessionIdleScheduleTask | aile-service-tenant/.../task/ | 掃描空閒過久的會話 |
OnceSessionIdleTask | aile-service-tenant/.../task/ | 單次空閒處理 |
8.3 自動轉接
| 任務 | 位置 | 說明 |
|---|---|---|
OwnerAutoTransferScheduleTask | aile-service-tenant/.../task/ | 客服離線自動轉接 |
OnceOwnerAutoTransferTask | aile-service-tenant/.../task/ | 單次自動轉接處理 |
8.4 自動結束
| 任務 | 位置 | 說明 |
|---|---|---|
OwnerAutoStopScheduleTask | aile-service-tenant/.../task/ | 客服離線自動結束會話 |
OnceOwnerAutoStopTask | aile-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) | 刷新會話、檢查房間狀態 |
| Gateway | Webhook 事件 | 接收 ServiceStart/ServiceEnd 事件 |
| 助手 | PubSub + Feign | 機器人接待階段的助手觸發 |
| 配額 | 配額檢查 | 會話建立時檢查配額 |