WeRoBot¶
WeRoBot 是一个微信公众号开发框架。
入门¶
Hello World¶
最简单的Hello World, 会给收到的每一条信息回复 Hello World
import werobot
robot = werobot.WeRoBot(token='tokenhere')
@robot.handler
def hello(message):
return 'Hello World!'
# 让服务器监听在 0.0.0.0:80
robot.config['HOST'] = '0.0.0.0'
robot.config['PORT'] = 80
robot.run()
消息处理¶
WeRoBot 会解析微信服务器发来的消息, 并将消息转换成成 Message 或者是 Event 。 Message 表示用户发来的消息,如文本消息、图片消息; Event 则表示用户触发的事件, 如关注事件、扫描二维码事件。 在消息解析、转换完成后, WeRoBot 会将消息转交给 Handler 进行处理,并将 Handler 的返回值返回给微信服务器。
在刚才的 Hello World 中, 我们编写的
@robot.handler
def hello(message):
return 'Hello World!'
就是一个简单的 Handler , @robot.handler 意味着 robot 会将所有接收到的消息( 包括 Message 和 Event ) 都转交给这个 Handler 来处理。 当然, 你也可以编写一些只能处理特定消息的 Handler
# @robot.text 修饰的 Handler 只处理文本消息
@robot.text
def echo(message):
return message.content
# @robot.image 修饰的 Handler 只处理图片消息
@robot.image
def img(message):
return message.img
使用 Session 记录用户状态¶
WeRoBot 提供了 Session 功能, 可以让你方便的记录用户状态。 比如, 这个 Handler 可以判断发消息的用户之前有没有发送过消息
@robot.text
def first(message, session):
if 'first' in session:
return '你之前给我发过消息'
session['first'] = True
return '你之前没给我发过消息'
Session 功能默认开启, 并使用 SQLite 存储 Session 数据。 详情请参考 Session 文档
创建自定义菜单¶
自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能。 werobot.client.Client
封装了微信的部分 API 接口,我们可以使用 werobot.client.Client.create_menu()
来创建自定义菜单。
在使用 Client 之前, 我们需要先提供微信公众平台内的 AppID 和 AppSecret
from werobot import WeRoBot
robot = WeRoBot()
robot.config["APP_ID"] = "你的 AppID"
robot.config["APP_SECRET"] = "你的 AppSecret"
client = robot.client
然后, 我们就可以创建自定义菜单了
client.create_menu({
"button":[{
"type": "click",
"name": "今日歌曲",
"key": "music"
}]
})
注意以上代码只需要运行一次就可以了。在创建完自定义菜单之后, 我们还需要写一个 Handler 来响应菜单的点击操作
@robot.key_click("music")
def music(message):
return '你点击了“今日歌曲”按钮'
消息加解密¶
WeRoBot 支持对消息的加解密,即微信公众号的安全模式。
在开启消息加解密功能之前,请先阅读微信官方的 消息加解密说明
为 WeRoBot 开启消息加密功能,首先需要安装 cryptography
pip install cryptography
之后, 你只需要将开发者 ID(AppID) 和微信公众平台后台设置的 EncodingAESKey 加到 WeRoBot 的 Config 里面就可以了
from werobot import WeRoBot
robot = WeRoBot()
robot.config["APP_ID"] = "Your AppID"
robot.config['ENCODING_AES_KEY'] = 'Your Encoding AES Key'
WeRoBot 之后会自动进行消息的加解密工作。
部署¶
备注
本节所讨论的是将 WeRoBot 作为独立服务运行情况下的部署操作。 如果你希望将 WeRoBot 集成到其他 Web 框架内,请阅读 与其他 Web 框架集成
在独立服务器上部署¶
使用 werobot.run
来启动 WSGI 服务器¶
你可以在 werobot.config
中配置好 WeRoBot 需要监听的地址和端口号, 然后使用 werobot.run
来启动服务器
import werobot
robot = werobot.WeRoBot(token='tokenhere')
@robot.handler
def echo(message):
return 'Hello World!'
robot.config['HOST'] = '0.0.0.0'
robot.config['PORT'] = 80
robot.run()
备注
你需要 root 或管理员权限才能监听 1024 以下的端口。
你可以通过传递 server 参数来手动指定使用的服务器
import werobot
robot = werobot.WeRoBot(token='tokenhere')
@robot.handler
def echo(message):
return 'Hello World!'
robot.config['HOST'] = '0.0.0.0'
robot.config['PORT'] = 80
robot.run(server='gevent')
server 支持以下几种:
cgi
flup
wsgiref
waitress
cherrypy
paste
fapws3
tornado
gae
twisted
diesel
meinheld
gunicorn
eventlet
gevent
rocket
bjoern
auto
当 server 为 auto 时, WeRoBot 会自动依次尝试以下几种服务器:
Waitress
Paste
Twisted
CherryPy
WSGIRef
所以,只要你安装了相应的服务器软件,就可以使用 werobot.run
直接跑在生产环境下。
备注
server 的默认值为 auto
。
注意
WSGIRef 的性能非常差, 仅能用于开发环境。 如果你要在生产环境下部署 WeRoBot , 请确保你在使用其他 server 。
通过 WSGI HTTP Server 运行 WeRoBot¶
werobot.wsgi
暴露了一个 WSGI Application ,你可以使用任何你喜欢的 WSGI HTTP Server 来部署 WeRoBot。
比如, 如果你想用 Gunicorn 来部署
# FileName: robot.py
from werobot import WeRoBot
robot = WeRoBot()
那么你只需要在 Shell 下运行
gunicorn robot:robot.wsgi
就可以了。
使用 Supervisor 管理守护进程¶
请注意, werobot.run
是跑在 非守护进程模式下 的——也就是说,一旦你关闭终端,进程就会自动退出。
我们建议您使用 Supervisor 来管理 WeRoBot 的进程。
配置文件样例:
[program:wechat_robot]
command = python /home/<username>/robot.py
user = <username>
redirect_stderr = true
stdout_logfile = /home/<username>/logs/robot.log
stdout_errfile = /home/<username>/logs/robot_error.log
使用 Nginx 进行反向代理¶
微信服务器只支持80端口的机器人——显然,你的服务器上不会只跑着一个微信机器人。对于这种情况,我们建议您使用 Nginx 来进行反向代理。
配置文件样例:
server {
server_name example.com;
listen 80;
location / {
proxy_pass_header Server;
proxy_redirect off;
proxy_pass http://127.0.0.1:12233;
}
}
备注
在这个例子中, WeRoBot 的端口号为 12233。你应该在微信管理后台中将服务器地址设为 http://example.com
。
在SAE上部署¶
注意
从 Version 1.11.0 开始,WeRoBot 停止测试 SAE 相关部分的代码。
新浪云上的 Python 应用的入口为 index.wsgi:application ,也就是 index.wsgi 这个文件中名为 application 的 callable object。
所以,假设你在 robot.py 中使用了 WeRoBot
# filename: robot.py
import werobot
robot = werobot.WeRoBot(token='tokenhere')
@robot.handler
def echo(message):
return 'Hello World!'
你需要再创建一个 index.wsgi 文件, 里面写
import sae
from robot import robot
application = sae.create_wsgi_app(robot.wsgi)
然后按照 SAE 的要求编写好 config.yaml 文件就可以了。 可以参考 示例仓库
如果你希望使用 SAE 提供的 KVDB 存储 Session 数据, 可以选择 werobot.session.saekvstorage
作为你的 Session Storage.
Handler¶
WeRoBot会将合法的请求发送给 handlers 依次执行。
如果某一个 Handler 返回了非空值, WeRoBot 就会根据这个值创建回复,后面的 handlers 将不会被执行。
你可以通过修饰符或 add_handler()
添加 handler
import werobot
robot = werobot.WeRoBot(token='tokenhere')
# 通过修饰符添加handler
@robot.handler
def echo(message):
return 'Hello World!'
# 通过`add_handler`添加handler
def echo(message):
return 'Hello World!'
robot.add_handler(echo)
类型过滤¶
在大多数情况下, 一个 Handler 并不能处理所有类型的消息。幸运的是, WeRoBot 可以帮你过滤收到的消息。
只想处理被新用户关注的消息?:
import werobot
robot = werobot.WeRoBot(token='tokenhere')
@robot.subscribe
def subscribe(message):
return 'Hello My Friend!'
robot.run()
或者,你的 handler 只能处理文本?
import werobot
robot = werobot.WeRoBot(token='tokenhere')
@robot.text
def echo(message):
return message.content
robot.run()
在 WeRobot 中我们把请求分成了 Message 和 Event 两种类型,针对两种类型的请求分别有不同的 Handler。
修饰符 |
类型 |
---|---|
文本 (Message) |
|
图像 (Message) |
|
位置 (Message) |
|
链接 (Message) |
|
语音 (Message) |
|
未知类型 (Message) |
|
被关注 (Event) |
|
被取消关注 (Event) |
|
自定义菜单事件 (Event) |
|
链接 (Event) |
|
扫描推送 (Event) |
|
扫描弹消息 (Event) |
|
弹出系统拍照发图(Event) |
|
弹出拍照或者相册发图(Event) |
|
弹出微信相册发图器(Event) |
|
弹出地理位置选择器(Event) |
|
已关注扫描二维码(Event) |
|
打开商品主页事件推送(Event) |
|
进入公众号事件推送(Event) |
|
地理位置信息异步推送(Event) |
|
商品审核结果推送(Event) |
|
卡券通过审核 (Event) |
|
卡券未通过审核 (Event) |
|
用户领取卡券 (Event) |
|
用户转赠卡券 (Event) |
|
用户删除卡券 (Event) |
|
卡券被核销 (Event) |
|
微信买单完成 (Event) |
|
用户进入会员卡 (Event) |
|
用户卡券里点击查看公众号进入会话 (Event) |
|
会员卡积分余额发生变动 (Event) |
|
库存警告 (Event) |
|
券点发生变动 (Event) |
|
模板信息推送事件 (Event) |
|
激活卡券 (Event) |
|
上报位置 (Event) |
|
未知类型 (Event) |
额,这个 handler 想处理文本信息和地理位置信息?
import werobot
robot = werobot.WeRoBot(token='tokenhere')
@robot.text
@robot.location
def handler(message):
# Do what you love to do
pass
robot.run()
当然,你也可以用 add_handler()
函数添加handler,就像这样:
import werobot
robot = werobot.WeRoBot(token='tokenhere')
def handler(message):
# Do what you love to do
pass
robot.add_handler(handler, type='text')
robot.add_handler(handler, type='location')
robot.run()
备注
通过 robot.handler
添加的 handler 将收到所有信息;只有在其他 handler 没有给出返回值的情况下, 通过 robot.handler
添加的 handler 才会被调用。
robot.key_click —— 回应自定义菜单¶
key_click()
是对 click()
修饰符的改进。
如果你在自定义菜单中定义了一个 Key 为 abort
的菜单,响应这个菜单的 handler 可以写成这样
@robot.key_click("abort")
def abort():
return "I'm a robot"
当然,如果你不喜欢用 key_click()
,也可以写成这样
@robot.click
def abort(message):
if message.key == "abort":
return "I'm a robot"
两者是等价的。
robot.filter —— 回应有指定文本的消息¶
现在你可以写这样的代码
@robot.filter("a")
def a():
return "正文为 a "
import re
@robot.filter(re.compile(".*?bb.*?"))
def b():
return "正文中含有 bb "
@robot.filter(re.compile(".*?c.*?"), "d")
def c():
return "正文中含有 c 或正文为 d"
@robot.filter(re.compile("(.*)?e(.*)?"), "f")
def d(message, session, match):
if match:
return "正文为 " + match.group(1) + "e" + match.group(2)
return "正文为 f"
这段代码等价于
@robot.text
def a(message):
if message.content == "a":
return "正文为 a "
import re
@robot.text
def b(message):
if re.compile(".*?bb.*?").match(message.content):
return "正文中含有 b "
@robot.text
def c(message):
if re.compile(".*?c.*?").match(message.content) or message.content == "d":
return "正文中含有 c 或正文为 d"
@robot.text
def d(message):
match = re.compile("(.*)?e(.*)?").match(message.content)
if match:
return "正文为 " + match.group(1) + "e" + match.group(2)
if message.content == "f":
return "正文为 f"
如果你想通过修饰符以外的方法添加 filter,可以使用 add_filter()
方法
def say_hello():
return "hello!"
robot.add_filter(func=say_hello, rules=["hello", "hi", re.compile(".*?hello.*?")])
更多内容详见 werobot.robot.BaseRoBot
Session¶
你可以通过 Session 实现用户状态的记录。
一个简单的使用 Session 的 Demo
from werobot import WeRoBot
robot = WeRoBot(token=werobot.utils.generate_token())
@robot.text
def first(message, session):
if 'last' in session:
return
session['last'] = message.content
return message.content
robot.run()
开启/关闭 Session¶
Session 在 WeRoBot 中默认开启, 并使用 werobot.session.sqlitestorage.SQLiteStorage
作为存储后端。 如果想要更换存储后端, 可以修改 Config 中的 SESSION_STORAGE
from werobot import WeRoBot
from werobot.session.filestorage import FileStorage
robot = WeRoBot(token="token")
robot.config['SESSION_STORAGE'] = FileStorage()
如果想要关闭 Session 功能, 只需把 SESSION_STORAGE
设为 False 即可
from werobot import WeRoBot
robot = WeRoBot(token="token")
robot.config['SESSION_STORAGE'] = False
修改 Handler 以使用 Session¶
没有打开 Session 的时候,一个标准的 WeRoBot Handler 应该是这样的
@robot.text
def hello(message):
return "Hello!"
而在打开 Session 之后, 如果你的 handler 不需要使用 Session ,可以保持不变; 如果需要使用 Session ,则这个 Handler 需要修改为接受第二个参数: session
@robot.subscribe_event
def intro(message):
return "Hello!"
@robot.text
def hello(message, session):
count = session.get("count", 0) + 1
session["count"] = count
return "Hello! You have sent %s messages to me" % count
传入的 session
参数是一个标准的 Python 字典。
更多可用的 Session Storage 详见 Session 对象。
WeRoBot.Client
—— 微信 API 操作类¶
有部分接口暂未实现,可自行调用微信接口。
开始开发¶
获取 access token¶
详细请参考 http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html
- Client.grant_token()¶
获取 Access Token。
- 返回
返回的 JSON 数据包
- Client.get_access_token()¶
判断现有的token是否过期。 用户需要多进程或者多机部署可以手动重写这个函数 来自定义token的存储,刷新策略。
- 返回
返回token
备注
Client 的操作都会自动进行 access token 的获取和过期刷新操作,如果有特殊需求(如多进程部署)可重写 get_access_token
。
获取微信服务器IP地址¶
详细请参考 http://mp.weixin.qq.com/wiki/4/41ef0843d6e108cf6b5649480207561c.html
- Client.get_ip_list()¶
获取微信服务器IP地址。
- 返回
返回的 JSON 数据包
自定义菜单¶
自定义菜单创建接口¶
详细请参考 http://mp.weixin.qq.com/wiki/10/0234e39a2025342c17a7d23595c6b40a.html
创建自定义菜单:
client.create_menu({ "button":[ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "type":"click", "name":"歌手简介", "key":"V1001_TODAY_SINGER" }, { "name":"菜单", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://www.soso.com/" }, { "type":"view", "name":"视频", "url":"http://v.qq.com/" }, { "type":"click", "name":"赞一下我们", "key":"V1001_GOOD" } ] } ]})
- 参数
menu_data – Python 字典
- 返回
返回的 JSON 数据包
自定义菜单查询接口¶
详细请参考 http://mp.weixin.qq.com/wiki/5/f287d1a5b78a35a8884326312ac3e4ed.html
查询自定义菜单。
- 返回
返回的 JSON 数据包
自定义菜单删除接口¶
详细请参考 http://mp.weixin.qq.com/wiki/3/de21624f2d0d3dafde085dafaa226743.html
删除自定义菜单。
- 返回
返回的 JSON 数据包
个性化菜单接口¶
详细请参考 http://mp.weixin.qq.com/wiki/0/c48ccd12b69ae023159b4bfaa7c39c20.html
创建个性化菜单:
button = [ { "type":"click", "name":"今日歌曲", "key":"V1001_TODAY_MUSIC" }, { "name":"菜单", "sub_button":[ { "type":"view", "name":"搜索", "url":"http://www.soso.com/" }, { "type":"view", "name":"视频", "url":"http://v.qq.com/" }, { "type":"click", "name":"赞一下我们", "key":"V1001_GOOD" }] }] matchrule = { "group_id":"2", "sex":"1", "country":"中国", "province":"广东", "city":"广州", "client_platform_type":"2", "language":"zh_CN" } client.create_custom_menu(button, matchrule)
- 参数
menu_data – 如上所示的 Python 字典
matchrule – 如上所示的匹配规则
- 返回
返回的 JSON 数据包
删除个性化菜单。
- 参数
menu_id – 菜单的 ID
- 返回
返回的 JSON 数据包
测试个性化菜单匹配结果。
- 参数
user_id – 要测试匹配的用户 ID
- 返回
返回的 JSON 数据包
获取自定义菜单配置接口¶
详细请参考 http://mp.weixin.qq.com/wiki/14/293d0cb8de95e916d1216a33fcb81fd6.html
获取自定义菜单配置接口。
- 返回
返回的 JSON 数据包
消息管理¶
客服接口¶
详细请参考 http://mp.weixin.qq.com/wiki/11/c88c270ae8935291626538f9c64bd123.html 发送卡券接口暂时未支持。可自行实现。
- Client.add_custom_service_account(account, nickname, password)¶
添加客服帐号。
- 参数
account – 客服账号的用户名
nickname – 客服账号的昵称
password – 客服账号的密码
- 返回
返回的 JSON 数据包
- Client.update_custom_service_account(account, nickname, password)¶
修改客服帐号。
- 参数
account – 客服账号的用户名
nickname – 客服账号的昵称
password – 客服账号的密码
- 返回
返回的 JSON 数据包
- Client.delete_custom_service_account(account, nickname, password)¶
删除客服帐号。
- 参数
account – 客服账号的用户名
nickname – 客服账号的昵称
password – 客服账号的密码
- 返回
返回的 JSON 数据包
- Client.upload_custom_service_account_avatar(account, avatar)¶
设置客服帐号的头像。
- 参数
account – 客服账号的用户名
avatar – 头像文件,必须是 jpg 格式
- 返回
返回的 JSON 数据包
- Client.get_custom_service_account_list()¶
获取所有客服账号。
- 返回
返回的 JSON 数据包
- Client.get_online_custom_service_account_list()¶
获取状态为”在线”的客服账号列表。
- 返回
返回的 JSON 数据包
- Client.send_text_message(user_id, content, kf_account=None)¶
发送文本消息。
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
content – 消息正文
kf_account – 发送消息的客服账户,默认值为 None,None 为不指定
- 返回
返回的 JSON 数据包
- Client.send_image_message(user_id, media_id, kf_account=None)¶
发送图片消息。
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
media_id – 图片的媒体ID。 可以通过
upload_media()
上传。kf_account – 发送消息的客服账户,默认值为 None,None 为不指定
- 返回
返回的 JSON 数据包
- Client.send_voice_message(user_id, media_id, kf_account=None)¶
发送语音消息。
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
media_id – 发送的语音的媒体ID。 可以通过
upload_media()
上传。kf_account – 发送消息的客服账户,默认值为 None,None 为不指定
- 返回
返回的 JSON 数据包
- Client.send_video_message(user_id, media_id, title=None, description=None, kf_account=None)¶
发送视频消息。
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
media_id – 发送的视频的媒体ID。 可以通过
upload_media()
上传。title – 视频消息的标题
description – 视频消息的描述
kf_account – 发送消息的客服账户,默认值为 None,None 为不指定
- 返回
返回的 JSON 数据包
- Client.send_music_message(user_id, url, hq_url, thumb_media_id, title=None, description=None, kf_account=None)¶
发送音乐消息。 注意如果你遇到了缩略图不能正常显示的问题, 不要慌张; 目前来看是微信服务器端的问题。 对此我们也无能为力 ( #197 )
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
url – 音乐链接
hq_url – 高品质音乐链接,wifi环境优先使用该链接播放音乐
thumb_media_id – 缩略图的媒体ID。 可以通过
upload_media()
上传。title – 音乐标题
description – 音乐描述
kf_account – 发送消息的客服账户,默认值为 None,None 为不指定
- 返回
返回的 JSON 数据包
- Client.send_article_message(user_id, articles, kf_account=None)¶
发送图文消息:
articles = [ { "title":"Happy Day", "description":"Is Really A Happy Day", "url":"URL", "picurl":"PIC_URL" }, { "title":"Happy Day", "description":"Is Really A Happy Day", "url":"URL", "picurl":"PIC_URL" } ] client.send_acticle_message("user_id", acticles)
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
articles – 一个包含至多8个 article 字典或 Article 对象的数组
kf_account – 发送消息的客服账户,默认值为 None,None 为不指定
- 返回
返回的 JSON 数据包
- Client.send_news_message(user_id, media_id, kf_account=None)¶
发送永久素材中的图文消息。
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
media_id – 媒体文件 ID
kf_account – 发送消息的客服账户,默认值为 None,None 为不指定
- 返回
返回的 JSON 数据包
- Client.send_miniprogrampage_message(user_id, title, appid, pagepath, thumb_media_id, kf_account=None)¶
发送小程序卡片(要求小程序与公众号已关联)
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
title – 小程序卡片的标题
appid – 小程序的 appid,要求小程序的 appid 需要与公众号有关联关系
pagepath – 小程序的页面路径,跟 app.json 对齐,支持参数,比如 pages/index/index?foo=bar
thumb_media_id – 小程序卡片图片的媒体 ID,小程序卡片图片建议大小为 520*416
kf_account – 需要以某个客服帐号来发消息时指定的客服账户
- 返回
返回的 JSON 数据包
群发接口¶
- Client.send_mass_msg(msg_type, content, user_list=None, send_ignore_reprint=False, client_msg_id=None)¶
向指定对象群发信息。
- 参数
msg_type – 群发类型,图文消息为 mpnews,文本消息为 text,语音为 voice,音乐为 music,图片为 image,视频为 video,卡券为 wxcard。
content – 群发内容。
user_list – 发送对象,整型代表用户组,列表代表指定用户,如果为 None 则代表全部发送。
send_ignore_reprint – 图文消息被判定为转载时,是否继续群发。 True 为继续群发(转载),False 为停止群发。 该参数默认为 False。
client_msg_id – 群发时,微信后台将对 24 小时内的群发记录进行检查,如果该 clientmsgid 已经存在一条群发记录,则会拒绝本次群发请求,返回已存在的群发 msgid, 控制再 64 个字符内。
- 返回
返回的 JSON 数据包。
- Client.delete_mass_msg(msg_id, article_idx=0)¶
群发之后,随时可以通过该接口删除群发。
- 参数
msg_id – 发送出去的消息 ID。
article_idx – 要删除的文章在图文消息中的位置,第一篇编号为 1,该字段不填或填 0 会删除全部文章。
- 返回
微信返回的 json 数据。
- Client.send_mass_preview_to_user(msg_type, content, user, user_type='openid')¶
开发者可通过该接口发送消息给指定用户,在手机端查看消息的样式和排版。为了满足第三方平台开发者的需求,在保留对 openID 预览能力的同时,增加了对指定微信号发送预览的能力,但该能力每日调用次数有限制(100 次),请勿滥用。
- 参数
user_type – 预览对象,openid 代表以 openid 发送,wxname 代表以微信号发送。
msg_type – 发送类型,图文消息为 mpnews,文本消息为 text,语音为 voice,音乐为 music,图片为 image,视频为 video,卡券为 wxcard。
content – 预览内容。
user – 预览用户。
- 返回
返回的 json。
- Client.get_mass_msg_status(msg_id)¶
查询群发消息发送状态。
- 参数
msg_id – 群发消息后返回的消息 id。
- 返回
返回的 json。
- Client.get_mass_msg_speed()¶
获取群发速度。
- 返回
返回的 json。
用户管理¶
用户分组管理¶
详细请参考 http://mp.weixin.qq.com/wiki/8/d6d33cf60bce2a2e4fb10a21be9591b8.html
- Client.create_group(name)¶
创建分组。
- 参数
name – 分组名字(30个字符以内)
- 返回
返回的 JSON 数据包
- Client.get_groups()¶
查询所有分组。
- 返回
返回的 JSON 数据包
- Client.get_group_by_id(openid)¶
查询用户所在分组。
- 参数
openid – 用户的OpenID
- 返回
返回的 JSON 数据包
- Client.update_group(group_id, name)¶
修改分组名。
- 参数
group_id – 分组 ID,由微信分配
name – 分组名字(30个字符以内)
- 返回
返回的 JSON 数据包
- Client.move_user(user_id, group_id)¶
移动用户分组。
- 参数
user_id – 用户 ID,即收到的 Message 的 source
group_id – 分组 ID
- 返回
返回的 JSON 数据包
- Client.move_users(user_id_list, group_id)¶
批量移动用户分组。
- 参数
user_id_list – 用户 ID 的列表(长度不能超过50)
group_id – 分组 ID
- 返回
返回的 JSON 数据包
- Client.delete_group(group_id)¶
删除分组。
- 参数
group_id – 要删除的分组的 ID
- 返回
返回的 JSON 数据包
设置备注名¶
详细请参考 http://mp.weixin.qq.com/wiki/16/528098c4a6a87b05120a7665c8db0460.html
- Client.remark_user(user_id, remark)¶
设置备注名。
- 参数
user_id – 设置备注名的用户 ID
remark – 新的备注名,长度必须小于30字符
- 返回
返回的 JSON 数据包
获取用户基本信息¶
详细请参考 http://mp.weixin.qq.com/wiki/1/8a5ce6257f1d3b2afb20f83e72b72ce9.html
- Client.get_user_info(user_id, lang='zh_CN')¶
获取用户基本信息。
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
lang – 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
- 返回
返回的 JSON 数据包
- Client.get_users_info(user_id_list, lang='zh_CN')¶
批量获取用户基本信息。
- 参数
user_id_list – 用户 ID 的列表
lang – 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语
- 返回
返回的 JSON 数据包
账户管理¶
长链接转短链接接口和微信认证事件推送暂未添加,可自行实现。
生成带参数的二维码¶
详细请参考 http://mp.weixin.qq.com/wiki/18/167e7d94df85d8389df6c94a7a8f78ba.html
- Client.create_qrcode(data)¶
创建二维码。
- 参数
data – 你要发送的参数 dict
- 返回
返回的 JSON 数据包
- Client.show_qrcode(ticket)¶
通过ticket换取二维码。
- 参数
ticket – 二维码 ticket 。可以通过
create_qrcode()
获取到- 返回
返回的 Request 对象
获取用户列表¶
详细请参考 http://mp.weixin.qq.com/wiki/12/54773ff6da7b8bdc95b7d2667d84b1d4.html
- Client.get_followers(first_user_id=None)¶
获取关注者列表 详情请参考 http://mp.weixin.qq.com/wiki/index.php?title=获取关注者列表
- 参数
first_user_id – 可选。第一个拉取的OPENID,不填默认从头开始拉取
- 返回
返回的 JSON 数据包
素材管理¶
新增临时素材¶
详细请参考 http://mp.weixin.qq.com/wiki/15/2d353966323806a202cd2deaafe8e557.html
- Client.upload_media(media_type, media_file)¶
上传临时多媒体文件。
- 参数
media_type – 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)
media_file – 要上传的文件,一个 File-object
- 返回
返回的 JSON 数据包
获取临时素材¶
详细请参考 http://mp.weixin.qq.com/wiki/9/677a85e3f3849af35de54bb5516c2521.html
- Client.download_media(media_id)¶
下载临时多媒体文件。
- 参数
media_id – 媒体文件 ID
- 返回
requests 的 Response 实例
新增永久素材¶
详细请参考 http://mp.weixin.qq.com/wiki/10/10ea5a44870f53d79449290dfd43d006.html
- Client.add_news(articles)¶
新增永久图文素材:
articles = [{ "title": TITLE, "thumb_media_id": THUMB_MEDIA_ID, "author": AUTHOR, "digest": DIGEST, "show_cover_pic": SHOW_COVER_PIC(0 / 1), "content": CONTENT, "content_source_url": CONTENT_SOURCE_URL } # 若新增的是多图文素材,则此处应有几段articles结构,最多8段 ] client.add_news(articles)
- 参数
articles – 如示例中的数组
- 返回
返回的 JSON 数据包
- Client.upload_news_picture(file)¶
上传图文消息内的图片。
- 参数
file – 要上传的文件,一个 File-object
- 返回
返回的 JSON 数据包
- Client.upload_permanent_media(media_type, media_file)¶
上传其他类型永久素材。
- 参数
media_type – 媒体文件类型,分别有图片(image)、语音(voice)和缩略图(thumb)
media_file – 要上传的文件,一个 File-object
- 返回
返回的 JSON 数据包
- Client.upload_permanent_video(title, introduction, video)¶
上传永久视频。
- 参数
title – 视频素材的标题
introduction – 视频素材的描述
video – 要上传的视频,一个 File-object
- 返回
requests 的 Response 实例
获取永久素材¶
详细请参考 http://mp.weixin.qq.com/wiki/12/3c12fac7c14cb4d0e0d4fe2fbc87b638.html
- Client.download_permanent_media(media_id)¶
获取永久素材。
- 参数
media_id – 媒体文件 ID
- 返回
requests 的 Response 实例
删除永久素材¶
详细请参考 http://mp.weixin.qq.com/wiki/7/2212203f4e17253b9aef77dc788f5337.html
- Client.delete_permanent_media(media_id)¶
删除永久素材。
- 参数
media_id – 媒体文件 ID
- 返回
返回的 JSON 数据包
上传图文消息素材¶
- Client.upload_news(articles)¶
上传图文消息素材
articles = [{ "thumb_media_id":"qI6_Ze_6PtV7svjolgs-rN6stStuHIjs9_DidOHaj0Q-mwvBelOXCFZiq2OsIU-p", "author":"xxx", "title":"Happy Day", "content_source_url":"www.qq.com", "content":"content", "digest":"digest", "show_cover_pic":1, "need_open_comment":1, "only_fans_can_comment":1 }]
- 参数
articles – 上传的图文消息数据。
- 返回
返回的 JSON 数据包。
修改永久图文素材¶
详细请参考 http://mp.weixin.qq.com/wiki/10/c7bad9a463db20ff8ccefeedeef51f9e.html
- Client.update_news(update_data)¶
修改永久图文素材:
update_data = { "media_id":MEDIA_ID, "index":INDEX, "articles": { "title": TITLE, "thumb_media_id": THUMB_MEDIA_ID, "author": AUTHOR, "digest": DIGEST, "show_cover_pic": SHOW_COVER_PIC(0 / 1), "content": CONTENT, "content_source_url": CONTENT_SOURCE_URL } } client.update_news(update_data)
- 参数
update_data – 更新的数据,要包含 media_id(图文素材的 ID),index(要更新的文章在图文消息中的位置),articles(新的图文素材数据)
- 返回
返回的 JSON 数据包
获取素材总数¶
详细请参考 http://mp.weixin.qq.com/wiki/5/a641fd7b5db7a6a946ebebe2ac166885.html
- Client.get_media_count()¶
获取素材总数。
- 返回
返回的 JSON 数据包
获取素材列表¶
详细请参考 http://mp.weixin.qq.com/wiki/15/8386c11b7bc4cdd1499c572bfe2e95b3.html
- Client.get_media_list(media_type, offset, count)¶
获取素材列表。
- 参数
media_type – 素材的类型,图片(image)、视频(video)、语音 (voice)、图文(news)
offset – 从全部素材的该偏移位置开始返回,0表示从第一个素材返回
count – 返回素材的数量,取值在1到20之间
- 返回
返回的 JSON 数据包
用户标签管理¶
详细请参考 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140837
创建标签¶
- Client.create_tag(tag_name)¶
创建一个新标签
- 参数
tag_name – 标签名
- 返回
返回的 JSON 数据包
获取公众号已创建的标签¶
- Client.get_tags()¶
获取已经存在的标签
- 返回
返回的 JSON 数据包
编辑标签¶
- Client.update_tag(tag_id, tag_name)¶
修改标签
- 参数
tag_id – 标签 ID
tag_name – 新的标签名
- 返回
返回的 JSON 数据包
删除标签¶
- Client.delete_tag(tag_id)¶
删除标签
- 参数
tag_id – 标签 ID
- 返回
返回的 JSON 数据包
获取标签下粉丝列表¶
- Client.get_users_by_tag(tag_id, next_open_id='')¶
获取标签下粉丝列表
- 参数
tag_id – 标签 ID
next_open_id – 第一个拉取用户的 OPENID,默认从头开始拉取
- 返回
返回的 JSON 数据包
批量为用户打标签¶
- Client.tag_users(tag_id, open_id_list)¶
批量为用户打标签
- 参数
tag_id – 标签 ID
open_id_list – 包含一个或多个用户的 OPENID 的列表
- 返回
返回的 JSON 数据包
批量为用户取消标签¶
- Client.untag_users(tag_id, open_id_list)¶
批量为用户取消标签
- 参数
tag_id – 标签 ID
open_id_list – 包含一个或多个用户的 OPENID 的列表
- 返回
返回的 JSON 数据包
获取用户身上的标签列表¶
- Client.get_tags_by_user(open_id)¶
获取用户身上的标签列表
- 参数
open_id – 用户的 OPENID
- 返回
返回的 JSON 数据包
模板消息¶
- Client.send_template_message(user_id, template_id, data, url='', miniprogram=None)¶
发送模板消息 详情请参考 https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html
- 参数
user_id – 用户 ID 。 就是你收到的 Message 的 source
template_id – 模板 ID。
data – 用于渲染模板的数据。
url – 模板消息的可选链接。
miniprogram – 跳小程序所需数据的可选数据。
- 返回
返回的 JSON 数据包
返回码都是什么意思?¶
参考 https://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html
Message¶
Message 公共属性¶
除了 UnknownMessage, 每一种 Message 都包括以下属性:
name |
value |
---|---|
message_id |
消息id,64位整型 |
target |
开发者账号( OpenID ) |
source |
发送方账号( OpenID ) |
time |
信息发送的时间,一个UNIX时间戳。 |
raw |
信息的原始 XML 格式 |
TextMessage¶
TextMessage 的属性:
name |
value |
---|---|
type |
‘text’ |
content |
信息的内容 |
ImageMessage¶
ImageMessage 的属性:
name |
value |
---|---|
type |
‘image’ |
img |
图片网址。你可以从这个网址下到图片 |
LinkMessage¶
name |
value |
---|---|
type |
‘link’ |
title |
消息标题 |
description |
消息描述 |
url |
消息链接 |
LocationMessage¶
LocationMessage 的属性:
name |
value |
---|---|
type |
‘location’ |
location |
一个元组。(纬度, 经度) |
scale |
地图缩放大小 |
label |
地理位置信息 |
VoiceMessage¶
VoiceMessage 的属性:
name |
value |
---|---|
type |
‘voice’ |
media_id |
消息媒体 ID |
format |
声音格式 |
recognition |
语音识别结果 |
VideoMessage¶
VideoMessage 的属性:
name |
value |
---|---|
type |
‘video’ |
media_id |
消息媒体 ID |
thumb_media_id |
视频缩略图媒体 ID |
UnknownMessage¶
UnknownMessage 的属性:
name |
value |
---|---|
type |
‘unknown’ |
raw |
请求的正文部分。标准的XML格式。 |
备注
如果你不为 WeRoBot 贡献代码,你完全可以无视掉 UnknownMessage 。在正常的使用中,WeRoBot应该不会收到 UnknownMessage ——除非 WeRoBot 停止开发。
Event¶
Event 公共属性¶
除了 UnknownEvent, 每一种 Event 都包括以下属性:
name |
value |
---|---|
message_id |
消息id |
target |
开发者账号( OpenID ) |
source |
发送方账号( OpenID ) |
time |
信息发送的时间,一个UNIX时间戳 |
raw |
信息的原始 XML 格式 |
SubscribeEvent¶
SubscribeEvent 的属性:
name |
value |
---|---|
type |
‘subscribe_event’ |
key |
事件 key 值。 当且仅当未关注公众号扫描二维码时存在 |
ticket |
二维码的 ticket。 当且仅当未关注公众号扫描二维码时存在 |
UnSubscribeEvent¶
UnSubscribeEvent 的属性:
name |
value |
---|---|
type |
‘unsubscribe_event’ |
ScanEvent¶
ScanEvent 的属性:
name |
value |
---|---|
type |
‘scan_event’ |
key |
事件KEY值,是一个32位无符号整数,即创建二维码时的二维码 scene_id |
ticket |
二维码的 ticket,可用来换取二维码图片 |
ScanCodePushEvent¶
ScanCodePushEvent 的属性:
name |
value |
---|---|
type |
‘scancode_push_event’ |
scan_type |
扫描类型,一般是qrcode |
scan_result |
扫描结果,即二维码对应的字符串信息 |
ScanCodeWaitMsgEvent¶
ScanCodeWaitMsgEvent 的属性:
name |
value |
---|---|
type |
‘scancode_waitmsg_event’ |
scan_type |
扫描类型,一般是qrcode |
scan_result |
扫描结果,即二维码对应的字符串信息 |
PicSysphotoEvent¶
弹出系统拍照发图的事件推送的 Event。属性:
name |
value |
---|---|
type |
‘pic_sysphoto_event’ |
key |
事件KEY值,由开发者在创建菜单时设定 |
count |
发送的图片数量 |
pic_list |
图片列表,例如 [{‘pic_md5_sum’: ‘123’}] |
PicPhotoOrAlbumEvent¶
弹出拍照或者相册发图的事件推送的 Event。属性:
name |
value |
---|---|
type |
‘pic_photo_or_album_event’ |
key |
事件KEY值,由开发者在创建菜单时设定 |
count |
发送的图片数量 |
pic_list |
图片列表,例如 [{‘pic_md5_sum’: ‘123’}] |
PicWeixinEvent¶
弹出微信相册发图器的事件推送的 Event。属性:
name |
value |
---|---|
type |
‘pic_weixin_event’ |
key |
事件KEY值,由开发者在创建菜单时设定 |
count |
发送的图片数量 |
pic_list |
图片列表,例如 [{‘pic_md5_sum’: ‘123’}] |
LocationSelectEvent¶
弹出地理位置选择器的事件推送的 Event。属性:
name |
value |
---|---|
type |
‘location_select_event’ |
key |
事件KEY值,由开发者在创建菜单时设定 |
location_x |
X坐标信息 |
location_y |
Y坐标信息 |
scale |
精度,可理解为精度或者比例尺、越精细的话 scale 越高 |
label |
地理位置的字符串信息 |
poi_name |
朋友圈POI的名字,可能为 None |
ClickEvent¶
ClickEvent 的属性:
name |
value |
---|---|
type |
‘click_event’ |
key |
事件 key 值。 |
ViewEvent¶
ViewEvent 的属性:
name |
value |
---|---|
type |
‘view_event’ |
key |
事件 key 值。 |
LocationEvent¶
LocationEvent 的属性:
name |
value |
---|---|
type |
‘location_event’ |
latitude |
地理位置纬度 |
longitude |
地理位置经度 |
precision |
地理位置精度 |
TemplateSendJobFinishEvent¶
模版消息发送任务完成后的 Event 通知。 属性:
name |
value |
---|---|
status |
发送是否成功。为 ‘success’ 或失败原因 |
UserScanProductEvent¶
打开商品主页事件推送的 Event。属性:
name |
value |
---|---|
type |
‘user_scan_product_event’ |
key_standard |
商品编码标准。 |
key_str |
商品编码内容。 |
country |
用户在微信内设置的国家。 |
province |
用户在微信内设置的省份。 |
city |
用户在微信内设置的城市。 |
sex |
用户的性别,1为男性,2为女性,0代表未知。 |
scene |
打开商品主页的场景,1为扫码,2为其他打开场景(如会话、收藏或朋友圈)。 |
ext_info |
调用“获取商品二维码接口”时传入的 extinfo,为标识参数。 |
UserScanProductEnterSessionEvent¶
当用户从商品主页进入公众号会话时推送的 Event。属性:
name |
value |
---|---|
type |
‘user_scan_product_enter_session_event’ |
key_standard |
商品编码标准。 |
key_str |
商品编码内容。 |
ext_info |
调用“获取商品二维码接口”时传入的 extinfo,为标识参数。 |
UserScanProductAsyncEvent¶
当用户打开商品主页,微信会将该用户实时的地理位置信息以异步事件的形式推送的 Event。属性:
name |
value |
---|---|
type |
‘user_scan_product_async_event’ |
key_standard |
商品编码标准。 |
key_str |
商品编码内容。 |
ext_info |
调用“获取商品二维码接口”时传入的 extinfo,为标识参数。 |
region_code |
用户的实时地理位置信息(目前只精确到省一级),可在国家统计局网站查到对应明细: http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201504/t20150415_712722.html |
UserScanProductVerifyActionEvent¶
提交审核的商品,完成审核后,微信会将审核结果以事件的形式推送的 Event。属性:
name |
value |
---|---|
type |
‘user_scan_product_verify_action_event’ |
key_standard |
商品编码标准。 |
key_str |
商品编码内容。 |
result |
审核结果。verify_ok表示审核通过,verify_not_pass表示审核未通过。 |
reason_msg |
审核未通过的原因。 |
CardPassCheckEvent¶
生成的卡券通过审核时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘card_pass_check_event’ |
card_id |
卡券 ID。 |
refuse_reason |
审核不通过原因。 |
CardNotPassCheckEvent¶
生成的卡券未通过审核时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘card_not_pass_check_event’ |
card_id |
卡券 ID。 |
refuse_reason |
审核不通过原因。 |
UserGetCardEvent¶
用户在领取卡券时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘user_get_card_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
is_give_by_friend |
是否为转赠领取,1 代表是,0 代表否。 |
friend_user_name |
当 is_give_by_friend 为 1 时填入的字段,表示发起转赠用户的 openid。 |
outer_id |
未知。 |
old_user_card_code |
为保证安全,微信会在转赠发生后变更该卡券的 code 号,该字段表示转赠前的 code。 |
outer_str |
领取场景值,用于领取渠道数据统计。可在生成二维码接口及添加 Addcard 接口中自定义该字段的字符串值。 |
is_restore_member_card |
用户删除会员卡后可重新找回,当用户本次操作为找回时,该值为 1,否则为 0。 |
is_recommend_by_friend |
未知。 |
UserGiftingCardEvent¶
用户在转赠卡券时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘user_gifting_card_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
friend_user_name |
接收卡券用户的openid。 |
is_return_back |
是否转赠退回,0 代表不是,1 代表是。 |
is_chat_room |
是否是群转赠。 |
UserDelCardEvent¶
用户在删除卡券时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘user_del_card_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。自定义 code 及非自定义 code 的卡券被领取后都支持事件推送。 |
UserConsumeCardEvent¶
卡券被核销时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘user_consume_card_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
consume_source |
核销来源。 |
location_name |
门店名称,当前卡券核销的门店名称(只有通过自助核销和买单核销时才会出现该字段)。 |
staff_open_id |
核销该卡券核销员的 openid(只有通过卡券商户助手核销时才会出现)。 |
verify_code |
自助核销时,用户输入的验证码。 |
remark_amount |
自助核销时 ,用户输入的备注金额。 |
outer_str |
开发者发起核销时传入的自定义参数,用于进行核销渠道统计。 |
UserPayFromPayCellEvent¶
用户微信买单完成时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘user_pay_from_pay_cell_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
trans_id |
微信支付交易订单号(只有使用买单功能核销的卡券才会出现)。 |
location_id |
门店 ID,当前卡券核销的门店 ID(只有通过卡券商户助手和买单核销时才会出现)。 |
fee |
实付金额,单位为分。 |
original_fee |
应付金额,单位为分。 |
UserViewCardEvent¶
用户在进入会员卡时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘user_view_card_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
outer_str |
商户自定义二维码渠道参数,用于标识本次扫码打开会员卡来源来自于某个渠道值的二维码。 |
UserEnterSessionFromCardEvent¶
用户在卡券里点击查看公众号进入会话时(需要用户已经关注公众号),微信推送的 Event。属性:
name |
value |
---|---|
type |
‘user_enter_session_from_card_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
UpdateMemberCardEvent¶
用户的会员卡积分余额发生变动时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘update_member_card_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
modify_bonus |
变动的积分值。 |
modify_balance |
变动的余额值。 |
CardSkuRemindEvent¶
当某个card_id的初始库存数大于200且当前库存小于等于100时,用户尝试领券,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘card_sku_remind_event’ |
card_id |
卡券 ID。 |
detail |
报警详细信息。 |
CardPayOrderEvent¶
用户的会员卡积分余额发生变动时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘card_pay_order_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
order_id |
本次推送对应的订单号。 |
status |
本次订单号的状态。 |
create_order_time |
购买券点时,支付二维码的生成时间。 |
pay_finish_time |
购买券点时,实际支付成功的时间。 |
desc |
支付方式,一般为微信支付充值。 |
free_coin_count |
剩余免费券点数量。 |
pay_coin_count |
剩余付费券点数量。 |
refund_free_coin_count |
本次变动的免费券点数量。 |
refund_pay_coin_count |
本次变动的付费券点数量 |
order_type |
所要拉取的订单类型。 |
memo |
系统备注,说明此次变动的缘由,如开通账户奖励、门店奖励、核销奖励以及充值、扣减。 |
receipt_info |
所开发票的详情。 |
SubmitMembercardUserInfoEvent¶
用户通过一键激活的方式提交信息并点击激活或者用户修改会员卡信息时,微信推送的 Event。属性:
name |
value |
---|---|
type |
‘submit_membercard_user_info_event’ |
card_id |
卡券 ID。 |
user_card_code |
code 序列号。 |
UnknownEvent¶
UnknownEvent 的属性:
name |
value |
---|---|
type |
‘unknown_event’ |
raw |
请求的正文部分。标准的XML格式。 |
备注
如果你不为 WeRoBot 贡献代码,你完全可以无视掉 UnknownEvent 。在正常的使用中,WeRoBot应该不会收到 UnknownEvent ——除非 WeRoBot 停止开发。
回复¶
你可以在构建Reply时传入一个合法的 Message 对象来自动生成 source 和 target
reply = TextReply(message=message, content='Hello!')
TextReply¶
TextReply 是简单的文本消息,构造函数的参数如下:
name |
value |
---|---|
content |
信息正文。 |
target |
信息的目标用户。通常是机器人用户。 |
source |
信息的来源用户。通常是发送信息的用户。 |
time |
信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。 |
备注
如果你的handler返回了一个字符串, WeRoBot会自动将其转化为一个文本消息。
ImageReply¶
ImageReply 为回复图片消息,构造函数的参数如下:
name |
value |
---|---|
media_id |
通过素材管理接口上传多媒体文件,得到的id。 |
target |
信息的目标用户。通常是机器人用户。 |
source |
信息的来源用户。通常是发送信息的用户。 |
time |
信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。 |
VoiceReply¶
VoiceReply 为回复语音消息,构造函数的参数如下:
name |
value |
---|---|
media_id |
通过素材管理接口上传多媒体文件,得到的id。 |
target |
信息的目标用户。通常是机器人用户。 |
source |
信息的来源用户。通常是发送信息的用户。 |
time |
信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。 |
VideoReply¶
VideoReply 为回复视频消息,构造函数的参数如下:
name |
value |
---|---|
media_id |
通过素材管理接口上传多媒体文件,得到的id。 |
title |
视频消息的标题。可为空。 |
description |
视频消息的描述。可为空。 |
target |
信息的目标用户。通常是机器人用户。 |
source |
信息的来源用户。通常是发送信息的用户。 |
time |
信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。 |
ArticlesReply¶
ArticlesReply 是图文消息,构造函数的参数如下:
name |
value |
---|---|
content |
信息正文。可为空。 |
target |
信息的目标用户。通常是机器人用户。 |
source |
信息的来源用户。通常是发送信息的用户。 |
time |
信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。 |
你需要给 ArticlesReply 添加 Article 来增加图文。 Article 类位于 werobot.reply.Article 。
Article 的构造函数的参数如下:
name |
value |
---|---|
title |
标题 |
description |
描述 |
img |
图片链接 |
url |
点击图片后跳转链接 |
注意,微信公众平台对图片链接有特殊的要求,详情可以在 消息接口使用指南 里看到。
在构造完一个 Article 后, 你需要通过 ArticlesReply 的 add_article 参数把它添加进去。就像这样:
from werobot.replies import ArticlesReply, Article
reply = ArticlesReply(message=message)
article = Article(
title="WeRoBot",
description="WeRoBot是一个微信机器人框架",
img="https://github.com/apple-touch-icon-144.png",
url="https://github.com/whtsky/WeRoBot"
)
reply.add_article(article)
备注
根据微信公众平台的 最新公告,每个ArticlesReply中 最多添加1个Article 。
- 你也可以让你的 handler 返回一个列表, 里面每一个元素都是一个长度为四的列表,
WeRoBot 会将其自动转为 ArticlesReply 。就像这样:
import werobot robot = werobot.WeRoBot(token='tokenhere') @robot.text def articles(message): return [ [ "title", "description", "img", "url" ], [ "whtsky", "I wrote WeRoBot", "https://secure.gravatar.com/avatar/0024710771815ef9b74881ab21ba4173?s=420", "http://whouz.com/" ] ] robot.run()
MusicReply¶
MusicReply 是音乐消息,构造函数的参数如下:
name |
value |
---|---|
target |
信息的目标用户。通常是机器人用户。 |
source |
信息的来源用户。通常是发送信息的用户。 |
time |
信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。 |
title |
标题 |
description |
描述 |
url |
音乐链接 |
hq_url |
高质量音乐链接,WIFI环境优先使用该链接播放音乐。可为空 3 |
- 你也可以让你的 handler 返回一个长度为三或四的列表, 3
WeRoBot 会将其自动转为 MusicReply 。就像这样:
import werobot robot = werobot.WeRoBot(token='tokenhere') @robot.text def music(message): return [ "title", "description", "music_url", "hq_music_url" ] @robot.text def music2(message): return [ "微信你不懂爱", "龚琳娜最新力作", "http://weixin.com/budongai.mp3", ] robot.run()
TransferCustomerServiceReply¶
将消息转发到多客服,构造函数的参数如下:
name |
value |
---|---|
target |
信息的目标用户。通常是机器人用户。 |
source |
信息的来源用户。通常是发送信息的用户。 |
time |
信息发送的时间,一个UNIX时间戳。默认情况下会使用当前时间。 |
account |
指定会话接入的客服账号,可以没有此参数,没有时会自动分配给可用客服。 |
SuccessReply¶
给微信服务器回复 “success”。 假如服务器无法保证在五秒内处理并回复,需要回复 SuccessReply ,这样微信服务器才不会对此作任何处理,并且不会发起重试。
Config¶
WeRoBot 使用 WeRoBot.Config
类来存储配置信息。 WeRoBot
类实例的 config
属性是一个 werobot.config.Config
实例。
Config
继承自 dict 。因此, 你可以像使用普通 dict 一样使用它
from werobot import WeRoBot
robot = WeRoBot(token='2333')
robot.config.update(
HOST='0.0.0.0',
PORT=80
)
当然, 你也可以先创建一个 Config ,然后在初始化 WeRobot
的时候传入自己的 Config
from werobot.config import Config
config = Config(
TOKEN="token from config!"
)
robot = WeRoBot(config=config, token="token from init")
assert robot.token == "token from config!"
备注
如果你在初始化 WeRoBot
时传入了 config
参数, WeRoBot
会忽略除 logger
外其他所有的初始化参数。 如果你需要对 WeRoBot
进行一些配置操作, 请修改 Config 。
与普通 dict 不同的是, 你可以先把配置文件保存在一个对象或是文件中, 然后在 Config
中导入配置
from werobot import WeRoBot
robot = WeRoBot(token='2333')
class MyConfig(object):
HOST = '0.0.0.0'
PORT = 80
robot.config.from_object(MyConfig)
robot.config.from_pyfile("config.py")
默认配置¶
dict(
TOKEN=None,
SERVER="auto",
HOST="127.0.0.1",
PORT="8888",
SESSION_STORAGE=None,
APP_ID=None,
APP_SECRET=None,
ENCODING_AES_KEY=None
)
与其他 Web 框架集成¶
WeRoBot 可以作为独立服务运行,也可以集成在其他 Web 框架中一同运行。
Django¶
WeRoBot 支持 Django 2.2+。
首先,在一个文件中写好你的微信机器人
# Filename: robot.py
from werobot import WeRoBot
myrobot = WeRoBot(token='token')
@myrobot.handler
def hello(message):
return 'Hello World!'
然后,在你 Django 项目中的 urls.py
中调用 werobot.contrib.django.make_view()
,将 WeRoBot 集成进 Django
from django.conf.urls import patterns, include, url
from werobot.contrib.django import make_view
from robot import myrobot
urlpatterns = patterns('',
url(r'^robot/', make_view(myrobot)),
)
- werobot.contrib.django.make_view(robot)¶
为一个 BaseRoBot 生成 Django view。
- 参数
robot – 一个 BaseRoBot 实例。
- 返回
一个标准的 Django view
Flask¶
首先, 同样在文件中写好你的微信机器人
# Filename: robot.py
from werobot import WeRoBot
myrobot = WeRoBot(token='token')
@myrobot.handler
def hello(message):
return 'Hello World!'
然后, 在 Flask 项目中为 Flask 实例集成 WeRoBot
from flask import Flask
from robot import myrobot
from werobot.contrib.flask import make_view
app = Flask(__name__)
app.add_url_rule(rule='/robot/', # WeRoBot 挂载地址
endpoint='werobot', # Flask 的 endpoint
view_func=make_view(myrobot),
methods=['GET', 'POST'])
- werobot.contrib.flask.make_view(robot)¶
为一个 BaseRoBot 生成 Flask view。
Usage
from werobot import WeRoBot robot = WeRoBot(token='token') @robot.handler def hello(message): return 'Hello World!' from flask import Flask from werobot.contrib.flask import make_view app = Flask(__name__) app.add_url_rule(rule='/robot/', # WeRoBot 的绑定地址 endpoint='werobot', # Flask 的 endpoint view_func=make_view(robot), methods=['GET', 'POST'])
- 参数
robot – 一个 BaseRoBot 实例
- 返回
一个标准的 Flask view
Bottle¶
在你的 Bottle App 中集成 WeRoBot
from werobot import WeRoBot
myrobot = WeRoBot(token='token')
@myrobot.handler
def hello(message):
return 'Hello World!'
from bottle import Bottle
from werobot.contrib.bottle import make_view
app = Bottle()
app.route('/robot', # WeRoBot 挂载地址
['GET', 'POST'],
make_view(myrobot))
- werobot.contrib.bottle.make_view(robot)¶
为一个 BaseRoBot 生成 Bottle view。
Usage
from werobot import WeRoBot robot = WeRoBot(token='token') @robot.handler def hello(message): return 'Hello World!' from bottle import Bottle from werobot.contrib.bottle import make_view app = Bottle() app.route( '/robot', # WeRoBot 挂载地址 ['GET', 'POST'], make_view(robot) )
- 参数
robot – 一个 BaseRoBot 实例
- 返回
一个标准的 Bottle view
Tornado¶
最简单的 Hello World
import tornado.ioloop
import tornado.web
from werobot import WeRoBot
from werobot.contrib.tornado import make_handler
myrobot = WeRoBot(token='token')
@myrobot.handler
def hello(message):
return 'Hello World!'
application = tornado.web.Application([
(r"/robot/", make_handler(myrobot)),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
- werobot.contrib.tornado.make_handler(robot)¶
为一个 BaseRoBot 生成 Tornado Handler。
Usage
import tornado.ioloop import tornado.web from werobot import WeRoBot from tornado_werobot import make_handler robot = WeRoBot(token='token') @robot.handler def hello(message): return 'Hello World!' application = tornado.web.Application([ (r"/", make_handler(robot)), ])
- 参数
robot – 一个 BaseRoBot 实例。
- 返回
一个标准的 Tornado Handler
错误页面¶
WeRoBot
自带了一个错误页面,它将会在 Signature 验证不通过的时候返回错误页面。
定制错误页面¶
如果你想为 WeRoBot
指定 Signature 验证不通过时显示的错误页面,可以这么做:
@robot.error_page
def make_error_page(url):
return "<h1>喵喵喵 %s 不是给麻瓜访问的快走开</h1>" % url
小工具¶
Token 生成器¶
WeRoBot帮你准备了一个Token生成器:
import werobot.utils
print(werobot.utils.generate_token())
贡献指南¶
有许多种为 WeRoBot 做贡献的方式, 包括但并不仅限于
加入 WeRoBot QQ 群(283206829) 帮助解答问题
把 WeRoBot 安利给你周围的人 :)
贡献代码¶
如果你希望为 WeRoBot 贡献代码, 请现在 GitHub 上 Fork WeRoBot 仓库, 然后在 master
分支上开一个新的分支。
如果你的贡献的代码是修复 Bug , 请确认这个 Bug 已经有了对应的 Issue (如果没有, 请先创建一个); 然后在 Pull Request 的描述里面引用这个 Bug 的 Issue ID , 就像这样(假设 Issue ID 为 153)
Fix #153
环境搭建¶
建议使用 virtualenv
创建虚拟环境进行开发, 然后安装开发环境需要的 packages。
关于 Python 版本, 推荐使用 Python 3.6 进行开发。
如果使用的是 3.x 版本
# Python 3.5
python -m venv venv
如果是其他版本
# virtualenv is highly recommended.
virtualenv venv
# Activate virtualenv.
source venv/bin/activate
# Install dev packages.
pip install -r dev-requirements.txt
代码风格¶
我们使用 yapf 进行代码格式化。 在提交代码之前,请格式化一下你的代码
# Install yapf
pip install yapf
# format code
yapf -i -p -r werobot/ tests/ *.py
你也可以 安装 yapf Pre-Commit Hook 来自动进行代码格式化工作。
测试¶
在代码提交之前, 请先运行本地的测试。每次提交之后会有在线的 CI 运行更多版本兼容性的测试, 请密切关注测试结果。
# Run tests locally.
python setup.py test
当然也可以使用 tox 在本地运行多版本的兼容性测试。
# Run multi-version tests locally.
tox
如果你的 Pull Request 添加了新的模块或者功能,请为这些代码添加必要的测试。 所有的测试文件都在 tests 文件夹下。
当一切开发完成之后, 可以发 Pull Request 到 master
分支, 我们会为你的代码做 Review。同时 CI 也会自动运行测试。
备注
我们只会 Merge 通过了测试的代码。
API¶
应用对象¶
- class werobot.robot.BaseRoBot(token=None, logger=None, enable_session=None, session_storage=None, app_id=None, app_secret=None, encoding_aes_key=None, config=None, **kwargs)¶
BaseRoBot 是整个应用的核心对象,负责提供 handler 的维护,消息和事件的处理等核心功能。
- 参数
logger – 用来输出 log 的 logger,如果是
None
,将使用 werobot.loggerconfig – 用来设置的
werobot.config.Config
对象
备注
对于下面的参数推荐使用
Config
进行设置, 并且以下参数均已 deprecated。- 参数
token – 微信公众号设置的 token (deprecated)
enable_session – 是否开启 session (deprecated)
session_storage – 用来储存 session 的对象,如果为
None
, 将使用 werobot.session.sqlitestorage.SQLiteStorage (deprecated)app_id – 微信公众号设置的 app id (deprecated)
app_secret – 微信公众号设置的 app secret (deprecated)
encoding_aes_key – 用来加解密消息的 aes key (deprecated)
- add_filter(func, rules)¶
为 BaseRoBot 添加一个
filter handler
。- 参数
func – 如果 rules 通过,则处理该消息的 handler。
rules – 一个 list,包含要匹配的字符串或者正则表达式。
- 返回
None
- add_handler(func, type='all')¶
为 BaseRoBot 实例添加一个 handler。
- 参数
func – 要作为 handler 的方法。
type – handler 的种类。
- 返回
None
- card_not_pass_check(f)¶
为生成的卡券未通过审核
(card_not_pass_check_event)
事件添加一个 handler 方法的装饰器。
- card_pass_check(f)¶
为生成的卡券通过审核
(card_pass_check_event)
事件添加一个 handler 方法的装饰器。
- card_pay_order(f)¶
为券点发生变动
(card_pay_order_event)
事件添加一个 handler 方法的装饰器。
- card_sku_remind(f)¶
为某个card_id的初始库存数大于200且当前库存小于等于100
(card_sku_remind_event)
事件添加一个 handler 方法的装饰器。
- check_signature(timestamp, nonce, signature)¶
根据时间戳和生成签名的字符串 (nonce) 检查签名。
- 参数
timestamp – 时间戳
nonce – 生成签名的随机字符串
signature – 要检查的签名
- 返回
如果签名合法将返回
True
,不合法将返回False
- click(f)¶
为自定义菜单事件
(click)
事件添加一个 handler 方法的装饰器。
- error_page(f)¶
为 robot 指定 Signature 验证不通过时显示的错误页面。
Usage:
@robot.error_page def make_error_page(url): return "<h1>喵喵喵 %s 不是给麻瓜访问的快走开</h1>" % url
- filter(*args)¶
为文本
(text)
消息添加 handler 的简便方法。使用
@filter("xxx")
,@filter(re.compile("xxx"))
或@filter("xxx", "xxx2")
的形式为特定内容添加 handler。
- get_encrypted_reply(message)¶
对一个指定的 WeRoBot Message ,获取 handlers 处理后得到的 Reply。 如果可能,对该 Reply 进行加密。 返回 Reply Render 后的文本。
- 参数
message – 一个 WeRoBot Message 实例。
- 返回
reply (纯文本)
- get_reply(message)¶
根据 message 的内容获取 Reply 对象。
- 参数
message – 要处理的 message
- 返回
获取的 Reply 对象
- handler(f)¶
为每一条消息或事件添加一个 handler 方法的装饰器。
- image(f)¶
为图像
(image)
消息添加一个 handler 方法的装饰器。
- key_click(key)¶
为自定义菜单
(click)
事件添加 handler 的简便方法。@key_click(‘KEYNAME’) 用来为特定 key 的点击事件添加 handler 方法。
- link(f)¶
为链接
(link)
消息添加一个 handler 方法的装饰器。
- location(f)¶
为位置
(location)
消息添加一个 handler 方法的装饰器。
- location_event(f)¶
为上报位置
(location_event)
事件添加一个 handler 方法的装饰器。
- location_select(f)¶
为弹出地理位置选择器的事件推送
(location_select_event)
事件添加一个 handler 方法的装饰器。
- parse_message(body, timestamp=None, nonce=None, msg_signature=None)¶
解析获取到的 Raw XML ,如果需要的话进行解密,返回 WeRoBot Message。 :param body: 微信服务器发来的请求中的 Body。 :return: WeRoBot Message
- pic_photo_or_album(f)¶
为弹出拍照或者相册发图的事件推送
(pic_photo_or_album_event)
事件添加一个 handler 方法的装饰器。
- pic_sysphoto(f)¶
为弹出系统拍照发图的事件推送
(pic_sysphoto_event)
事件添加一个 handler 方法的装饰器。
- pic_weixin(f)¶
为弹出微信相册发图器的事件推送
(pic_weixin_event)
事件添加一个 handler 方法的装饰器。
- scan(f)¶
为扫描推送
(scan)
事件添加一个 handler 方法的装饰器。
- scancode_push(f)¶
为扫描推送
(scancode_push)
事件添加一个 handler 方法的装饰器。
- scancode_waitmsg(f)¶
为扫描弹消息
(scancode_waitmsg)
事件添加一个 handler 方法的装饰器。
- shortvideo(f)¶
为小视频
(shortvideo)
消息添加一个 handler 方法的装饰器。
- submit_membercard_user_info(f)¶
为用户通过一键激活的方式提交信息并点击激活或者用户修改会员卡信息
(submit_membercard_user_info_event)
事件添加一个 handler 方法的装饰器。
- subscribe(f)¶
为被关注
(subscribe)
事件添加一个 handler 方法的装饰器。
- templatesendjobfinish_event(f)¶
在模版消息发送任务完成后,微信服务器会将是否送达成功作为通知,发送到开发者中心中填写的服务器配置地址中
- text(f)¶
为文本
(text)
消息添加一个 handler 方法的装饰器。
- unknown(f)¶
为未知类型
(unknown)
消息添加一个 handler 方法的装饰器。
- unknown_event(f)¶
为未知类型
(unknown_event)
事件添加一个 handler 方法的装饰器。
- unsubscribe(f)¶
为被取消关注
(unsubscribe)
事件添加一个 handler 方法的装饰器。
- update_member_card(f)¶
为用户的会员卡积分余额发生变动
(update_member_card_event)
事件添加一个 handler 方法的装饰器。
- user_consume_card(f)¶
为卡券被核销
(user_consume_card_event)
事件添加一个 handler 方法的装饰器。
- user_del_card(f)¶
为用户删除卡券
(user_del_card_event)
事件添加一个 handler 方法的装饰器。
- user_enter_session_from_card(f)¶
为用户卡券里点击查看公众号进入会话
(user_enter_session_from_card_event)
事件添加一个 handler 方法的装饰器。
- user_get_card(f)¶
为用户领取卡券
(user_get_card_event)
事件添加一个 handler 方法的装饰器。
- user_gifting_card(f)¶
为用户转赠卡券
(user_gifting_card_event)
事件添加一个 handler 方法的装饰器。
- user_pay_from_pay_cell(f)¶
为微信买单完成
(user_pay_from_pay_cell_event)
事件添加一个 handler 方法的装饰器。
- user_scan_product(f)¶
为打开商品主页事件推送
(user_scan_product_event)
事件添加一个 handler 方法的装饰器。
- user_scan_product_async(f)¶
为地理位置信息异步推送
(user_scan_product_async_event)
事件添加一个 handler 方法的装饰器。
- user_scan_product_enter_session(f)¶
为进入公众号事件推送
(user_scan_product_enter_session_event)
事件添加一个 handler 方法的装饰器。
- user_scan_product_verify_action(f)¶
为商品审核结果推送
(user_scan_product_verify_action_event)
事件添加一个 handler 方法的装饰器。
- user_view_card(f)¶
为用户进入会员卡
(user_view_card_event)
事件添加一个 handler 方法的装饰器。
- video(f)¶
为视频
(video)
消息添加一个 handler 方法的装饰器。
- view(f)¶
为链接
(view)
事件添加一个 handler 方法的装饰器。
- voice(f)¶
为语音
(voice)
消息添加一个 handler 方法的装饰器。
- class werobot.robot.WeRoBot(token=None, logger=None, enable_session=None, session_storage=None, app_id=None, app_secret=None, encoding_aes_key=None, config=None, **kwargs)¶
WeRoBot 是一个继承自 BaseRoBot 的对象,在 BaseRoBot 的基础上使用了 bottle 框架, 提供接收微信服务器发来的请求的功能。
配置对象¶
Session 对象¶
- class werobot.session.sqlitestorage.SQLiteStorage(filename='werobot_session.sqlite3')¶
SQLiteStorge 会把 Session 数据储存在一个 SQLite 数据库文件中
import werobot from werobot.session.sqlitestorage import SQLiteStorage session_storage = SQLiteStorage robot = werobot.WeRoBot(token="token", enable_session=True, session_storage=session_storage)
- 参数
filename – SQLite数据库的文件名, 默认是
werobot_session.sqlite3
- class werobot.session.filestorage.FileStorage(filename: str = 'werobot_session')¶
FileStorage 会把你的 Session 数据以 dbm 形式储存在文件中。
- 参数
filename – 文件名, 默认为
werobot_session
- class werobot.session.mongodbstorage.MongoDBStorage(collection)¶
MongoDBStorage 会把你的 Session 数据储存在一个 MongoDB Collection 中
import pymongo import werobot from werobot.session.mongodbstorage import MongoDBStorage collection = pymongo.MongoClient()["wechat"]["session"] session_storage = MongoDBStorage(collection) robot = werobot.WeRoBot(token="token", enable_session=True, session_storage=session_storage)
你需要安装
pymongo
才能使用 MongoDBStorage 。- 参数
collection – 一个 MongoDB Collection。
- class werobot.session.redisstorage.RedisStorage(redis, prefix='ws_')¶
RedisStorage 会把你的 Session 数据储存在 Redis 中
import redis import werobot from werobot.session.redisstorage import RedisStorage db = redis.Redis() session_storage = RedisStorage(db, prefix="my_prefix_") robot = werobot.WeRoBot(token="token", enable_session=True, session_storage=session_storage)
你需要安装
redis
才能使用 RedisStorage 。- 参数
redis – 一个 Redis Client。
prefix – Reids 中 Session 数据 key 的 prefix 。默认为
ws_
- class werobot.session.saekvstorage.SaeKVDBStorage(prefix='ws_')¶
SaeKVDBStorage 使用SAE 的 KVDB 来保存你的session
import werobot from werobot.session.saekvstorage import SaeKVDBStorage session_storage = SaeKVDBStorage() robot = werobot.WeRoBot(token="token", enable_session=True, session_storage=session_storage)
需要先在后台开启 KVDB 支持
- 参数
prefix – KVDB 中 Session 数据 key 的 prefix 。默认为
ws_
- class werobot.session.mysqlstorage.MySQLStorage(conn)¶
MySQLStorage 会把你的 Session 数据储存在 MySQL 中
import MySQLdb # 使用 mysqlclient import werobot from werobot.session.mysqlstorage import MySQLStorage conn = MySQLdb.connect(user='', db='', passwd='', host='') session_storage = MySQLStorage(conn) robot = werobot.WeRoBot(token="token", enable_session=True, session_storage=session_storage)
或者
import pymysql # 使用 pymysql import werobot from werobot.session.mysqlstorage import MySQLStorage session_storage = MySQLStorage( conn=pymysql.connect( user='喵', password='喵喵', db='werobot', host='127.0.0.1', charset='utf8' )) robot = werobot.WeRoBot(token="token", enable_session=True, session_storage=session_storage)
你需要安装一个 MySQL Client 才能使用 MySQLStorage,比如
pymysql
,mysqlclient
。理论上符合 PEP-249 的库都可以使用, 测试时使用的是
pymysql
。- 参数
conn –
PEP-249 定义的 Connection 对象
- class werobot.session.postgresqlstorage.PostgreSQLStorage(conn)¶
PostgreSQLStorage 会把你的 Session 数据储存在 PostgreSQL 中
import psycopg2 # pip install psycopg2-binary import werobot from werobot.session.postgresqlstorage import PostgreSQLStorage conn = psycopg2.connect(host='127.0.0.1', port='5432', dbname='werobot', user='nya', password='nyanya') session_storage = PostgreSQLStorage(conn) robot = werobot.WeRoBot(token="token", enable_session=True, session_storage=session_storage)
你需要安装一个
PostgreSQL Client
才能使用 PostgreSQLStorage,比如psycopg2
。理论上符合 PEP-249 的库都可以使用, 测试时使用的是
psycopg2
。- 参数
conn –
PEP-249 定义的 Connection 对象
log¶
- werobot.logger.enable_pretty_logging(logger, level='info')¶
按照配置开启 log 的格式化优化。
- 参数
logger – 配置的 logger 对象
level – 要为 logger 设置的等级
Changelog¶
Version 1.13.1¶
更新了部分依赖。
Version 1.13.0¶
停止了对 Django 1.11、Django 2.0 的测试
增加了对 Django 2.2、 Django 3.0、 Django 3.1 的测试
停止了对 Python 3.4、 Python 3.5 的测试
增加了对 Python 3.9 的测试
werobot.client.Client.send_template_message()
添加跳转小程序 ( #604 )
Version 1.12.0¶
增加了对微信模板回调消息的处理
robot.templatesendjobfinish_event
( #544 )
Version 1.11.0¶
Version 1.10.1¶
修复 群发接口 的 docstring 样式。
Version 1.10.0¶
Version 1.9.0¶
Version 1.8.0¶
增加
werobot.session.postgresqlstorage.PostgreSQLStorage
(#383) (#412)修复 imp 在 Python3.4 后被废弃的问题 (#411)
Version 1.7.0¶
为
werobot.client.Client.send_text_message()
,werobot.client.Client.send_image_message()
,werobot.client.Client.send_voice_message()
,werobot.client.Client.send_video_message()
,werobot.client.Client.send_music_message()
,werobot.client.Client.send_article_message()
,werobot.client.Client.send_news_message()
加入kf_account
参数 ( #384 )将
werobot.replies.TransferCustomerServiceReply
的account
改为非必需 ( #363 )
Version 1.6.0¶
增加对发送小程序卡片的支持:
werobot.client.Client.send_miniprogrampage_message()
( #309 by @helloqiu)
Version 1.5.0¶
为正则匹配的 handler 加入匹配后的
Match Object
作为参数(#305)(Author: cxgreat2014)
Version 1.4.1¶
修复
werobot.client.Client.post()
中文文件名的 bug (#292)
Version 1.4.0¶
增加
werobot.messages.events.CardPassCheckEvent
增加
werobot.messages.events.CardNotPassCheckEvent
增加
werobot.messages.events.UserGetCardEvent
增加
werobot.messages.events.UserGiftingCardEvent
增加
werobot.messages.events.UserDelCardEvent
增加
werobot.messages.events.UserConsumeCardEvent
增加
werobot.messages.events.UserPayFromPayCellEvent
增加
werobot.messages.events.UserViewCardEvent
增加
werobot.messages.events.UserEnterSessionFromCardEvent
增加
werobot.messages.events.UpdateMemberCardEvent
增加
werobot.messages.events.CardSkuRemindEvent
增加
werobot.messages.events.CardPayOrderEvent
增加
werobot.messages.events.SubmitMembercardUserInfoEvent
Version 1.3.0¶
增加
werobot.messages.events.UserScanProductEvent
增加
werobot.messages.events.UserScanProductEnterSessionEvent
增加
werobot.messages.events.UserScanProductAsyncEvent
增加
werobot.messages.events.UserScanProductVerifyActionEvent
增加
werobot.messages.events.PicSysphotoEvent
增加
werobot.messages.events.PicPhotoOrAlbumEvent
增加
werobot.messages.events.PicWeixinEvent
增加
werobot.messages.events.LocationSelectEvent
Version 1.2.0¶
增加
werobot.messages.events.ScanCodePushEvent
增加
werobot.messages.events.ScanCodeWaitMsgEvent
werobot.utils.generate_token()
在 Python 3.6+ 下优先使用secrets.choice
来随机生成 token修复
werobot.client.Client.get_media_list()
的调用参数错误 (#208)修复了某些情况下 Client 中文编码不正确的问题 (#250)
Handler 中的 Exception 现在会以 Error level 记录到 logger 中
在文档中增加了独立的 API 部分
添加了
video
和shortvideo
的修饰器增加了对 Django 2.0 的测试
抛弃对 Django < 1.8 、 Django 1.9 、 Django 1.10 的支持
Version 1.1.1¶
修复
werobot.client.Client.create_menu()
文档中的错误在
werobot.client.Client.send_music_message()
的文档中提示了可能的缩略图不显示的问题
Version 1.1.0¶
为
werobot.robot.BaseRoBot
增加client
property允许在初始化
werobot.robot.BaseRoBot
时传入 Config 。注意如果传入了 config , BaseRoBot 会忽略除config
与logger
外的其他所有的参数。deprecate
werobot.robot.BaseRoBot
的enable_session
参数Session Storage 现在是惰性加载的了; 如果希望关闭 Session , 请将 Config 中的
SESSION_STORAGE
设为False
(#189)修复了打包时 error.html 被忽略导致的默认错误页面错误的问题 (#194)
允许使用
reply.time
的方式快速读取 Reply 属性完善 WeRoBot.Client —— 微信 API 操作类 中自定义菜单、消息管理、素材管理、用户管理、账户管理、素材管理部分的 API
修复了直接 GET 访问 Robot 主页返回 500 的问题
Version 1.0.0¶
增加对消息加解密的支持
重写 werobot.messages, 完善对 Event 的支持
将微信消息的 id 属性重命名为 message_id
增加
werobot.reply.SuccessReply
增加
werobot.reply.ImageReply
增加
werobot.reply.VoiceReply
增加
werobot.reply.VideoReply
删除
werobot.reply.create_reply()
为
werobot.reply.WeChatReply
增加process_args
方法为
werobot.robot.BaseRoBot
增加parse_message
方法为
werobot.robot.BaseRoBot
增加get_encrypted_reply
方法删去了 Reply 中过时的 flag
修复
werobot.session.filestorage.FileStorage
在 PyPy 下的兼容性问题将默认的 SessionBackend 切换为
werobot.session.sqlitestorage.SQLiteStorage
将图文消息单个消息的渲染函数放到
werobot.replies.Article
内取消对 Python2.6, Python3.3 的支持
增加与 Django 1.6+, Flask, Bottle, Tornado 集成的支持
替换 inspect.getargspec()
Version 0.6.1¶
Fix wrong URL in
upload_media
Add VideoMessage
Version 0.6.0¶
Add
@werobot.filter
Add support for Weixin Pay (
werobot.pay.WeixinPayClient
)Add
werobot.reply.TransferCustomerServiceReply
Fix FileStorage’s bug
Version 0.5.3¶
Fix: can’t handle request for root path
Version 0.5.2¶
Fix Python 3 support
Version 0.5.1¶
Fix typo
Version 0.5.0¶
Add
werobot.client
Add
werobot.config
Add
werobot.logger
Add
@werobot.key_click
(Thanks @tg123)Support Location Event
Use smart args
Friendly 403 page
Improved server support
Enable session by default.
Drop
werobot.testing.make_text_message
Drop
werobot.testing.make_image_message
Drop
werobot.testing.make_location_message
Drop
werobot.testing.make_voice_message
Drop
werobot.testing.WeTest.send
Rewrite
werobot.message
Rewrite testing case
Version 0.4.1¶
Add VoiceMessage
Add
message.raw
: Raw XML of messageRename
UnknownMessage.content
toUnknownMessage.raw
Fix a bug when signature is invalid.
Ignore session when receive UnknownMessage
Version 0.4.0¶
Add session support
Add logging support
Rename
werobot.test
towerobot.testing
Handlers added by
@robot.handler
will have the lowest priority.
Version 0.3.5¶
Bug fix: Make
BaseRoBot
importable
Version 0.3.4¶
Rename
WeRoBot.app
toWeRoBot.wsgi
Add
BaseRoBot
class. It’s useful for creating extensions.Reorganized documents.
Version 0.3.3¶
Add
host
param in werobot.runUpdate EventMessage
Add LinkMessage
Version 0.3.2¶
Convert all arguments to unicode in Python 2 ( See issue #1 )
Version 0.3.1¶
Add
server
param in werobot.run
Version 0.3.0¶
Add new messages and replies support for WeChat 4.5