利用 Python 给微信发消息?怎么做的?

起因

上周做过一个爬虫爬取课表的,本应该尽快出下半部分的内容的,但是嘛,中间放了个中秋假,就开始鸽了。
其实下半部分内容就是把爬到的课表进行格式化再通知自己而已。
其中我最先考虑的是使用 server 酱的,虽然 server 酱服务很到位,但是我想白嫖啊,因为我的 server 每天推送的次数已经全部安排得明明白白了。
接下来便有了用邮件提醒的想法,这个确实有得搞的,但今天先不说。
在我折腾我的路由后台时发现了里面的自建微信推送功能,便看到了微信开放平台的这个接口
那就开搞,又免费又是推送到微信又不会产生过多的邮件,你就说香不香吧


测试号申请

微信公众平台接口测试帐号申请
找到自己的 appID 和 appsecret
6729E6D4FC19D27C9C5E77892FC40150
扫码自己的测试号二维码并且得到微信号(这个微信号不是真正的微信号,可以理解为微信的 ID)
C5C9757E0FF906A54100E0A45226520F
新增一个模板
CD9FC0A33645D6864C4AD2CC806DAD02
模板内容照着这个写

1
{{title.DATA}} {{content.DATA}}

这样便可得到所需的内容

  • appid
  • appsecret
  • 微信号
  • 模板 ID

请求 token

首先看一下 [微信开放平台](模板消息 | 微信开放文档 (qq.com)) 的文档吧

1
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

请求参数

属性类型默认值必填说明
grant_typestring填写 client_credential
appidstring小程序唯一凭证,即 AppID,可在「微信公众平台 - 设置 - 开发设置」页中获得。(需要已经成为开发者,且帐号没有异常状态)
secretstring小程序唯一凭证密钥,即 AppSecret,获取方式同 appid

返回值

返回的 JSON 数据包

属性类型说明
access_tokenstring获取到的凭证
expires_innumber凭证有效时间,单位:秒。目前是 7200 秒之内的值。
errcodenumber错误码
errmsgstring错误信息

这就是获取一个临时的一次性通行证,我们需要拿着我们的身份信息 appid 和 secret 去给微信后台,微信知道是我就给我一个通行证让我利用这个通行证来进行发出信息

1
2
3
4
5
6
# 获取推送token
def get_token():
result = requests.get(
f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={app_id}&secret={app_secret}")
access_token = json.loads(result.text)
return access_token["access_token"]

推送消息

1
POST https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN

请求参数

参数是否必填说明
touser接收者 openid
template_id模板 ID
url模板跳转链接(海外帐号没有跳转能力)
miniprogram跳小程序所需数据,不需跳小程序可不用传该数据
appid所需跳转到的小程序 appid(该小程序 appid 必须与发模板消息的公众号是绑定关联关系,暂不支持小游戏)
pagepath所需跳转到小程序的具体页面路径,支持带参数,(示例 index?foo=bar),要求该小程序已发布,暂不支持小游戏
data模板数据
color模板内容字体颜色,不填默认为黑色

POST 数据说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
"touser":"OPENID",
"template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY",
"url":"http://weixin.qq.com/download",
"miniprogram":{
"appid":"xiaochengxuappid12345",
"pagepath":"index?foo=bar"
},
"data":{
"first": {
"value":"恭喜你购买成功!",
"color":"#173177"
},
"keyword1":{
"value":"巧克力",
"color":"#173177"
},
"keyword2": {
"value":"39.8元",
"color":"#173177"
},
"keyword3": {
"value":"2014年9月22日",
"color":"#173177"
},
"remark":{
"value":"欢迎再次购买!",
"color":"#173177"
}
}
}
1
2
3
4
5
6
7
8
# 推送消息
def post_message(access_token, title, text):
url = f"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={access_token}"
parameter = {"touser": to_user, "template_id": template_id,
"data": {"title": {"value": title}, "content": {"value": text}}}
json_parameter = json.dumps(parameter)
result = requests.post(url, data=json_parameter)
print(result.text)

这里我们拿着上面请求回来的 token 和我们需要发送的标题和正文,我们便可以发送消息了

7E6E2F128651A0174EE16432AAC03D2E

7E9088695FD3D8031F0C1C73B7A300D5

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import json
import requests

# 这里填写你的APPID
app_id = "APPID"
# 这里填写你的APP_SECRET
app_secret = "APP_SECRET"
# 用户ID
to_user = "用户ID"
# 模板ID
template_id = "模板ID"


# 获取推送token
def get_token():
result = requests.get(
f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={app_id}&secret={app_secret}")
access_token = json.loads(result.text)
return access_token["access_token"]


# 推送消息
def post_message(access_token, title, text):
url = f"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={access_token}"
parameter = {"touser": to_user, "template_id": template_id,
"data": {"title": {"value": title}, "content": {"value": text}}}
json_parameter = json.dumps(parameter)
result = requests.post(url, data=json_parameter)
print(result.text)


if __name__ == '__main__':
token = get_token()
post_message(token, "Python代码推送标题", "Python代码推送正文")