背景
笔者近十年的体检,总会报一个小问题:肾结石。经常肾结石的朋友应该知道,这毛病除了做碎石手术,主流的食疗方式就是:多喝水。
于是乎,六年前,笔者写了这么一篇文章——Win7定时任务——提醒自己喝水_如何用cmd写一个定时器,使得每小时提醒喝水-CSDN博客。实现了让自己的电脑提醒自己喝水。
然而这种方式存在一个局限性就是,当我们不用电脑的时候,就看不到提醒了。
为弥补上述缺点,本文要实现的方案是,通过微信实现定时喝水提醒。
注册测试号
没有完成资质认证(需要每年用公司账户给腾讯打钱)的微信公众号,很多功能受限。无法像下图这样开通这么多的接口权限。
于是我们使用测试公众号来完成接下来的演示,注册及登陆的地址为 微信公众平台 (qq.com)
获取账号信息
登录成功后可以拿到appID和appsecret,这个稍后获取令牌需要用到
在用户列表可以拿到我们的微信号,稍后发送消息需要用到
新增消息模板
如下,模板内容: 该喝水了!!!{{name.DATA}}同学
效果示例:
代码实现
代码结构
access_token.py
该文件主要负责获取access_token验证令牌
# encoding: utf-8
import requests
class AccessToken(object):
# 微信公众测试号账号
APPID = "wxb8ba74XXXXXX"
# 微信公众测试号密钥
APPSECRET = "0eb793c688c47b8xxxxxxxxxx"
def __init__(self, app_id=APPID, app_secret=APPSECRET) -> None:
self.app_id = app_id
self.app_secret = app_secret
def get_access_token(self) -> str:
"""
获取 access_token 凭证
:return: access_token
"""
url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={self.app_id}&secret={self.app_secret}"
resp = requests.get(url)
result = resp.json()
if 'access_token' in result:
return result["access_token"]
else:
print(result)
send_message.py
定义发送消息的方法
# encoding: utf-8
import sys
import os
# 获取当前工作目录
current_dir = os.getcwd()
# 将当前工作目录添加到sys.path
sys.path.append(current_dir)
import json
import requests
from access_token import AccessToken
class SendMessage(object):
# 消息接收者(在测试号用户列表里的微信号))
TOUSER = 'oAbc56vNgQVROXXXXXXXX'
# 消息模板id
TEMPLATE_ID = 'HBb3hJOnEKxz0372L2KQmBtxxxxxxx'
# 点击跳转链接(可无)
CLICK_URL = 'https://blog.csdn.net/chenxy02'
def __init__(self, touser=TOUSER, template_id=TEMPLATE_ID, click_url=CLICK_URL) -> None:
"""
构造函数
:param touser: 消息接收者
:param template_id: 消息模板id
:param click_url: 点击跳转链接(可无)
"""
self.access_token = AccessToken().get_access_token()
self.touser = touser
self.template_id = template_id
self.click_url = click_url
def get_send_data(self, json_data) -> object:
"""
获取发送消息data
:param json_data: json数据对应模板
:return: 发送的消息体
"""
return {
"touser": self.touser,
"template_id": self.template_id,
"url": self.click_url,
"topcolor": "#FF0000",
# json数据对应模板
"data": {
"name": {
"value": json_data["name"],
# 字体颜色
"color": "#173177"
},
}
}
def send_message(self, json_data) -> None:
"""
发送消息
:param json_data: json数据
:return:
"""
# 模板消息请求地址
url = f"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={self.access_token}"
data = json.dumps(self.get_send_data(json_data))
resp = requests.post(url, data=data)
result = resp.json()
if result["errcode"] == 0:
print("消息发送成功")
else:
print(result)
main.py
# encoding: utf-8
from send_message import SendMessage
import schedule
import time
def waterRemind():
# 实例SendMessage
sm = SendMessage()
# 获取接口返回数据
json_data = {"name": "小宇"}
# 发送消息
sm.send_message(json_data=json_data)
if __name__ == '__main__':
# 设置定时任务,每小时执行一次
schedule.every().hour.at(":01").do(waterRemind)
# 在每天的8点到22点之间执行定时任务
while True:
current_hour = int(time.strftime("%H"))
if current_hour >= 8 and current_hour <= 22:
schedule.run_pending()
time.sleep(60) # 每隔60秒检查一次是否需要执行定时任务
运行代码
# 前台运行
python main.py
# 后台运行
nohup python main.py &
预期结果——在每天的8点到22点,每小时第一分钟都会接收一条通知消息,如下: