You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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模型,当客服空闲时自动从队列分配客户

测试验证

  1. 启动Bot后,确认3名客服的is_available状态为True
  2. 用3个不同客户账号同时发起聊天,检查每个客服仅分配一个客户,且状态变为False
  3. 每个客户发送消息,验证仅对应客服收到
  4. 结束任一聊天,检查对应客服状态恢复为True,新客户请求会分配给该空闲客服

内容的提问来源于stack exchange,提问作者Firdavsbek Narzullaev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 13:02:08