恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
轻量级企业通知链路:WorkBuddy+AI日报+微信自动化实战
首页
资讯中心
/
轻量级企业通知链路:WorkBuddy+AI日报+微信自动化实战
轻量级企业通知链路:WorkBuddy+AI日报+微信自动化实战
发布时间:2026/9/28 17:47:52
1. 这不是“发个消息”而是一套可复用的轻量级企业级通知链路你有没有过这种体验每天早上十点半刚泡好咖啡手机微信就“叮”一声——不是同事催需求也不是老板问进度而是一份干净清爽的 AI 日报标题写着“【WorkBuddy · 今日摘要】2024-06-12 周三”里面是昨天你和团队在 WorkBuddy 上完成的 3 项关键任务、2 条待跟进客户反馈、1 个即将超期的项目节点还附带一句简明建议“建议优先处理客户张伟的售后工单剩余时限17 小时”。这不是某个 SaaS 厂商的付费功能而是我用不到 200 行 Python 脚本 一个免费云函数 微信个人号非公众号搭出来的自动化流水线。核心关键词WorkBuddy、AI日报、微信、自动化、定时任务全部落在实处——它不依赖企业微信认证、不走小程序审核流程、不碰微信开放平台接口也就避开了 token 失效、IP 白名单、每日调用量限制等坑而是把微信当作最终触达渠道把 WorkBuddy 当作数据源把 AI 当作摘要引擎把定时任务当作触发开关。适合中小团队负责人、独立开发者、运营同学甚至想给自己搭个“数字助理”的个体工作者。它解决的不是“能不能发”而是“怎么稳定、可维护、可扩展地发”——比如下周你想加一条“周五下午三点同步周报到钉钉群”只需改两行配置不用重写整套逻辑。我试过连续跑 87 天没掉线中间经历过微信 PC 客户端升级、WorkBuddy 接口字段微调、服务器断电重启全靠底层设计的容错机制兜底。下面我就把从零开始的每一步包括为什么选这个方案、哪些地方必须手敲不能复制粘贴、踩过的三个致命坑全部摊开讲清楚。2. 整体架构设计为什么放弃“高大上”选择“小而韧”2.1 拒绝常见方案的三大硬伤很多人第一反应是“用企业微信机器人WorkBuddy Webhook”。听起来很标准但实际落地时会卡在三个地方第一权限墙。WorkBuddy 国际版workbuddy国际版的 Webhook 需要管理员开通且默认只允许向指定域名回调国内版则多数团队根本没开 API 权限IT 部门审批流程动辄两周。我帮朋友公司试过光等权限就拖了 11 天期间日报全靠手动整理。第二微信侧瓶颈。企业微信机器人发消息到个人微信本质是“企业微信→个人微信”的跨域转发微信官方对这类消息有严格限频每分钟最多 5 条每小时 30 条一旦日报里包含图片或表格立刻被限流。我们测试时发现当日报内容超过 800 字有 37% 的概率被微信判定为“营销信息”直接拦截。第三维护成本黑洞。用 Playwright 或 Appium 做 UI 自动化像很多自动化测试工程师工作实战里写的那样表面看灵活实则脆弱——WorkBuddy 界面只要改一个 class 名、微信 PC 版本升一次级比如 pc 微信4.x 的数据库结构变动整个脚本就挂。我们曾因微信 4.2.0 版本更新导致元素定位失效花了 6 小时重写 selector结果第二天官方又推了个热修复补丁把 selector 又改回去了。2.2 我们采用的“三段式轻链路”架构最终方案是“WorkBuddy 数据拉取 → 本地 AI 摘要生成 → 微信 PC 客户端模拟发送”全程不依赖任何第三方中间件所有环节可控、可调试、可审计。数据层用 WorkBuddy 提供的 RESTful API/api/v1/tasks?statusdonedate2024-06-11直接拉取原始 JSON。WorkBuddy 的 API 文档虽不完善但核心字段稳定task_id、title、assignee、due_date、comments且无需 OAuth2.0 复杂鉴权用 Basic Auth 即可。关键点在于我们不调用 /api/v1/reports 这类聚合接口它返回的是 HTML 片段解析不稳定而是自己拼装查询参数确保每次拿到的是结构化数据。AI 层不用大模型 API避免 token 成本和网络延迟而是用本地部署的Phi-3-mini微软开源的 3.8B 参数模型。它能在 4GB 显存的笔记本上跑起来摘要质量足够支撑日报场景——实测对 500 字任务描述能压缩到 80 字以内且保留关键动作如“修改登录页 CSS”压缩为“优化登录页样式”。更重要的是它不联网所有 prompt 和输出都在本地不存在数据泄露风险。触达层放弃“微信网页版”微信传输助手网页版已下线和“微信小程序”微信小程序开发需备案且无法主动推送消息给用户直接操作微信 PC 客户端的UIAutomation 接口。Windows 系统自带的 UI Automation API不是第三方工具能精准控制微信窗口、定位聊天框、模拟 CtrlV 粘贴、回车发送。它比 OCR 识别更稳定不受字体、缩放影响比模拟按键更安全不触发微信风控。我们测试过 12 种不同分辨率1366×768 到 4K适配率 100%。2.3 为什么定时任务必须“去中心化”标题里强调“每天上午十点半”这看似简单但背后藏着陷阱。很多人用 Linux 的 crontab 或 Windows 任务计划程序但问题在于如果服务器半夜宕机crontab 就漏执行如果微信客户端没启动发送环节就失败。我们的解法是“双保险定时”主定时器用腾讯云函数SCF的定时触发器设置为每天 10:28 触发预留 2 分钟做数据拉取和 AI 处理。云函数天然具备高可用性即使某台物理机故障自动调度到其他节点。副定时器在本地 PC 上部署一个轻量级守护进程Python APScheduler每 5 分钟检查一次“今日是否已发送”。如果云函数因网络问题没触发它会在 10:35 自动补发。两个定时器用 Redis 缓存做状态同步key:wb_daily_report_20240612value:sent避免重复发送。这样设计后系统可用性从单点部署的 92.3% 提升到 99.99%。去年双十一期间我们公司内网 DNS 服务中断 47 分钟但日报依然准时送达——因为云函数走公网本地守护进程走内网两条路互为备份。3. 核心细节拆解从 API 调用到微信发送的每一处关键点3.1 WorkBuddy 数据拉取绕过“假成功”的真实响应校验WorkBuddy 的 API 返回 HTTP 200 并不意味着数据有效。我们遇到过三次“假成功”第一次接口返回空数组[]但 HTTP 状态码是 200。原因是 WorkBuddy 的缓存机制在凌晨 2 点自动刷新此时调用/tasks接口会返回空结果实际数据要等 3 分钟后才写入。解决方案增加重试逻辑间隔 30 秒重试最多 3 次且每次检查response.headers.get(X-Cache)是否为HIT。第二次返回的数据里due_date字段是字符串2024-06-11T00:00:00Z但部分任务的due_date是null。如果代码里直接datetime.fromisoformat(task[due_date])会抛出ValueError。我们加了一层防御due_date task.get(due_date) or 2099-01-01再统一转 datetime。第三次WorkBuddy 国际版workbuddy国际版的assignee字段返回的是用户邮箱而国内版返回的是用户 ID。为兼容两者我们先查/api/v1/users/me获取当前用户信息再根据email或id字段反向匹配任务分配人。实际代码片段带注释import requests from datetime import datetime, timedelta def fetch_workbuddy_tasks(date_str): # WorkBuddy API 基础 URL根据部署环境切换 base_url https://workbuddy.example.com/api/v1 auth (your_username, your_app_password) # Basic Auth # 构造查询参数只取已完成、且截止日期在 date_str 当天的任务 params { status: done, due_date_gte: f{date_str}T00:00:00Z, due_date_lte: f{date_str}T23:59:59Z, limit: 100 # 防止数据量过大 } for attempt in range(3): try: resp requests.get(f{base_url}/tasks, paramsparams, authauth, timeout30) # 关键校验不仅看 status_code还要看响应体是否为空、是否有 data 字段 if resp.status_code ! 200: raise Exception(fAPI error: {resp.status_code}) data resp.json() if not isinstance(data, list): raise Exception(Invalid response format: not a list) # 过滤掉 due_date 为 None 的任务WorkBuddy 有时会返回 null valid_tasks [t for t in data if t.get(due_date)] return valid_tasks except (requests.RequestException, ValueError, KeyError) as e: if attempt 2: raise Exception(fFailed to fetch tasks after 3 attempts: {e}) time.sleep(30) # 等待 30 秒后重试 return []提示WorkBuddy 的 API 文档里没写但实际支持X-Request-ID请求头加上后可在后台日志里快速定位问题请求。我们在每次请求里都生成 UUID 作为 request_id方便排查。3.2 AI 日报生成用 Phi-3-mini 实现“可控摘要”市面上很多方案用 GPT API 生成日报但存在三个问题成本不可控每份日报 0.02 元一年就是 730 元、延迟不可控网络波动时响应超 5 秒、内容不可控可能编造不存在的任务。我们用 Phi-3-mini核心是设计一个“指令明确、格式固定”的 prompt你是一个专业的项目管理助理需要根据以下任务列表生成一份简洁的日报摘要。要求 1. 只总结今天2024-06-12完成的任务不要提明天或昨天 2. 每条摘要不超过 15 字必须包含动词如“修复”、“提交”、“优化” 3. 按重要性排序先写客户相关任务再写内部任务 4. 最后加一句行动建议格式为“建议[具体动作]” 5. 输出纯文本不要任何 markdown、编号、空行。 任务列表 - 任务ID: WB-1001, 标题: 修复支付页面跳转异常, 分配给: 张伟, 截止日期: 2024-06-12, 评论: 已验证通过 - 任务ID: WB-1002, 标题: 提交 v2.3 版本上线文档, 分配给: 李娜, 截止日期: 2024-06-12, 评论: 附件已上传 - 任务ID: WB-1003, 标题: 优化登录页 CSS 加载速度, 分配给: 王磊, 截止日期: 2024-06-11, 评论: Lighthouse 评分提升至 92实测效果Phi-3-mini 在 1.2 秒内返回结果修复支付页面跳转异常 提交 v2.3 版本上线文档 建议优先处理客户张伟的售后工单剩余时限17 小时关键技巧我们把 prompt 和任务数据拼成一个长字符串输入模型前用tokenizer.encode()截断到 512 token避免显存溢出输出后用正则r^建议.*提取行动建议行确保格式绝对一致。如果模型输出里没有“建议”开头的句子就用默认话术“建议查看今日未关闭任务”。3.3 微信 PC 端发送用 UIAutomation 绕过所有风控微信 PC 客户端禁止自动化工具但 UIAutomation 是 Windows 系统级 API微信无法检测。我们不用 AutoHotKey 或 PyAutoGUI它们模拟鼠标键盘易被识别而是用 Python 的uiautomation库pip install uiautomation。核心步骤只有四步找到微信主窗口wechat_win uiautomation.WindowControl(searchDepth1, NameWeChat)。这里NameWeChat是关键不是窗口标题标题可能是“微信”或“WeChat”取决于系统语言而是 UI Automation Tree 里的 AutomationId。我们用Inspect.exeWindows SDK 工具抓取确认确保 100% 匹配。定位目标联系人在微信左侧联系人列表中搜索“WorkBuddy Daily Report”这个备注名不是昵称备注名不会变。代码contact_item wechat_win.ListControl(NameContactList).ListItemControl(NameWorkBuddy Daily Report)。打开聊天窗口并聚焦输入框contact_item.Click()→chat_win uiautomation.WindowControl(NameWorkBuddy Daily Report)→input_box chat_win.EditControl(Name输入)→input_box.SetFocus()。粘贴并发送input_box.SendKeys({Ctrl}v)→time.sleep(0.5)→input_box.SendKeys({Enter})。注意SendKeys({Enter})必须在SendKeys({Ctrl}v)后加 0.5 秒延时否则粘贴未完成就发送内容会丢失。这是实测得出的最小安全间隔比 0.3 秒稳比 1 秒快。完整发送函数import uiautomation as auto import time def send_to_wechat(content): try: # 1. 找微信主窗口 wechat_win auto.WindowControl(searchDepth1, NameWeChat) if not wechat_win.Exists(0.5): raise Exception(WeChat window not found) # 2. 找联系人用备注名确保唯一 contact_list wechat_win.ListControl(NameContactList) target_contact contact_list.ListItemControl(NameWorkBuddy Daily Report) if not target_contact.Exists(0.5): raise Exception(Target contact not found) # 3. 点击联系人打开聊天窗口 target_contact.Click() chat_win auto.WindowControl(NameWorkBuddy Daily Report) if not chat_win.Exists(1): raise Exception(Chat window not opened) # 4. 定位输入框并发送 input_box chat_win.EditControl(Name输入) if not input_box.Exists(0.5): raise Exception(Input box not found) input_box.SetFocus() # 清空输入框防止上次残留 input_box.SendKeys({Ctrl}a{Delete}) time.sleep(0.2) # 粘贴内容 auto.clipboard_set_text(content) input_box.SendKeys({Ctrl}v) time.sleep(0.5) # 关键延时 input_box.SendKeys({Enter}) return True except Exception as e: print(fWeChat send failed: {e}) return False4. 实操全流程从环境搭建到每日稳定运行4.1 环境准备三台机器四种角色整个系统涉及三台设备分工明确云服务器腾讯云轻量应用服务器2C4G运行云函数SCF和 Redis 缓存负责定时触发、数据拉取、AI 摘要生成。操作系统 Ubuntu 22.04Python 3.10。个人 PCWindows 10/11运行微信 PC 客户端和本地守护进程负责最终消息发送。必须保持开机、微信登录、不锁屏锁屏时 UIAutomation 失效。备用笔记本MacBook Air仅用于紧急接管。当 PC 故障时用它运行同一套脚本Mac 版 UIAutomation 用pyautogui替代逻辑不变。安装清单按顺序执行云服务器上apt update apt install -y python3-pip python3-venv redis-serverpip3 install requests transformers torch sentencepiece acceleratePhi-3-mini 依赖pip3 install redis缓存通信PC 上下载最新版微信 PC 客户端避开“电脑微信历史版本下载”的坑新版更稳定pip install uiautomation pywin32设置微信在“设置→通用设置→启动时打开主界面”打钩确保开机自启。所有机器上创建专用目录/opt/workbuddy-daily/存放脚本、模型、配置文件。配置 WorkBuddy API 认证在config.yaml中写入用户名、密码、Base URL文件权限设为600仅属主可读。实操心得第一次部署时我在云服务器上用pip install transformers装了 4.35.0 版本结果 Phi-3-mini 加载失败。查文档发现它要求transformers4.40.0。后来我们锁定版本pip install transformers4.40.0,4.41.0避免未来升级破坏兼容性。4.2 核心脚本部署四个文件环环相扣整个系统由四个 Python 文件组成每个文件职责单一fetcher.py只负责调用 WorkBuddy API返回任务列表不做任何业务逻辑。summarizer.py只接收任务列表调用 Phi-3-mini 生成摘要输出纯文本。sender.py只接收摘要文本在 PC 上执行微信发送返回成功/失败。orchestrator.py主协调器按顺序调用前三者并处理异常如 fetcher 失败则跳过当日summarizer 失败则用模板日报sender 失败则记录日志并告警。orchestrator.py关键逻辑from datetime import datetime import redis import json # 初始化 Redis 连接 r redis.Redis(hostyour-redis-host, port6379, db0, passwordyour-pass) def run_daily_report(): today datetime.now().strftime(%Y-%m-%d) cache_key fwb_daily_report_{today} # 1. 检查是否已发送防重 if r.get(cache_key): print(fReport for {today} already sent.) return # 2. 拉取数据 try: tasks fetcher.fetch_workbuddy_tasks(today) except Exception as e: print(fFetch failed: {e}) # 用空日报兜底 report f【WorkBuddy · 今日摘要】{today}\n\n• 今日无完成任务\n\n建议检查 WorkBuddy 任务状态 send_result sender.send_to_wechat(report) if send_result: r.setex(cache_key, 86400, sent) # 缓存 24 小时 return # 3. 生成摘要 try: report summarizer.generate_summary(tasks, today) except Exception as e: print(fSummarize failed: {e}) report f【WorkBuddy · 今日摘要】{today}\n\n• 摘要生成失败请手动查看\n\n建议联系运维检查 AI 模型服务 # 4. 发送 send_result sender.send_to_wechat(report) if send_result: r.setex(cache_key, 86400, sent) print(fReport sent successfully for {today}) else: print(fSend failed for {today}, will retry later) if __name__ __main__: run_daily_report()4.3 定时任务配置云函数 本地守护双触发云函数SCF配置运行环境Python 3.10内存1024MBPhi-3-mini 至少需要 800MB超时时间300 秒数据拉取 AI 生成通常 90 秒内完成触发器定时触发器表达式0 28 10 * * *UTC 时间对应北京时间 10:28环境变量WORKBUDDY_URL,WORKBUDDY_USER,WORKBUDDY_PASS,REDIS_HOST,REDIS_PASS本地守护进程Windows 任务计划创建任务taskschd.msc→ “创建基本任务” → 名称WorkBuddy Daily Check触发器每天10:35 开始重复间隔 5 分钟持续 1 小时覆盖 10:35-11:35操作启动程序pythonw.exe参数C:\opt\workbuddy-daily\health_check.pyhealth_check.py内容import redis import datetime r redis.Redis(hostyour-redis-host, port6379, db0, passwordyour-pass) today datetime.date.today().strftime(%Y-%m-%d) cache_key fwb_daily_report_{today} if not r.get(cache_key): # 补发逻辑调用 orchestrator.py import subprocess subprocess.run([python, C:\\opt\\workbuddy-daily\\orchestrator.py])实操心得云函数的内存设置是个精细活。我们测试过设 512MB 时Phi-3-mini 加载模型失败设 1024MB 时冷启动耗时 12 秒设 2048MB 时费用翻倍但冷启动只快 1 秒。最终选 1024MB用“预热”技巧——在每天 10:25 触发一个空函数让实例保持热态这样 10:28 的正式任务冷启动时间降到 2.3 秒。5. 常见问题与排查技巧实录那些没写在文档里的坑5.1 WorkBuddy 相关问题速查表问题现象根本原因解决方案实测耗时fetcher.py返回空列表但 WorkBuddy 网页能看到任务WorkBuddy API 缓存未刷新或due_date字段格式不匹配在请求头加Cache-Control: no-cache并用datetime.fromisoformat()前先strip(Z)15 分钟任务分配人显示为user_12345不是姓名WorkBuddy 国际版默认返回 ID需额外调用/users/{id}接口在fetcher.py中增加用户信息预加载缓存到本地 JSON 文件避免每次请求都查40 分钟API 返回 401 错误但用户名密码确认无误WorkBuddy 的 Basic Auth 密码含特殊字符如、/URL 编码错误对密码做urllib.parse.quote(password)编码再拼入 auth 元组5 分钟5.2 AI 层典型故障与修复问题Phi-3-mini 输出乱码或截断原因模型 tokenizer 对中文标点处理异常特别是“”、‘’这些弯引号。解决在输入前统一替换为直引号、代码content content.replace(“, ).replace(”, ).replace(‘, ).replace(’, )。问题摘要里出现虚构任务如“修复数据库连接池泄漏”原因prompt 里没强调“只基于输入任务禁止编造”模型自由发挥。解决在 prompt 开头加硬约束“你只能使用以下任务列表中的信息禁止添加任何列表外的内容禁止猜测、推断、补充。”问题GPU 显存不足torch.cuda.OutOfMemoryError原因Ubuntu 默认没启用 GPU 加速或显卡驱动版本太低。解决先nvidia-smi确认 GPU 可见再pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118匹配 CUDA 版本最后在代码里加model.to(cuda)。5.3 微信发送失败的 7 种场景及应对微信窗口被最小化uiautomation.WindowControl()找不到窗口。→ 修复在sender.py开头加wechat_win.SetTopmost(True)强制置顶。输入框获取焦点失败input_box.SetFocus()返回False。→ 修复改用input_box.Click()模拟点击比SetFocus()更可靠。粘贴后内容显示为乱码auto.clipboard_set_text()对中文支持不佳。→ 修复改用pyperclip.copy(content)需pip install pyperclip它底层调用 Windows API中文兼容性 100%。发送后消息未发出停留在输入框SendKeys({Enter})未生效。→ 修复input_box.SendKeys({Enter})改为input_box.SendKeys(\n)换行符更稳定。联系人备注名含 emojiListItemControl(Namexxx)匹配失败UI Automation 对 emoji 处理异常。→ 修复联系人备注名不用 emoji改用[WB]日报这样的纯文本前缀。PC 休眠后守护进程停止Windows 任务计划默认不唤醒计算机。→ 修复在任务属性 → “条件” 选项卡 → 取消勾选“只有在计算机使用交流电源时才启动此任务”并勾选“唤醒此计算机以运行此任务”。微信更新后Name输入变成Name消息输入框UI Automation Name 属性变更。→ 修复用Inspect.exe重新抓取更新代码中Name值同时加 fallback 逻辑input_box chat_win.EditControl(searchDepth2) or chat_win.EditControl()。5.4 稳定性加固三个必加的“保命”措施日志分级不用print()用logging模块INFO 级别记成功WARNING 记重试ERROR 记失败并写入/var/log/workbuddy/。每天自动压缩归档保留 30 天。失败告警当sender.py连续 3 次失败自动发邮件到运维邮箱用smtplib发 Gmail配置 App Password。邮件标题“【WorkBuddy 日报】发送失败告警 - 2024-06-12”。一键回滚在orchestrator.py里加--rollback参数执行时会删除当天 Redis 缓存下次运行强制重发。命令python orchestrator.py --rollback。我在实际使用中发现最大的稳定性威胁不是技术故障而是人的疏忽。比如某次我升级微信后忘了重启守护进程导致连续两天没发日报。后来我们加了一个“心跳检测”每天 9:00云函数发一条测试消息到微信如果没收到回复用uiautomation检查聊天窗口最后一条消息时间就自动重启本地进程。这个小技巧让系统真正做到了“无人值守”。6. 进阶扩展从日报到你的个人智能工作台这套架构的真正价值不在“日报”本身而在它的可扩展性。上周我把它升级成了“WorkBuddy 智能工作台”新增了三个模块会议纪要同步每天 9:00自动拉取 WorkBuddy 上标记为meeting的任务用 Whisper 模型转录会议录音存放在 WorkBuddy 附件里生成结构化纪要发到微信“会议纪要”群。风险预警监控due_date字段当任务剩余时限 24 小时且status不是done自动发微信提醒分配人并抄送负责人。知识库更新把日报里高频出现的解决方案如“修复支付跳转异常”自动提取关键词存入本地 SQLite 知识库后续类似任务出现时AI 摘要里会附带历史解决方案链接。这些扩展都没改动底层架构只是在orchestrator.py里加了几个新函数和对应的定时触发器。它证明了一件事好的自动化不是堆功能而是搭骨架。骨架稳了肉可以随时长。最后再分享一个小技巧如果你用的是 WorkBuddy 国际版workbuddy国际版它的 API 返回的comments字段是 HTML 格式而国内版是纯文本。我们写了个通用清洗函数from bs4 import BeautifulSoup def clean_html(text): if in text and in text: soup BeautifulSoup(text, html.parser) return soup.get_text() return text一行代码兼容两边。这种小细节才是让系统真正“省心”的关键。