云计算百科
云计算领域专业知识百科平台

Python 微信定时提醒机器人怎么做?从 schedule 到防重复的完整实现

需求很简单:每天早上九点,提醒群里的人交日报;每周五下午,提醒自己写周报。写个小脚本,让微信替你当闹钟。

拆开是三件事:定时触发、发消息到微信、别重复发。跟着做,二十分钟跑通。

第一步:先让消息发出去

定时逻辑之前,先把“发消息”跑通。测试阶段统一发文件传输助手,打扰不到任何人:

# WTAPI 微信机器人接口平台 | 文档: https://weiti.apifox.cn
# 本文依赖:
# – 发文本: postText (appId/toWxid/content, toWxid=filehelper 可自测)
# – 发图片: postImage (appId/toWxid/imgUrl, 提醒带图时用)
import requests

BASE_URL = "https://wx.chuapi.com"
HEADERS = {"Content-Type": "application/json", "X-finder-TOKEN": "<your_token>"}

def send_text(app_id, to_wxid, content):
resp = requests.post(f"{BASE_URL}/finder/v2/api/message/postText",
headers=HEADERS, timeout=10,
json={"appId": app_id, "toWxid": to_wxid,
"content": content}).json()
print(f"发送结果: {resp.get('ret')}") # 200 即成功
return resp.get("ret") == 200

if __name__ == "__main__":
send_text("<your_app_id>", "filehelper", "提醒链路测试")

跑一下,文件传输助手收到消息,第一步完成。appId 从哪来:控制台「微信实例」页扫码登录后自动生成,拿不到的话先去看登录那篇。

第二步:加定时

定时用 schedule 库,纯 Python、零配置:

import schedule, time

schedule.every().day.at("09:00").do(send_text,
"<your_app_id>",
"filehelper",
"早安,该交日报了")

while True:
schedule.run_pending()
time.sleep(30) # 半分钟检查一次, 精度足够

为什么不用系统 crontab?新手视角两个理由:一是逻辑和提醒内容都留在代码里,改一处就行;二是脚本拷到 Windows 也能跑,不用学两套定时语法。服务器长期跑再换 systemd,本地先跑通要紧。

第三步:防重复——最容易翻车的地方

重复发送的元凶不是 schedule,是脚本被跑了两个实例:本地跑着一个忘了关,服务器又部署了一个,九点钟用户收到两条一模一样的提醒。

解法很简单:发之前检查“今天发过没有”,状态落在文件里:

import os

STATE_FILE = "last_sent.txt"

def already_sent_today() –> bool:
if not os.path.exists(STATE_FILE):
return False
with open(STATE_FILE) as f:
return f.read().strip() == time.strftime("%Y-%m-%d")

def mark_sent():
with open(STATE_FILE, "w") as f:
f.write(time.strftime("%Y-%m-%d"))

发送前 already_sent_today() 拦一道,发完 mark_sent() 记一笔。多实例问题在单机版里就解决了;将来上多机部署,这个文件换 Redis,思路不变。

完整脚本

import os, time, requests, schedule

BASE_URL = "https://wx.chuapi.com"
HEADERS = {"Content-Type": "application/json", "X-finder-TOKEN": "<your_token>"}
APP_ID = "<your_app_id>"
STATE_FILE = "last_sent.txt"

def send_text(to_wxid, content):
try:
resp = requests.post(f"{BASE_URL}/finder/v2/api/message/postText",
headers=HEADERS, timeout=10,
json={"appId": APP_ID, "toWxid": to_wxid,
"content": content}).json()
print(f"[{time.strftime('%H:%M:%S')}] 发送 {to_wxid}: ret={resp.get('ret')}")
return resp.get("ret") == 200
except requests.RequestException as e:
print(f"网络异常, 稍后重试: {e}")
return False

def remind_job():
if already_sent_today():
print("今天已发过, 跳过")
return
if send_text("filehelper", "早安,该交日报了"):
mark_sent()

schedule.every().day.at("09:00").do(remind_job)

if __name__ == "__main__":
print("提醒机器人启动, 等待定时触发…")
while True:
schedule.run_pending()
time.sleep(30)

跑起来的样子(示例输出):

提醒机器人启动, 等待定时触发…
[09:00:12] 发送 filehelper: ret=200
[09:30:00] 今天已发过, 跳过 <- 重启脚本后也不会重发

我自己卡过的问题

Q:为什么定时时间到了没触发?
A:schedule 的 at() 走的是脚本运行环境的本地时间。我在服务器上设了 09:00,服务器是 UTC,实际到下午五点才触发。先 print(time.localtime()) 确认时区,或者在 at() 里直接写目标时区的时间。

Q:脚本挂了提醒就没了,怎么办?
A:挂了说明没进程守护。Linux 用 systemd(Restart=always),Windows 用任务计划程序拉起。新手阶段至少做到:脚本崩了有日志可查,别静默死掉。

Q:提醒想带张图,可以吗?
A:可以,换成 postImage 接口,参数是 appId、toWxid、imgUrl 三个,imgUrl 传图片的链接地址。参数我在文档里核过一遍,返回里还带图片的宽高和 CDN 信息。提醒里放张今日值日表之类的图,效果比纯文字好。

Q:能发到群里吗?
A:能。toWxid 换成群的 ID(@chatroom 结尾)就行,接口同一个。注意群里提醒别配太密,一天一条是上限感觉,再多就有人嫌吵了。

小结

  • 先用 filehelper 跑通 postText,再接定时
  • schedule 起步够用,注意时区;长期上服务器换 systemd 守护
  • 防重复靠“今天发过没”的状态文件,多实例是重复的头号元凶
  • 网络异常要 catch 且重试,别让一次抖动丢掉当天提醒
  • 群提醒一天一条封顶,提醒机器人的分寸感就是别烦人
  • 接口路径与参数以 WTAPI 文档为准。


    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Python 微信定时提醒机器人怎么做?从 schedule 到防重复的完整实现
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!