基于Django+python-telegram-bot的多客服消息混乱问题求助
解决多客服多客户场景下的消息混乱问题
你遇到的消息混乱本质是缺少客服状态管理+消息路由逻辑失效——因为没有维护is_available状态,系统无法区分空闲/忙碌客服,会把新客户请求分配给忙碌客服,或者把客户消息错发给其他客服。以下是具体修复方案:
1. 恢复客服状态切换核心逻辑
首先确认你的Django客服模型(示例命名为SupportAgent)已包含状态字段,然后实现状态切换的原子操作:
客服模型定义
# models.py from django.db import models class SupportAgent(models.Model): telegram_id = models.BigIntegerField(unique=True) name = models.CharField(max_length=100) is_available = models.BooleanField(default=True) # 标记是否空闲 def __str__(self): return self.name # 新增客户-客服绑定模型,用于消息路由 class CustomerChatBinding(models.Model): customer_telegram_id = models.BigIntegerField(unique=True) agent = models.ForeignKey(SupportAgent, on_delete=models.CASCADE)
接入客户时标记忙碌(原子分配)
用数据库事务+行锁避免并发场景下的重复分配:
# 处理客户发起聊天的Bot Handler from django.db import transaction from .models import SupportAgent, CustomerChatBinding def assign_agent_to_customer(customer_telegram_id): with transaction.atomic(): # 原子获取并锁定第一个空闲客服 agent = SupportAgent.objects.select_for_update().filter(is_available=True).first() if not agent: # 无空闲客服时的处理逻辑,比如提示客户排队 return None # 标记客服为忙碌 agent.is_available = False agent.save() # 绑定客户与客服,用于后续消息路由 CustomerChatBinding.objects.get_or_create( customer_telegram_id=customer_telegram_id, defaults={'agent': agent} ) return agent
结束聊天时恢复空闲
def end_chat(customer_telegram_id): try: binding = CustomerChatBinding.objects.get(customer_telegram_id=customer_telegram_id) # 恢复客服空闲状态 agent = binding.agent agent.is_available = True agent.save() # 解除绑定关系 binding.delete() return True except CustomerChatBinding.DoesNotExist: return False
2. 修正消息路由逻辑
所有消息必须通过CustomerChatBinding路由,确保仅在绑定的客服与客户之间传递:
客户消息转发给绑定客服
def handle_customer_message(update, context): customer_id = update.effective_user.id try: binding = CustomerChatBinding.objects.get(customer_telegram_id=customer_id) # 转发客户消息给对应客服 context.bot.send_message( chat_id=binding.agent.telegram_id, text=f"客户[{customer_id}]:{update.message.text}" ) except CustomerChatBinding.DoesNotExist: update.message.reply_text("请先发起聊天请求,我们会安排空闲客服对接")
客服消息转发给绑定客户
def handle_agent_message(update, context): agent_id = update.effective_user.id # 获取当前客服绑定的客户(一对一场景取第一个即可) bindings = CustomerChatBinding.objects.filter(agent__telegram_id=agent_id) if not bindings: update.message.reply_text("您当前没有对接的客户") return binding = bindings.first() # 转发客服消息给对应客户 context.bot.send_message( chat_id=binding.customer_telegram_id, text=f"客服[{binding.agent.name}]:{update.message.text}" )
3. 并发场景额外保障
- 给
SupportAgent的is_available字段添加数据库索引,提升空闲客服查询效率 - 若需支持客户排队,可新增
CustomerQueue模型,当客服空闲时自动从队列分配客户
测试验证
- 启动Bot后,确认3名客服的
is_available状态为True - 用3个不同客户账号同时发起聊天,检查每个客服仅分配一个客户,且状态变为
False - 每个客户发送消息,验证仅对应客服收到
- 结束任一聊天,检查对应客服状态恢复为
True,新客户请求会分配给该空闲客服
内容的提问来源于stack exchange,提问作者Firdavsbek Narzullaev
相关产品推荐
相关产品推荐

