用戶進線 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
@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;
String serviceNumberId;
ServiceNumberType serviceNumberType;
String roomId;
String accountId;
String customerId;
String scopeId;
String agentId;
String gwSessionId;
ServiceSessionStatus status;
Channel channel;
Long startTime;
Long activeTime;
Long endTime;
Long distributeTime;
Long robotActiveTime;
Long robotStopTime;
Long timeoutTime;
Integer satisfactionScore;
String satisfactionComment;
}
3. Session 生命週期狀態機
3.1 狀態定義
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 分配上下文
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 統計資料結構
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 | 機器人接待階段的助手觸發 |
| 配額 | 配額檢查 | 會話建立時檢查配額 |
| 進線原因 | ServiceInboundReasonSessionService | 會話關聯進線原因 |
| Saga | ProcessServiceSessionMergeStep | 客戶合併時的會話處理 |
13. 關鍵檔案索引
| 層級 | 檔案 | 說明 |
| API Model | aile-api/aile-tenant-api/.../model/servicenumber/ServiceSessionModel.java | 會話持久化模型 |
| API Enum | aile-api/aile-tenant-api/.../enums/ServiceSessionStatus.java | 會話狀態枚舉 |
| Service | aile-service/aile-service-tenant/.../service/servicenumber/ServiceSessionService.java | 會話服務接口 |
| Service Impl | aile-service/aile-service-tenant/.../service/servicenumber/impl/ServiceSessionServiceImpl.java | 會話服務實現 |
| Controller | aile-service/aile-service-tenant/.../controller/servicenumber/ServiceSessionController.java | 會話 API |
| DTO | aile-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 | 滿意度評價 |
| Saga | aile-service/aile-service-tenant/.../saga/step/ProcessServiceSessionMergeStep.java | Saga 會話合併 |
| Gateway 事件 | aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/ServiceStartEventImpl.java | Gateway 開始事件 |
| Gateway 事件 | aile-service/aile-service-tenant/.../gateway/factory/strategy/impl/ServiceEndEventImpl.java | Gateway 結束事件 |