孙亮亮
返回 小企业智能化

小企业智能化

小企业经营异常自动告警实战:企业微信机器人把问题主动推到群里

2026年8月30日

看板要人主动看,告警会自己找人,异常处理才不会拖成事故

小企业智能化企业微信机器人自动告警定时任务

小企业经营异常自动告警实战:企业微信机器人把问题主动推到群里

不少小企业已经做了经营看板,图表挺漂亮,但真正出问题时没人第一时间知道——因为看板需要人主动打开。库存卖穿了三天才发现,客户回款逾期两周才想起催,这些不是数据缺失,而是信息没有主动送到该处理的人手上。本文给出一套低成本落地方案:定时跑几条 SQL 判断异常,通过企业微信群机器人推送到对应的业务群,并处理好去重、静默和分级,避免变成没人看的骚扰消息。

先定义什么算异常,再谈技术

这一步比写代码重要。见过太多团队一上手就配告警,最后配出几十条规则,每天推几百条消息,所有人都设了免打扰。判断标准很简单:一条告警推出来,如果没有明确的人需要做明确的动作,这条告警就不该存在。

建议起步只上三类,覆盖大部分小企业的痛点:

阈值类,比如某个 SKU 可用库存低于安全库存,或者某个仓位的库存为零但仍在接单。这类规则明确、误报率低,适合当第一批告警。

时效类,比如订单支付后超过 24 小时未发货,售后工单超过 48 小时无人跟进,采购单预计到货日已过但未入库。时效类是最容易产生实际价值的一类,因为它抓的是"被遗忘的事"。

异动类,比如今日某渠道订单量比过去七天均值下跌超过 50%,或者退款率突然翻倍。异动类阈值需要跑一段时间再调,初期建议阈值宽松些,先建立信任。

每条规则落地时都写清楚四件事:触发条件、检查频率、推送给哪个群、谁负责处理。写不出负责人的规则先不要上线。

用企业微信群机器人做推送通道

企业微信群机器人是小企业最便宜的推送通道,不需要企业认证、不需要开发应用、不占用应用调用额度。在目标群里点右上角,群机器人,添加机器人,就能拿到一个 Webhook 地址,里面带一个 key。

发消息就是一次 POST,支持 text 和 markdown 两种常用格式。markdown 格式可以做颜色标记和加粗,可读性明显更好:

import json, requests

WEBHOOK = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key"

def push_markdown(title, lines, level="warning"):
    color = {"info": "info", "warning": "warning", "critical": "warning"}[level]
    body = "\n".join(f"> {x}" for x in lines)
    content = f"**{title}**\n<font color=\"{color}\">{level.upper()}</font>\n{body}"
    r = requests.post(WEBHOOK, json={"msgtype": "markdown",
                                    "markdown": {"content": content}}, timeout=8)
    return r.json()   # 正常返回 {"errcode":0,"errmsg":"ok"}

两个必须记住的限制:同一个机器人每分钟最多 20 条消息,超了会被限流丢弃;单条消息内容不能超过 4096 字节。所以千万不要写成"每个异常单据推一条",一定要聚合成汇总消息。

写一个能复用的告警脚本

结构上把规则和推送分开,规则只负责返回"有没有异常、异常明细是什么",推送逻辑统一处理。以库存告警为例:

import pymysql

SQL_LOW_STOCK = """
SELECT s.sku_code, s.sku_name, s.qty_available, s.safety_stock
FROM stock s
WHERE s.qty_available < s.safety_stock AND s.is_active = 1
ORDER BY (s.safety_stock - s.qty_available) DESC
LIMIT 15
"""

def rule_low_stock(conn):
    with conn.cursor(pymysql.cursors.DictCursor) as cur:
        cur.execute(SQL_LOW_STOCK)
        rows = cur.fetchall()
    if not rows:
        return None
    lines = [f"{r['sku_code']} {r['sku_name']}:可用 {r['qty_available']}"
             f"/安全 {r['safety_stock']}" for r in rows]
    return {"key": "low_stock", "title": f"库存预警:{len(rows)} 个 SKU 低于安全库存",
            "lines": lines, "level": "warning"}

定时用系统的计划任务跑就够了,不用上调度平台。库存类每小时一次,时效类每天早上九点半一次,异动类每天一次:

30 9 * * *  /opt/venv/bin/python /opt/alert/run.py --rules overdue,anomaly
0  9-18 * * 1-6 /opt/venv/bin/python /opt/alert/run.py --rules low_stock

去重、静默与分级

这是决定告警能不能长期活下去的关键。库存低于安全库存这件事,如果不处理会连续触发几十次,一天推十几条同样的消息,人就麻了。

做法是加一张告警记录表,字段包括规则标识、指纹、首次触发时间、最近推送时间、状态。指纹用规则标识加上受影响对象的排序拼接后取哈希,内容没变就认为是同一条告警。推送前判断:同一指纹在静默期内不再推送,静默期按级别设置,提醒类 12 小时,警告类 4 小时,严重类 1 小时。

分级体现在两个地方:一是消息里的颜色和措辞,二是要不要 @人。真正需要立刻处理的才用 mentioned_mobile_list 点名,其余的只推文字。全都 @所有人等于都不 @。

另外记得补一条"恢复通知"。异常解除时推一句"库存预警已恢复,共 12 个 SKU 补货完成",这条消息看起来没用,但它是让业务同事信任告警系统的关键——否则大家永远不知道问题有没有解决。

落地清单与踩坑

上线前对照检查:Webhook key 放在环境变量或配置文件里,不要硬编码进代码提交到仓库,泄露了任何人都能往你的群里发消息;告警内容不要带客户手机号、身份证等敏感信息,群成员范围往往比你想的大;SQL 一律加 LIMIT,避免某天数据异常时拉出上万行;脚本要有异常兜底,数据库连不上时自己发一条"告警系统异常",否则静默失效比不装更危险;统计口径写进注释,比如"今日"是按业务日还是自然日。

小结

从看板到告警,本质是把"人找数据"变成"数据找人"。技术上并不复杂,一个 Webhook、几条 SQL、一个计划任务就能跑起来。难的是规则收敛和降噪:宁可只上三条高价值告警,也不要上三十条没人看的。先跑通库存和时效这两类,观察两周,再逐步扩展。

本模块其他文章

小企业经营异常自动告警实战:企业微信机器人把问题主动推到群里 · 孙亮亮