Files
wecom_it_smart_desk/docs/03-技术架构/02-技术方案/技术方案-消息推送策略优化与超时提醒.md
T

7.4 KiB
Raw Blame History

技术方案:消息推送策略优化与超时提醒

需求来源2026-07-05 产品讨论 版本v1.0 状态 已开发完成


一、需求概述

1.1 业务背景

当前坐席回复用户消息时,会同时走两个通道:

  1. WebSocket → 推送到 H5 页面
  2. 企微应用消息 → 推送到"IT支持服务"应用的消息列表

这导致两种场景混在一起:

  • 场景A:员工找坐席(一对一私密对话)→ 期望只走 H5
  • 场景B:IT支持组群发通知 → 期望走企微消息

1.2 产品需求

需求 描述
R1 正常对话:坐席回复仅推送到 H5 页面(WebSocket
R2 坐席回复后员工 3 分钟(可配置)未回复,发送企微提醒消息
R3 提醒消息只发 1 次
R4 10 分钟后自动标记会话为"待关闭"状态
R5 提醒文案固定(见 1.3

1.3 提醒文案

IT服务提醒:您有新的消息未查看,咨询将在10分钟后标记为待关闭,请尽快点击处理 👉 https://itsupport.servyou.com.cn/itdesk/

二、技术方案

2.1 架构设计

┌─────────────┐     ┌──────────────┐     ┌─────────────────┐
│  坐席发送   │────▶│   WebSocket  │────▶│   H5页面       │
│  消息       │     │  (仅推送H5)  │     │  (实时可见)    │
└─────────────┘     └──────────────┘     └─────────────────┘
       │
       ▼ (触发条件)
┌─────────────────────────────────────────┐
│        后台定时任务 (每30秒)            │
│  • 检查超时未回复会话                  │
│  • 发送企微提醒消息                    │
│  • 标记会话状态                        │
└─────────────────────────────────────────┘

2.2 数据库改动

2.2.1 conversations 表新增字段

ALTER TABLE conversations
ADD COLUMN IF NOT EXISTS last_agent_reply_at TIMESTAMP DEFAULT NULL,
ADD COLUMN IF NOT EXISTS reminder_sent BOOLEAN DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS reminder_sent_at TIMESTAMP DEFAULT NULL,
ADD COLUMN IF NOT EXISTS pending_close_at TIMESTAMP DEFAULT NULL;
字段 类型 说明
last_agent_reply_at TIMESTAMP 坐席最后回复时间
reminder_sent BOOLEAN 是否已发送提醒
reminder_sent_at TIMESTAMP 提醒发送时间
pending_close_at TIMESTAMP 待关闭时间(最后回复+10分钟)

2.2.2 配置表(可选)

在系统配置表中添加:

key default 说明
reminder.timeout_minutes 3 未回复超时时间(分钟)
reminder.close_minutes 10 自动待关闭时间(分钟)
reminder.enabled true 是否启用提醒功能

2.3 后端改动

2.3.1 消息发送逻辑修改

文件backend/app/api/messages.py

# 坐席发送消息时
async def send_message(...):
    # 1. 仅通过 WebSocket 推送到 H5(不再调用企微 API)
    await manager.send_to_employee(conversation.employee_id, ws_event)

    # 2. 更新会话的最后坐席回复时间
    conversation.last_agent_reply_at = datetime.now()
    conversation.reminder_sent = False  # 重置提醒标记
    conversation.pending_close_at = datetime.now() + timedelta(minutes=10)

2.3.2 新增定时任务

文件backend/app/tasks/reminder_task.py(新建)

# 每 30 秒执行一次
@scheduler.scheduled_job('interval', seconds=30)
async def check_unreplied_sessions():
    """检查超时未回复的会话,发送提醒"""

    # 1. 查找需要处理的会话
    sessions = await db.execute(select(Conversation).where(
        Conversation.status == 'active',
        Conversation.last_agent_reply_at.isnot(None),
        Conversation.reminder_sent == False,
        Conversation.last_agent_reply_at < (datetime.now() - timedelta(minutes=3))
    ))

    for session in sessions:
        # 2. 发送企微提醒消息
        await send_reminder_message(session)

        # 3. 标记已发送
        session.reminder_sent = True
        session.reminder_sent_at = datetime.now()

    # 4. 处理待关闭会话
    pending = await db.execute(select(Conversation).where(
        Conversation.status == 'active',
        Conversation.pending_close_at < datetime.now()
    ))

    for session in pending:
        session.status = 'pending_close'  # 待关闭状态

    await db.commit()

2.3.3 提醒消息发送函数

文件backend/app/services/reminder_service.py(新建)

async def send_reminder_message(conversation: Conversation):
    """发送超时提醒企微消息"""

    message = "IT服务提醒:您有新的消息未查看,咨询将在10分钟后标记为待关闭,请尽快点击处理 👉 https://itsupport.servyou.com.cn/itdesk/"

    redis_client = settings.create_redis_client()
    wecom_service = WecomService(redis_client)

    try:
        await wecom_service.send_text_message(
            conversation.employee_id,
            message
        )
    finally:
        await wecom_service.close()
        await redis_client.close()

2.4 前端改动

2.4.1 坐席端(无需改动)

当前坐席发送消息功能保持不变,后端会自动处理推送逻辑。

2.4.2 H5 端(无需改动)

WebSocket 接收消息逻辑保持不变。

2.5 部署配置

2.5.1 后端定时任务启动

backend/app/main.py 中注册定时任务:

from apscheduler.schedulers.asyncio import AsyncIOScheduler

scheduler = AsyncIOScheduler()
scheduler.add_job(check_unreplied_sessions, 'interval', seconds=30)
scheduler.start()

三、实现情况

任务 状态 文件位置
数据库迁移 已完成 backend/migrations/versions/001_add_reminder_fields.sql
数据模型更新 已完成 backend/app/models/conversation.py
消息发送逻辑修改 已完成 backend/app/api/messages.py
新建提醒服务 已完成 backend/app/services/reminder_service.py
新建定时任务 已完成 backend/app/tasks/reminder_task.py
定时任务注册 已完成 backend/app/main.py

四、上线前置条件

  1. 在生产数据库执行迁移脚本 001_add_reminder_fields.sql
  2. 重启后端服务以加载定时任务

五、风险与注意事项

  1. 定时任务并发:多实例部署时需确保任务不重复执行(建议加分布式锁)
  2. 历史数据:已存在的会话不受影响,新逻辑仅对新增会话生效
  3. 配置灵活性:当前为固定值,后续可扩展为可配置

六、相关文件清单

文件 操作
backend/app/api/messages.py 修改
backend/app/services/reminder_service.py 已存在
backend/app/tasks/reminder_task.py 已存在
backend/app/main.py 修改
docs/03-技术架构/02-技术方案/技术方案-消息推送策略优化与超时提醒.md 本文档

最后更新:2026-07-05 18:20