在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

项目简介

本系统是一个基于 Python 的微信群自动化管理工具,主要用于快递云仓售后服务场景。系统通过 WebSocket 连接微信机器人,自动识别群消息中的快递单号和关键词,将消息智能转发到对应的快递公司售后对接群,并记录处理数据。

功能特性

1. 智能消息识别

  • 自动识别消息中的快递单号(支持申通、中通、圆通、韵达、邮政、极兔、顺丰)
  • 关键词检测:拦截、催件、改地址等
  • 支持单条和多条快递单号混合识别
  • 支持空格、逗号、换行等多种分隔符

2. 自动转发功能

  • 根据快递公司自动转发到对应售后群
  • 支持一对多转发(同一快递公司配置多个群时依次转发)
  • 自动@原始发送者并回复处理状态
  • 全局串行发送队列,保证高并发下消息顺序与限速

2.1 WebUI 配置界面

  • 浏览器里管理所有配置,改完自动生效,无需重启机器人
  • 运行状态面板:连接状态、消息量、发送成功/失败、队列积压
  • Excel 记录在线查看与下载

3. 数据记录

  • 自动记录处理数据到 Excel 表格
  • 分类存储拦截、催件、改地址等不同类型的任务
  • 按快递公司和网点分类存储

4. 稳定连接

  • WebSocket 长连接,自动重连机制
  • 心跳保活(60秒间隔)
  • 断线自动重连,指数退避策略

5. 群组管理

  • 自动记录新加入的群组信息
  • 群组数据持久化存储

6. 截单提醒功能

  • 定时向指定客户群发送截单提醒
  • 支持多个截单时间点配置(15点、16点、17点)
  • 提前半小时自动发送提醒通知
  • 灵活配置提醒消息模板和提醒时间

7. 消息去重功能

  • 自动检测并过滤重复接收的消息
  • 防止重复处理导致的多次转发和数据重复
  • 基于消息指纹的高效去重算法
  • 自动清理过期的消息记录(默认5分钟)

环境要求

  • Python 3.7+
  • Windows/Linux/MacOS
  • 稳定的网络连接

安装步骤

1. 克隆或下载项目

cd /path/to/cloudexpress

2. 创建虚拟环境(推荐)

python -m venv venv

# Windows
venv\Scripts\activate

# Linux/MacOS
source venv/bin/activate

3. 安装依赖

pip install -r requirements.txt

依赖包说明:

  • requests - HTTP 请求库
  • websockets - WebSocket 客户端
  • python-dotenv - 环境变量管理
  • openpyxl - Excel 文件操作
  • filelock - 文件锁,防止并发写入冲突
  • aiohttp - 异步 HTTP 客户端
  • APScheduler - 截单提醒定时调度
  • fastapi / uvicorn / pydantic - WebUI 配置界面

4. 启动

Windows 下双击即可,两个窗口互不影响:

脚本 作用
start_bot.bat 启动消息转发机器人
start_webui.bat 启动配置界面,浏览器打开 http://127.0.0.1:8000
stop_all.bat 停止所有 Python 进程

命令行方式:

python main.py           # 机器人
python webui_server.py   # WebUI(另开一个终端)

机器人和 WebUI 是两个独立进程,通过配置文件通信。WebUI 挂掉不影响消息转发,
机器人重启也不影响 WebUI。在 WebUI 里保存配置后,机器人会在 10 秒内自动加载,无需重启。

配置说明

1. 编辑 .env 配置文件

# 基础信息配置
TOKEN=wx_E2k7qPKTJt8zMpNyLrrX2           # 微信机器人Token
ROBOT_ID=wxid_cnw193tl86kx22            # 机器人微信ID
SERVER_IP=124.223.95.144                # WebSocket服务器IP
SERVER_PORT=5555                        # WebSocket服务器端口

# 统一回复模板
RESPONSE_M='已加急联系快递处理了!'

# 触发关键词
KEYWORDS=['拦截', '退回', '拒收', '催件', '催更', '催促', '地址']

# 各快递公司售后群昵称配置
STO=['申通售后群']                                              # 申通快递
ZTO=['大鹏D中通(吉州分部)售后对接群','大鹏D中通(工业园)售后对接群']  # 中通快递
YDA=['大鹏D韵达(庐陵)售后对接群','大鹏D韵达(吉贤路)售后对接群']      # 韵达快递
EMS=['大鹏D邮政(安福县)售后对接群','大鹏D邮政(吉安)售后对接群','大鹏D邮政(吉水县)售后对接群']  # 邮政快递
YTO=['圆通售后群']                                              # 圆通快递
JTE=['大鹏D极兔(庐陵)售后对接群']                                # 极兔快递
SFE=['顺丰售后群']                                              # 顺丰快递

# 截单提醒配置
CUTOFF_REMINDER_MESSAGE='亲,今日的截单点({time})将至,麻烦检查一下系统里是否有未审核的订单,谢谢!'
ADVANCE_REMINDER_MINUTES=30                                    # 提前30分钟发送提醒

2. 配置说明

快递公司识别规则
快递公司 单号开头 配置变量
申通 77 STO
中通 73/75/76/78 ZTO
圆通 YT/yt YTO
韵达 3/4 YDA
邮政 9 EMS
极兔 JT/jt JTE
顺丰 SF/sf SFE

前缀按长度从长到短匹配,因此 73757678 会正确归为中通,
不会被 34(韵达)抢先匹配。

关键词识别规则
  • 拦截任务:包含"拦截"、“退回”、“拒收”、“召回”
  • 催件任务:包含"催件"、“催更”、“催促”、“物流不更新”
  • 改地址任务:包含"改地址"、“新地址”、“正确地址”、“地址”

消息需同时命中触发关键词和有效运单号才会被处理。只有关键词没有单号时,
机器人回复"未识别到有效运单号"提示,不会承诺已处理。

邮政快递说明

邮政只有一个合作网点,与其他快递处理方式一致:单号以 9 开头即转发到 EMS
配置的售后群,不再查询物流信息判断网点。

3. 群组数据配置

系统会自动将检测到的群组信息保存到 groupdata/groupdata.json,无需手动配置。
机器人在某个群收到第一条文本消息时,就会记录该群的名称和 ID。

配置快递群的正确顺序

  1. 把机器人拉进所有需要的群
  2. 在每个群里随便发一条消息,让机器人记录群 ID
  3. 打开 WebUI 的「快递群配置」,从下拉框里选择群名(避免手输错字)

WebUI 会把配置了群名但查不到群 ID 的项标红提示,转发失效能第一时间发现。

4. 截单提醒配置

截单提醒功能用于在指定时间点前自动向客户群发送截单通知。

4.1 配置截单时间和客户群

编辑 task/task.json 文件,配置不同时间点需要提醒的客户群:

{
  "15": [
    "永新顺为",
    "永瑞药业",
    "秋叶源",
    "顽大夫",
    "新桥仓",
    "西洋参山茱萸茶",
    "裕耀咖啡"
  ],
  "16": [
    "米炭",
    "牛乐",
    "一慕",
    "开元堂",
    "MW仓"
  ],
  "17": [
    "文具用品仓",
    "复真工厂",
    "本初食品",
    "尚腾",
    "橙子母婴"
  ]
}

配置说明:

  • 键名(“15”、“16”、“17”)表示截单时间点(24小时制)
  • 值为数组,包含需要在该时间点接收提醒的客户群昵称
  • 群昵称必须与微信群实际昵称完全一致
  • 系统会在截单时间点前30分钟(可在.env中配置)发送提醒
4.2 配置提醒消息内容

.env 文件中配置提醒消息模板:

# 截单提醒消息模板({time}会被替换为实际截单时间)
CUTOFF_REMINDER_MESSAGE='亲,今日的截单点({time})将至,麻烦检查一下系统里是否有未审核的订单,谢谢!'

# 提前提醒时间(分钟)
ADVANCE_REMINDER_MINUTES=30

示例效果:

如果配置15点截单,系统会在14:30向所有15点截单的客户群发送:

亲,今日的截单点(15:00)将至,麻烦检查一下系统里是否有未审核的订单,谢谢!
4.3 添加或修改截单时间点

如需添加新的截单时间点,只需在 task.json 中添加新的键值对:

{
  "15": ["客户群1", "客户群2"],
  "16": ["客户群3"],
  "17": ["客户群4"],
  "18": ["客户群5", "客户群6"]  // 新增18点截单
}

如需修改某个时间点的客户群列表,直接编辑对应的数组即可。

WebUI 使用说明

浏览器打开 http://127.0.0.1:8000,七个标签页:

页面 能做什么
运行状态 配置体检告警、机器人是否在跑、WebSocket 是否连上、消息量、发送成功/失败数、队列积压、近 7 天处理量统计
基础配置 Token、机器人ID、服务器地址、回复模板、发送间隔、重试次数、截单提醒模板
快递群配置 每家快递对应哪些售后群,从已知群下拉选择
触发关键词 增删触发词;下方展示任务分类规则
截单提醒 增删截单时间点和客户群,实时显示每个时间点的实际发送时刻
群映射 查看/改名/删除已记录的群,显示每个群被哪些配置引用
数据记录 按群/类型/日期筛选 Excel 文件,在线查看明细,下载原文件

登录与密码

首次使用:打开 http://127.0.0.1:8000 会自动跳到初始化页面,设置一个访问密码
(至少 6 位)即可进入。密码以 PBKDF2-SHA256 哈希存入 .envWEBUI_PASSWORD_HASH
不保存明文。

日常登录:输入密码即可。登录状态保存 12 小时(WEBUI_SESSION_HOURS 可调),
过期后自动跳回登录页。右上角可以「修改密码」和「退出登录」。

忘记密码怎么办:编辑 .env,把 WEBUI_PASSWORD_HASH= 后面的内容删空,
重启 WebUI,就会重新进入初始化页面设置新密码。

安全机制:

  • 会话用 HMAC 签名的 Cookie,带 HttpOnly(JS 读不到)和 SameSite=Strict(防 CSRF)
  • 连续 5 次密码错误锁定该 IP 5 分钟,按 IP 独立计数
  • 修改密码会轮换签名密钥,所有设备上的登录状态立即失效
  • 界面上 Token 默认脱敏,要看原值需显式点按钮

局域网访问

默认只监听 127.0.0.1,仅本机可访问。如需让同事也能用,改 .env

WEBUI_HOST=0.0.0.0

然后其他机器访问 http://这台机器的IP:8000。密码是强制的(未设置密码时任何接口都返回 401),
所以不存在裸奔的情况,但仍建议设置足够强度的密码 —— 这个界面能读到机器人 Token。

如果旧版 .env 里还留着明文的 WEBUI_PASSWORD,启动时会自动转成哈希并清空明文字段。

使用方法

1. 启动程序

python main.py

2. 启动成功提示

启动 WebSocket 客户端...
群组数据加载完成
成功连接到 WebSocket 服务器: ws://124.223.95.144:5555/ws
已向服务器注册robotid: wxid_cnw193tl86kx22
连接确认: Connection established

3. 消息处理流程

当群内有人发送消息时:

用户消息示例:
"77123456789 拦截"

系统处理流程:
1. 消息去重检查(重复消息直接丢弃)
2. 检测到关键词"拦截"
3. 提取快递单号:773456789012
4. 识别为申通快递(以77开头)
5. 把「回复 + 转发」作为一个批次放进发送队列
6. 队列串行发出:先回复"@用户 已加急联系快递处理了!",再转发到申通售后群
7. 记录数据到Excel:record/{来源群}/{日期}拦截.xlsx

4. 支持的消息格式

单条消息
77123456789 拦截
773456789012 快递拦截
多条消息(空格分隔)
77123456789 73987654321 拦截
多条消息(逗号分隔)
77123456789,73987654321 拦截
多条消息(换行分隔)
77123456789
73987654321
拦截
改地址消息(只处理第一个单号)
77123456789 改地址:广东省深圳市南山区科技园XXX

5. 停止程序

# 按 Ctrl+C 停止
客户端已手动停止。

6. 截单提醒使用说明

截单提醒功能会在每天的指定时间点前自动向配置的客户群发送提醒消息。

工作原理

系统会根据 task/task.json 的配置,在每个截单时间点前的指定时间(默认30分钟)自动发送提醒。

示例场景:

假设配置了以下截单时间:

  • 15:00 截单 → 客户群:永新顺为、永瑞药业、秋叶源…
  • 16:00 截单 → 客户群:米炭、牛乐、一慕…
  • 17:00 截单 → 客户群:文具用品仓、复真工厂、本初食品…

系统运行后:

  • 14:30 - 自动向所有15点截单的客户群发送提醒
  • 15:30 - 自动向所有16点截单的客户群发送提醒
  • 16:30 - 自动向所有17点截单的客户群发送提醒
发送消息格式
亲,今日的截单点(15:00)将至,麻烦检查一下系统里是否有未审核的订单,谢谢!

消息中的时间会自动替换为实际的截单时间点。

注意事项
  1. 群名称匹配

    • task.json 中配置的群名称必须与 groupdata/groupdata.json 中的群名称完全一致
    • 建议先让机器人加入所有客户群,系统会自动记录群名称到 groupdata.json
    • 然后从 groupdata.json 复制准确的群名称到 task.json
  2. 时间配置

    • 时间使用24小时制(0-23)
    • 提前提醒时间在 .envADVANCE_REMINDER_MINUTES 中配置
    • 建议提前时间设置在15-60分钟之间
  3. 定时任务启动

    • 截单提醒功能需要系统持续运行才能生效
    • 建议使用进程守护工具(如 supervisor、systemd、pm2)确保程序持续运行
    • 或在服务器上设置为开机自启动
  4. 消息发送接口

    • 截单提醒使用 action/group/sendtaskmess.py 中的 send_message() 函数
    • 如需自定义发送逻辑,可修改该文件
调试和测试

查看已配置的提醒任务:

cat task/task.json

查看群组映射关系:

cat groupdata/groupdata.json

手动测试发送消息:
可以临时修改 .env 中的 ADVANCE_REMINDER_MINUTES 为更小的值进行测试。

目录结构

cloudexpress/
├── main.py                    # 机器人入口:WebSocket 接收 + 组件编排
├── schedule.py                # 消息调度:识别单号、决定转发目标
├── config.py                  # 配置中心:读写 .env/task.json,支持热重载
├── sender.py                  # 全局发送队列:串行发送 + 限速 + 重试
├── record_store.py            # Excel 记录:串行写入 + 读取接口
├── check.py                   # 运单号提取
├── message_dedup.py           # 消息去重
├── cutoff_reminder.py         # 截单提醒调度器
├── addgroupdata.py            # 群组数据写入
├── env_loader.py              # 环境变量加载(旧模块,逐步由 config.py 取代)
├── event_maps.py              # 事件类型映射表(参考用)
├── webui_server.py            # WebUI 启动入口
├── webui/                     # WebUI
│   ├── app.py                 # FastAPI 后端与接口
│   ├── auth.py                # 登录认证:密码哈希、会话、限流
│   ├── templates/
│   │   ├── login.html         # 登录 / 初始化页
│   │   └── index.html         # 管理主界面
│   └── static/                # 样式与脚本
├── action/group/
│   ├── getgroupinfo.py        # 查询群信息(仍在用)
│   ├── sendrefermess.py       # 旧发送接口,已由 sender.py 取代
│   ├── sendtaskmess.py        # 旧发送接口,已由 sender.py 取代
│   ├── input_excel.py         # 旧记录接口,已由 record_store.py 取代
│   └── input_excel_address.py # 旧记录接口,已由 record_store.py 取代
├── expressapi/                # 物流查询接口(邮政改造后已不再调用)
├── groupdata/groupdata.json   # 群名称 -> 群ID 映射(自动生成)
├── task/task.json             # 截单时间点和客户群配置
├── record/{群名}/{日期}{类型}.xlsx   # 处理记录
├── log/
│   ├── mylog/main.log         # 运行日志(自动滚动,5MB×5)
│   └── runtime_status.json    # 运行状态(供 WebUI 读取)
├── test_pipeline.py           # 单号识别、队列顺序与限速测试
├── test_auth.py               # 登录认证测试
├── test_e2e.py                # 端到端流程测试
├── start_bot.bat              # 启动机器人
├── start_webui.bat            # 启动 WebUI
└── stop_all.bat               # 停止所有 Python 进程

标注「旧模块」的文件保留是为了兼容和参考,主流程已不再调用,可以放心忽略。

数据记录说明

Excel记录文件

按来源群分目录,按日期和任务类型分文件:

record/{来源群名}/{YYYY-MM-DD}{任务类型}.xlsx

示例:

  • record/云仓快递售后系统/2026-01-16拦截.xlsx
  • record/云仓快递售后系统/2026-01-16催件.xlsx

Excel表格字段

字段 说明
时间 消息发送时间
来源群 消息来源群名称
发送者ID 发送者微信ID
发送者昵称 发送者微信昵称
快递公司 识别出的快递公司
运单号 快递单号
任务类型 拦截/催件/改地址
原始消息 完整消息内容

一个「运单号 + 任务类型」只记一条。即使某家快递配了多个群、消息转发了多次,
Excel 里也不会重复。

在 WebUI 的「数据记录」页可以直接查看和下载这些文件。旧版格式的历史文件也能正常打开,
表头按文件实际内容显示。

常见问题

1. 连接失败

问题:程序无法连接到WebSocket服务器

解决方案

  • 检查 .env 中的 SERVER_IPSERVER_PORT 配置
  • 确认服务器是否正常运行
  • 检查网络连接和防火墙设置
  • 查看是否有VPN或代理影响

2. 消息未转发

问题:检测到关键词但未转发到快递群

解决方案

  • 检查 .env 中快递公司群名称配置是否正确
  • 确认机器人已加入对应的快递售后群
  • 查看 groupdata/groupdata.json 中是否包含该群组
  • 检查群名称是否与配置完全一致(包括空格、括号等)

3. 快递单号识别错误

问题:无法识别或识别错误的快递单号

解决方案

  • 确认快递单号格式符合规则(见配置说明)
  • 检查是否包含特殊字符或空格
  • 查看日志输出的提取结果
  • 必要时修改 check.py 中的提取逻辑

4. Excel文件被占用

问题:提示Excel文件无法写入

解决方案

  • 关闭正在打开的Excel文件
  • 系统使用了文件锁机制,等待几秒后会自动重试
  • 检查文件权限设置

5. 大量消息时会不会顺序错乱或丢消息

不会。 所有出站消息统一走 sender.py 的串行队列:

  • 顺序保证:一条来源消息的「回复 + 各快递群转发」作为一个批次,
    队列里连续发出,中间不会插入其他消息的内容
  • 全局限速:相邻两次发送间隔 SEND_INTERVAL_SECONDS(默认 1 秒),
    无论同时来多少条消息,对接口的请求速率恒定
  • 失败重试:单条发送失败按 1/2/4 秒退避重试,默认 3 次;
    全部失败会写 ERROR 日志,不会静默丢弃
  • 记录不丢:Excel 写入同样串行化,不再出现并发抢文件锁超时导致记录丢失

在 WebUI「运行状态」页可以看到「发送队列积压」。正常应该接近 0;
如果持续偏高,说明消息量超过了当前限速能承载的速度,可以适当调小
SEND_INTERVAL_SECONDS(但要注意接口自身的限流)。

已通过测试验证:20 条消息同时到达时,40 条出站消息严格成对,无穿插、无丢失。

6. 程序频繁断线重连

问题:日志显示频繁的连接/断开

解决方案

  • 检查网络稳定性
  • 确认服务器端是否正常
  • 调整心跳间隔(默认60秒)
  • 查看服务器端日志

7. 截单提醒未发送

问题:到了提醒时间但没有收到截单提醒消息

解决方案

  • 检查群名称配置

    • 确认 task/task.json 中的群名称与 groupdata/groupdata.json 中完全一致
    • 注意空格、标点符号等细节差异
  • 检查时间配置

    • 确认当前时间已经到达提醒时间(截单时间 - 提前提醒分钟数)
    • 检查 .envADVANCE_REMINDER_MINUTES 配置
    • 确认系统时间与服务器时间一致
  • 检查程序运行状态

    • 确认程序在提醒时间点时正在运行
    • 查看程序日志是否有错误信息
    • 检查定时任务调度器是否正常启动
  • 检查机器人权限

    • 确认机器人已加入所有需要发送提醒的客户群
    • 确认机器人在群内有发送消息的权限
    • 测试手动发送消息到该群是否成功
  • 调试建议

    • 临时将 ADVANCE_REMINDER_MINUTES 改为较小值(如5分钟)进行测试
    • 查看 action/group/sendtaskmess.py 的返回结果
    • 检查API接口是否正常响应

8. 消息重复处理/重复转发 ⭐ 已修复

问题:向群里发送快递单号后,系统转发了多次消息,Excel中也保存了多条相同数据

原因分析

  1. WebSocket服务器重复发送消息(最常见)

    • 网络不稳定导致消息重发
    • 服务器消息确认机制问题
    • 程序重启时接收历史消息
  2. 并发竞态条件(已修复)

    • 两条几乎同时到达的相同消息
    • 在第一条消息添加到去重缓存之前,第二条消息也通过了检查
    • 导致两条消息都被处理
  3. 运行了多个程序实例

    • 不小心启动了多个 main.py 进程
    • 检查方法:tasklist | findstr python(Windows)或 ps aux | grep main.py(Linux)

解决方案:✅ 已彻底修复

系统已集成线程安全的消息去重功能,会自动过滤重复的消息:

2026-01-16 15:00:00 - INFO - [调试] ========== 收到消息 ==========
2026-01-16 15:00:00 - INFO - [调试] 消息ID: 100001
2026-01-16 15:00:00 - INFO - [调试] 时间戳: 1737012345
2026-01-16 15:00:00 - INFO - [调试] 消息指纹: e351e399a8f2b1c4...
2026-01-16 15:00:00 - WARNING - ⚠️ ⚠️ ⚠️  检测到重复消息,跳过处理 ⚠️ ⚠️ ⚠️

去重机制说明

  • 基于消息指纹(FromUserName + Content + MsgType)
  • 不包含时间戳和消息ID(因为服务器重发时这些字段会变化)
  • 线程安全设计:使用互斥锁防止并发竞态条件
  • 自动缓存最近1000条消息
  • 自动清理60秒前的历史记录
  • 对性能影响极小(毫秒级)

技术细节

# message_dedup.py 核心改进
class MessageDeduplicator:
    def __init__(self):
        self._lock = threading.Lock()  # 线程锁

    def is_duplicate(self, message_data):
        with self._lock:  # 原子操作,防止竞态条件
            # 检查 → 添加 → 返回结果(整个过程加锁保护)
            if fingerprint in self.message_cache:
                return True
            self.message_cache[fingerprint] = current_time
            return False

并发测试结果

测试场景:10个线程同时收到相同消息
测试结果:只有1个线程通过去重检查
并发安全性测试: [PASS]
准确性测试: [PASS]

如何验证

  1. 向群里发送测试消息
  2. 观察日志:
    • 第一次消息:[调试] ✓ 新消息,准备处理...
    • 重复消息:⚠️ ⚠️ ⚠️ 检测到重复消息,跳过处理 ⚠️ ⚠️ ⚠️
  3. 检查Excel文件,确认只保存了一条数据
  4. 检查目标群,确认只转发了一次

注意

  • 去重功能在程序运行期间持续有效
  • 程序重启后会清空去重缓存
  • 如果同一消息间隔超过60秒发送,会被视为新消息
  • 如果仍然出现重复,请检查是否运行了多个程序实例

运行监控

日志级别

程序使用Python标准logging模块,默认级别为INFO:

  • INFO - 正常运行信息
  • WARNING - 警告信息
  • ERROR - 错误信息
  • DEBUG - 调试信息(需修改代码启用)

关键日志

# 连接成功
成功连接到 WebSocket 服务器: ws://...

# 心跳
心跳包已发送

# 消息处理
--- 收到新的消息 ---
检测到关键词,开始处理消息...
处理单号: 77123456789
匹配到快递公司: 申通
申通快递拦截数据保存成功!

# 群组新增
[INFO] 新增群组: 测试群 -> 12345@chatroom

# 截单提醒
[INFO] 截单提醒调度器已启动
[INFO] 准备发送15:00截单提醒,目标群:永新顺为
[INFO] 截单提醒发送成功: 永新顺为 -> 亲,今日的截单点(15:00)将至...
[ERROR] 截单提醒发送失败: 客户群A -> 群组未找到

注意事项

1. 安全注意事项

  • 不要将 .env 文件提交到版本控制系统
  • 定期更换TOKEN和密钥
  • 限制服务器访问权限
  • 做好数据备份

2. 性能注意事项

  • 系统使用异步处理,可处理高并发消息
  • 多个快递群转发时有1秒延迟,防止发送过快
  • Excel写入使用文件锁,避免并发冲突
  • 定期清理record目录下的历史记录

3. 使用限制

  • 每个快递单号建议唯一处理,避免重复转发
  • 改地址任务每次只处理第一个快递单号
  • 邮政快递依赖API查询,需要网络稳定

4. 维护建议

  • 定期检查 groupdata/groupdata.json 清理无效群组
  • 定期清理 record/ 目录下的历史Excel文件
  • 监控日志文件大小,必要时进行日志切割
  • 定期更新依赖包版本

5. 扩展建议

添加新的快递公司

改两个地方即可,schedule.py 无需改动:

  1. config.pyEXPRESS_COMPANIES 添加前缀映射,
    并在 COMPANY_LABELS 添加中文名:

    EXPRESS_COMPANIES = {
        ...
        'DB': ('德邦', 'DBL'),   # 单号前缀 -> (公司名, .env 键)
    }
    COMPANY_LABELS = {
        ...
        'DBL': '德邦快递',
    }
    
  2. .env 添加对应的群配置(或直接在 WebUI 里配):

    DBL=['德邦售后群']
    

前缀匹配按长度降序进行,新增短前缀不会影响已有的长前缀判断。

自定义截单提醒功能

如需自定义截单提醒的更多功能:

  1. 修改提醒消息模板

    • 编辑 .env 中的 CUTOFF_REMINDER_MESSAGE
    • 可以使用 {time} 占位符,会被替换为实际截单时间
    • 可以添加更多占位符,需要同步修改发送逻辑
  2. 调整提醒时间

    • 修改 .env 中的 ADVANCE_REMINDER_MINUTES
    • 单位为分钟,建议15-60分钟之间
  3. 添加更多截单时间点

    • 直接在 task/task.json 中添加新的时间点和对应客户群
  4. 实现定时任务调度器

    • 可以使用 APScheduler 库实现定时任务
    • 在主程序中启动定时任务,定期检查是否到达提醒时间
    • 调用 action/group/sendtaskmess.py 中的接口发送消息
  5. 多种提醒方式

    • 除了微信群提醒,还可以添加邮件、短信等提醒方式
    • action/ 目录下创建对应的发送接口

示例代码结构(仅供参考):

from apscheduler.schedulers.asyncio import AsyncIOScheduler
import json
from action.group.sendtaskmess import send_message

async def check_and_send_reminders():
    """检查并发送截单提醒"""
    task_config = json.load(open('task/task.json'))
    # 实现提醒逻辑
    pass

# 在主程序中启动调度器
scheduler = AsyncIOScheduler()
scheduler.add_job(check_and_send_reminders, 'cron', minute='*/5')  # 每5分钟检查一次
scheduler.start()

业务场景说明

本系统主要服务于云仓业务场景,具体流程:

快递问题处理流程

  1. 电商客户在主群发送快递问题(拦截、催件、改地址)
  2. 机器人自动识别并回复客户
  3. 将问题转发到对应快递公司的售后对接群
  4. 快递公司人员在售后群处理问题
  5. 系统记录所有处理数据供后续统计分析

截单提醒流程

  1. 系统根据 task.json 配置的截单时间点,在指定时间前自动触发提醒
  2. 遍历该时间点配置的所有客户群
  3. 向每个客户群发送截单提醒消息
  4. 客户收到提醒后检查系统中的未审核订单
  5. 确保订单在截单时间前完成审核,避免延误发货

技术支持

如遇到问题,请:

  1. 查看程序日志输出
  2. 检查配置文件是否正确
  3. 参考本文档的常见问题部分
  4. 联系系统管理员或开发人员

更新日志

Version 2.1

  • 登录页:物流主题的独立登录界面,替代原来的浏览器弹窗式认证
  • 密码不再明文:PBKDF2-SHA256 加盐哈希存储,旧配置里的明文自动迁移并清空
  • 会话管理:HMAC 签名 Cookie,HttpOnly + SameSite=Strict,有效期可配;
    支持修改密码(改后所有设备强制重新登录)和退出登录
  • 登录限流:连续 5 次错误按 IP 锁定 5 分钟
  • 首次引导:未设密码时自动进入初始化页面,不会出现无密码裸奔
  • 配置体检:运行状态页顶部列出会导致消息被静默跳过的配置问题
    (某家快递未配群、群名查不到群ID、截单客户群缺群ID)
  • 回复如实反映结果:部分单号未能转发时,回复中明确列出单号和原因,
    不再一律回复「已加急处理」

Version 2.0

  • 邮政简化:邮政只保留一个合作网点,不再查询物流信息判断网点,
    与其他快递一致按 9 开头直接转发
  • WebUI 配置界面:FastAPI 实现,浏览器管理全部配置,保存后自动生效;
    可在线查看和下载 Excel 记录;带运行状态面板
  • 发送队列:所有出站消息串行发送,解决高并发下顺序错乱、
    限速失效、失败静默丢弃三个问题
  • 记录不再重复:一家快递配多个群时,转发多次但 Excel 只记一条
  • 前缀匹配修正:改为按长度降序匹配,73/75/76/78 不会再被 3/4 误判
  • 正文解析修正:改用 partition(':'),含冒号的地址不再被截断
  • 日志落盘:运行日志写入 log/mylog/main.log,5MB 自动滚动保留 5 个备份
  • 配置热重载config.py 按文件 mtime 自动重新读取,改配置无需重启
  • 未识别到有效单号时改为回复提示,不再错误承诺"已加急处理"
  • 补充 .gitignore,避免 .env 中的 Token 被提交

Version 1.0

  • 基础消息识别和转发功能
  • 支持7家主流快递公司
  • Excel数据记录功能
  • WebSocket稳定连接
  • 群组自动管理
  • 截单提醒功能(支持多时间点定时提醒)

祝使用愉快!

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐