参考文档
corpwechatbot: https://github.com/GentleCP/corpwechatbot
官方文档: https://developer.work.weixin.qq.com/document/path/90930
疑似官方源码: https://github.com/sbzhu/weworkapi_python
说明
本文是基于python后端来调用企业微信API向用户微信发送消息的复现过程, 主要解决了以下问题:
- 解决回调配置中出现
openapi回调地址请求不通过
(自建应用 - 接收消息 - 设置API接收) - 设置代理服务器
- 设置可信域名
- 发送消息
- 本文的食用前提:已有企业微信,已初始化一个自建应用
开搞
设置API接收
官方文档提供了基于内网穿透的本地调试工具: 链接
初始化服务器
python
环境1
python -m venv WXWorkAPI
在企业微信后台进入应用管理,选择一个应用,找到接收消息
设置API接收消息的三个选项,如下
参考corpwechatbot-web (github.com),在服务器上运行web.py
1
python3 web.py -p=8000 -t="token" -a="aeskey" -c="corpid"
确认你的web服务成功启动,并能通过公网访问
点击保存,如果正常,会提示API设置成功,记住这些配置信息
这样就完成了url的配置,但是需要注意的是,以后所有的数据都需要从这个设置的端口中出入, 所以需要设置代理服务器, 让所有的数据都经过这里, 但是web.py会自己去使用端口,就会导致直接发送消息时出现端口占用的现象。
大佬的
web.py
中还配置了自动回复,触发关键词为“我帅吗”
设置代理服务器
本文使用的代理服务器是squid
, 可以支持全局代理, 但是此处并不需要, 只需要能够让指定端口实现转发数据来达成自建应用的所有数据都从特定端口出入的目的
安装squid
1
2sudo apt update
sudo apt install squid配置squid
1
2
3
4
5
6
7
8
9
10
11
12sudo nano /etc/squid/squid.conf
#修改监听端口: 默认 Squid 会监听在端口 3128 上,你可以更改这个端口。例如,如果要监听在 123 端口上:
http_port
#允许所有 IP 地址访问: 默认情况下,Squid 只允许本地机器访问。如果你想允许所有 IP 地址访问 Squid 代理,可以取消注释以下行或添加新的行
acl all src 0.0.0.0/0 # Allow all IP addresses
http_access allow all
#如果你只想允许特定的 IP 地址访问,可以这样配置:
acl localnet src 192.168.1.0/24 # Allow local network
http_access allow localnet启动并设置自启
1
2sudo systemctl start squid
sudo systemctl enable squid检查状态
1
systemctl status squid
端口冲突
如果出现端口冲突的时候,停用squid1
sudo systemctl stop squid
设置可信域名
找到对应的路径,输入ip注意不需要端口,只需要ip
发送消息
配置环境
1
2source /to/path/bin/activate
pip install -U corpwechatbot配置测试消息
该推送会直接传至你的个人微信上,你会像收到好友消息一样收到通知信息,你需要先初始化一个AppMsgSender实例对象,如下:1
2
3
4
5
6
7
8
9
10
11
12
13import cptools
from corpwechatbot.app import AppMsgSender
# from corpwehcatbot import AppMsgSender # both will work
app = AppMsgSender(corpid='', # 你的企业id
corpsecret='', # 你的应用凭证密钥
agentid='', # 你的应用id
log_level=cptools.INFO, # 设置日志发送等级,INFO, ERROR, WARNING, CRITICAL,可选
proxies={'http':'http:example.com', 'https':'https:example.com'} # 设置代理,可选
)
# 如果你在本地配置添加了企业微信本地配置文件,也可以直接初始化AppMsgSender,而无需再显式传入密钥参数
# app = AppMsgSender()在v0.3.0之后,你可以创建多个AppMsgSender,以实现通过多个不同的应用的消息发送,这让你可以实现在一个项目中跨用户、跨企业的消息通知,下面是一个例子
1
2
3
4
5
6
7
8app1 = AppMsgSender(corpid='1', # 你的企业id
corpsecret='1', # 你的应用凭证密钥
agentid='1') # 你的应用id
app2 = AppMsgSender(corpid='2', # 你的企业id
corpsecret='2', # 你的应用凭证密钥
agentid='2') # 你的应用id
app1.send_text('App1的消息')
app2.send_text('App2的消息')完成实例创建之后,你可以通过接口实现需要的信息推送,具体包括:
文本消息
最普通的消息,文字内容,最长不超过2048个字节app.send_text(content="如果我是DJ,你会爱我吗?")
图片消息
发送一张图片,可选jpg,png,大小不超过2MB,目前仅支持通过图片路径发送.app.send_img/picture/pythonWXWapi/image(img/picture/pythonWXWapi/image_path=’test.png’) # 图片存储路径
img.png语音消息
发送一条语音,大小不超过2MB,时长不超过60s,必须是.amr格式app.send_voice(voice_path=’test.amr’)
img_1.png视频消息
发送一段视频,大小不超过10MB,必须是.mp4格式app.send_video(video_path=’test.mp4’)
img_2.png普通文件
其他类型的文件,大小不超过20MB(不小于5字节)
app.send_file(file_path='test.txt')
- markdown消息
markdown类型消息,支持markdown语法,目前仅支持企业微信查看,若输入内容以.md结尾,则会尝试读取对应文件内容发送。
app.send_markdown(content=’# 面对困难的秘诀 \n > 加油,奥利给!’)
图文消息
图片+文字描述+跳转链接,目前仅支持企业微信查看1
2
3
4app.send_news(title='性感刘公,在线征婚',
desp='刘公居然要征婚了?这到底是人性的扭曲,还是道德的沦丧?...',
url='https://blog.gentlecp.com',
picurl='https://gitee.com/gentlecp/ImgUrl/raw/master/20210313141425.jpg')mpnews图文消息
该图文消息相比于上一个允许更丰富的表达,接受html语法,更多区别请参考官方文档1
2
3
4
5
6
7app.send_mpnews(title='你好,我是CP',
img/picture/pythonWXWapi/image_path='data/test.png',
content='<a href="https://blog.gentlecp.com">Hello World</a>',
content_source_url='https://blog.gentlecp.com',
author='GentleCP',
digest='这是一段描述',
safe=1)卡片消息
发送一张卡片,带有跳转链接1
2
3
4app.send_card(title='真骚哥出柜',
desp='真骚哥竟然出柜了?对象竟然是他...',
url='https://blog.gentlecp.com',
btntxt='一睹为快')任务卡片消息
任务发片消息实现用户对服务端的消息进行相应的反馈,如接收到通知后,执行相应操作(如重启)在发送应用卡片消息之前,请确保你已做好相应的回调配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16btn = [{
"key": "yes",
"name": "好的",
"color":"red",
"is_bold": True,
},
{
"key": "no",
"name": "wdnmd"
}
]
app.send_taskcard(title="老板的消息",
desp="下个月工资减半",
url="http://127.0.0.1",
btn=btn,
task_id='12323',) # task_id在应用中是唯一的更多参数使用
上面只是简单地列出了每个消息推送接口的使用,对于一般使用已经足够了,如果你还有更细致的要求,例如发送给指定人,消息安全性等,需要配置以下参数:所有应用推送消息有几个共同参数,用于指定发送消息的特性,如下
touser: 要发送的用户,通过列表划分,输入成员ID,默认发送给全体
toparty: 要发送的部门,通过列表划分,输入部门ID,当touser为@all时忽略
totag: 发送给包含指定标签的人,通过列表划分,输入标签ID,当touser为@all时忽略
safe(该参数并非所有接口都支持,使用时请确认): 是否是保密消息,0表示可对外分享,1表示不能分享且内容显示水印,默认为0一个演示程序
1
2
3
4
5
6
7
8
9
10
11from corpwechatbot.app import AppMsgSender
app = AppMsgSender(corpid='', # 你的企业id
corpsecret='', # 你的应用凭证密钥
agentid='') # 你的应用id
app.send_text(content='Hello',
touser=['sb'],
toparty=['1'],
totag=['1'],
safe=1)⚠️注意!在指定toparty参数的时候,请确保你应用的可见范围包括该部门,否则会发送失败!很多失败情况都是应用的可见范围没设置正确导致!!
获取相关用户数据方法
进入企业微信后台->通讯录