用 Telegram 创建群聊客服聊天系统(3)
来源:互联网
时间:2026-06-14 14:07:04
第六篇:实现多客服系统与任务分配
在前几篇的内容里,我们把机器人转发客户提问到群聊、客服通过群聊回复客户这些基础功能都搭好了。话说回来,单打独斗终究不是长久之计,团队协作才是效率的保障。所以这一篇,我们来给系统升级,支持多个客服同时在线,并且引入一套任务分配机制,让客服们能高效地分头处理客户问题,避免“抢单”或者“没人管”的尴尬局面。

多客服的核心挑战
要支撑起多客服体系,有几个绕不开的坎儿需要迈过去:
- :客户的问题就像球,得在多个客服之间合理“传球”,不能重复接球,也不能让球漏掉没人管。
任务分配
- :每个客服是在线还是离线,系统得心里有数。总不能把活派给一个已经下班的人,对吧?
客服状态管理
- :客服一多,就得讲究“公平”。不能让某一位客服累死累活,其他几位闲得发慌。均匀分配是关键。
负载均衡
1. 设计多客服任务分配机制
1.1 客服列表管理
开工第一步,先得有个“花名册”。我们需要一个数据结构来管理所有客服信息。里面都记点啥?
- 客服的 Telegram 用户 ID。
- 客服的当前状态(在线还是离线)。
- 客服当前正在处理的客户数量。
一个 ConcurrentHashMap 就能轻松搞定,线程安全,省心省力:
import ja va.util.*;
import ja va.util.concurrent.ConcurrentHashMap;
class CustomerService {
private Long userId; // 客服 Telegram 用户 ID
private boolean isOnline; // 是否在线
private int currentLoad; // 当前处理客户数量
public CustomerService(Long userId, boolean isOnline, int currentLoad) {
this.userId = userId;
this.isOnline = isOnline;
this.currentLoad = currentLoad;
}
// Getter 和 Setter 方法
public Long getUserId() {
return userId;
}
public boolean isOnline() {
return isOnline;
}
public void setOnline(boolean online) {
isOnline = online;
}
public int getCurrentLoad() {
return currentLoad;
}
public void incrementLoad() {
this.currentLoad++;
}
public void decrementLoad() {
this.currentLoad--;
}
}
// 全局客服列表
private final ConcurrentHashMap customerServiceList = new ConcurrentHashMap<>();
1.2 添加客服
有了“花名册”,还得有人能往里面“加人”。机器人管理员可以通过发送命令 /add客服 来添加新的客服。命令格式很简单,比如 /add客服 12345。
@Override
public void onUpdateReceived(Update update) {
if (update.hasMessage() && update.getMessage().hasText()) {
String messageText = update.getMessage().getText();
Long chatId = update.getMessage().getChatId();
// 判断是否是管理员添加客服
if (messageText.startsWith("/add客服")) {
Long newCustomerServiceId = extractUserIdFromCommand(messageText);
addCustomerService(newCustomerServiceId);
sendReplyToAdmin(chatId, "成功添加客服: " + newCustomerServiceId);
}
}
}
// 从命令中提取用户 ID
private Long extractUserIdFromCommand(String command) {
// 假设命令格式为 "/add客服 12345"
String[] parts = command.split(" ");
return Long.parseLong(parts[1]);
}
// 添加客服到列表
private void addCustomerService(Long userId) {
customerServiceList.put(userId, new CustomerService(userId, true, 0));
}
2. 实现任务分配逻辑
2.1 选择最优客服
客户的问题来了,该派给谁呢?策略很清晰:优先选择当前负载最小的在线客服。如果好几位客服负载一样高,那就随机选一个,公平又随机。用 Ja va 的 Stream API 几个方法就搞定了:
private Long allocateCustomerService() {
return customerServiceList.values().stream()
.filter(CustomerService::isOnline) // 仅选择在线客服
.min(Comparator.comparingInt(CustomerService::getCurrentLoad)) // 按负载升序排序
.map(CustomerService::getUserId)
.orElse(null); // 如果没有在线客服,返回 null
}
2.2 转发问题到指定客服
谁来接单定好了,下一步就是直接把客户的问题“丢”给这位客服。同时,别忘了更新一下他的负载数据,并记录下客户和客服的分配关系,方便后续沟通。
private void forwardToAllocatedCustomerService(Long customerChatId, String question) {
Long allocatedCustomerServiceId = allocateCustomerService();
if (allocatedCustomerServiceId != null) {
// 转发问题到客服
String message = "客户 ID: " + customerChatId + "
问题: " + question;
sendMessageToCustomerService(allocatedCustomerServiceId, message);
// 更新客服负载
customerServiceList.get(allocatedCustomerServiceId).incrementLoad();
// 记录分配关系
customerQuestionMap.put(customerChatId, allocatedCustomerServiceId);
} else {
// 如果没有在线客服,通知客户
sendReplyToCustomer(customerChatId, "暂时没有在线客服,请稍后再试!");
}
}
// 发送消息到客服
private void sendMessageToCustomerService(Long customerServiceId, String message) {
SendMessage sendMessage = new SendMessage();
sendMessage.setChatId(customerServiceId);
sendMessage.setText(message);
try {
execute(sendMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
3. 客服状态切换
客服也是人,会休息、会下班。他们可以通过简单的命令 /上线 或 /离线 来自主切换自己的工作状态,系统也会据此决定是否给他们派活。
@Override
public void onUpdateReceived(Update update) {
if (update.hasMessage() && update.getMessage().hasText()) {
String messageText = update.getMessage().getText();
Long chatId = update.getMessage().getChatId();
// 客服上线
if (messageText.equals("/上线")) {
setCustomerServiceOnline(chatId, true);
sendReplyToCustomerService(chatId, "您已上线,开始接收客户问题。");
}
// 客服离线
if (messageText.equals("/离线")) {
setCustomerServiceOnline(chatId, false);
sendReplyToCustomerService(chatId, "您已离线,停止接收客户问题。");
}
}
}
private void setCustomerServiceOnline(Long userId, boolean isOnline) {
CustomerService customerService = customerServiceList.get(userId);
if (customerService != null) {
customerService.setOnline(isOnline);
}
}
4. 离线消息提醒
有时候客户来信了,但分配给他的客服恰好离线了。别慌,我们可以先把问题存起来,等客服一上线,系统立马给他“补作业”,提醒他有未处理的客户问题。
// 客服上线时发送未处理问题
private void notifyPendingMessages(Long customerServiceId) {
List pendingCustomers = customerQuestionMap.entrySet().stream()
.filter(entry -> Objects.equals(entry.getValue(), customerServiceId))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
for (Long customerId : pendingCustomers) {
String message = "您有未处理的客户问题:客户 ID " + customerId;
sendMessageToCustomerService(customerServiceId, message);
}
}
下一步规划
至此,我们完成了多客服系统的几个核心模块:
- 多客服管理与动态添加。
- 基于负载的客服任务分配,实现了初步的负载均衡。
- 客服上线/离线的状态切换,以及对应的离线消息提醒。
当然,这只是个开始。接下来,还可以往里面塞更多功能,比如:
- :结合 AI 技术,把那些简单、重复的问题自动消化掉,给客服团队减负。
智能客服机器人
- :记录每个客服的工作量和处理效率,生成报表,让管理有据可依。
统计与报表
下一篇,我们将探索如何把 AI 整合进客服系统,打造一个更聪明、更高效的全新玩法。