{"id":13435899,"url":"https://github.com/jeffkit/wechat","last_synced_at":"2025-03-18T12:30:33.137Z","repository":{"id":7774015,"uuid":"9143264","full_name":"jeffkit/wechat","owner":"jeffkit","description":"A wechat python SDK","archived":false,"fork":false,"pushed_at":"2024-02-25T10:00:03.000Z","size":101,"stargazers_count":305,"open_issues_count":12,"forks_count":108,"subscribers_count":54,"default_branch":"master","last_synced_at":"2024-10-27T18:59:45.671Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeffkit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-04-01T07:50:10.000Z","updated_at":"2024-05-28T03:36:25.000Z","dependencies_parsed_at":"2024-06-19T04:10:24.137Z","dependency_job_id":"7327b09b-db1c-4557-a3c9-f81a9c903fb2","html_url":"https://github.com/jeffkit/wechat","commit_stats":{"total_commits":66,"total_committers":7,"mean_commits":9.428571428571429,"dds":0.2272727272727273,"last_synced_commit":"95510106605e3870e81d7b2ea08ef7868b01d3bf"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffkit%2Fwechat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffkit%2Fwechat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffkit%2Fwechat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffkit%2Fwechat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffkit","download_url":"https://codeload.github.com/jeffkit/wechat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244222061,"owners_count":20418436,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T03:00:40.517Z","updated_at":"2025-03-18T12:30:33.132Z","avatar_url":"https://github.com/jeffkit.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# 微信公众号Python-SDK\n\n作者: [@jeff_kit](http://twitter.com/jeff_kit)\n\n本SDK支持微信公众号以及企业号的上行消息及OAuth接口。本文档及SDK假设使用者已经具备微信公众号开发的基础知识，及有能力通过微信公众号、企业号的文档来查找相关的接口详情。\n\n\n## 1. 安装\n\n### pip\n\t\n\tpip install wechat\n\n### 源码安装\n\n\tgit clone git@github.com:jeffkit/wechat.git\n\tcd wechat\n\tpython setup.py install\n\t\n\t\n## 2. 用户上行消息处理框架\n\n对于微信用户在公众号内发送的上行消息，本sdk提供了一个微型处理框架，开发者只需继承wechat.official.WxApplication类, 实现各种消息对应的方法，然后把该类与自己熟悉的web框架结合起来使用即可。\n\nWxApplication内部会实现请求的合法性校验以及消息的分发等功能，还对上行消息对行了结构化，开发者把精力放到业务逻辑的编写即可。\n\nWxApplication类核心方法：\n\n### WxApplication.process(params, xml, token=None, app_id=None, aes_key=None)\n\nWxApplication的process函数，接受以下参数：\n\n- params, url参数字典，需要解析自微信回调的url的querystring。格式如：{'nonce': 1232, 'signature': 'xsdfsdfsd'}\n- xml, 微信回调时post的xml内容。\n- token, 公众号的上行token，可选，允许在子类配置。\n- app_id, 公众号应用id，可选，允许在子类配置。\n- aes_key, 公众号加密secret，可选，允许在子类配置。\n\nprocess最后返回一串文本(xml或echoStr)。\n\n\n#### 使用场景1：上行URL有效性验证\n\n在微信公众号的后台设置好URL及token等相关信息后，微信会通过GET的方式访问一次该URL，开发者在URL的响应程序里直接调用app.process(params, xml=None)即可返回echStr。\n\n\tqs = 'nonce=1221\u0026signature=19selKDJF\u0026timestamp=12312'\n\tquery = dict([q.split('=') for q in qs.split('\u0026')])\n\tapp = YourApplication()\n\techo_str = app.process(query, xml=None)\n\t# 返回echo_str给微信即可\n\t\n\n#### 使用场景2：处理上行消息\n\n用户在微信公众号上发消息给公众号，微信服务器调用上行的URL，开发者需要对每次的的请求进行合法性校验及对消息进行处理，同样的，直接调用app.process方法就好。\n\n\tqs = 'nonce=1221\u0026signature=19selKDJF\u0026timestamp=12312'\n\tquery = dict([q.split('=') for q in qs.split('\u0026')])\n\tbody = '\u003cxml\u003e ..... \u003c/xml\u003e'\n\tapp = YourApplication()\n\tresult = app.process(query, xml=body)\n\t# 返回result给微信即可\n\n\n### WxApplication子类示例\n\n下面先看看一个WxApplication的示例代码，用于把用户上行的文本返还给用户：\n\n\tfrom wechat.official import WxApplication, WxTextResponse, WxMusic,\\\n\t\tWxMusicResponse\n\t\n\tclass WxApp(WxApplication):\n\t\n    \tSECRET_TOKEN = 'test_token'\n\t    WECHAT_APPID = 'wx1234556'\n\t    WECHAT_APPSECRET = 'sevcs0j'\n\n    \tdef on_text(self, text):\n        \treturn WxTextResponse(text.Content, text)\n        \n    \t\n需要配置几个类参数，几个参数均可在公众号管理后台的开发者相关页面找到，前三个参数如果不配置，则需要在调用process方法时传入。\n\t\n- SECRET_TOKEN: 微信公众号回调的TOKEN\n- APP_ID: 微信公众号的应用ID\n- ENCODING_AES_KEY: (可选)，加密用的SECRET，如您的公众号未采取加密传输，不需填。\n- UNSUPPORT_TXT:(可选)，收到某种不支持类型的消息时自动响应给用户的文本消息。\n- WELCOME_TXT:(可选), 新关注时默认响应的文本消息。\n\n然后，您需要逐一实现WxApplication的各个on_xxxx函数。不同类型的上行消息及事件均有对应的on_xxx函数\n\n### on_xxx函数\n\n\n所有的on_xxx函数列举如下：\n\n- on_text, 响应用户文本\n- on_link，响应用户上行的链接\n- on_image，响应用户上行图片\n- on_voice，响应用户上行语音\n- on_video，响应用户上行视频\n- on_location，响应用户上行地理位置\n- on_subscribe，响应用户关注事件\n- on_unsubscribe，响应用户取消关注事件\n- on_click，响应用户点击自定义菜单事件\n- on_scan，响应用户扫描二维码事件\n- on_location_update，响应用户地理位置变更事件\n- on_view，响应用户点击自定义菜单访问网页事件\n- on_scancode_push\n- on_scancode_waitmsg\n- on_pic_sysphoto\n- on_pic_photo_or_album\n- on_pic_weixin\n- on_location_select\n\non_xxx函数的定义如下：\n\n\tdef on_xxx(self, req):\n\t\treturn WxResponse()\n\non_xxx函数，接受一个WxRequest参数req，返回一个WxResponse的子类实例。\n\n#### WxRequest\n\nreq是一个代表用户上行消息的WxRequest实例。其属性与消息的XML属性一一对应，不同的消息有几个相同的属性：\n\n- ToUserName\n- FromUserName\n- CreateTime\n- MsgType\n- MsgId\n\n不同的消息类型对应有各自的属性，属性名与消息的xml标签名保一致。如MsgType为\u0005text的的req，有一个Content属怀，而MsgType为image的req，则有PicUrl及MediaId两个属性。更多消息详情请查看微信公众号[官方文档](http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html)。\n\n#### WxResponse\n\non_xxx函数需要返回一个WxResponse的子类实例。WxResponse的子类及其构造的方式有：\n\n##### WxTextResponse, 文本消息\n\n \tWxTextResponse(\"hello\", req)\n\t\n##### WxImageResponse, 图片消息\n\n\tWxImageResponse(WxImage(MediaId='xxyy'),req)\n\t\n##### WxVoiceResponse, 语音消息\n\n\tWxVoiceResponse(WxVoice(MediaId='xxyy'),req)\n\t\n##### WxVideoResponse, 视频消息\n\n\tWxVideoResponse(WxVideo(MediaId='xxyy', Title='video', Description='test'),req)\n\t\n##### WxMusicResponse, 音乐消息\n\n\tWxMusicResponse(WxMusic(Title='hey jude', \n\t\tDescription='dont make it bad', \n\t\tPicUrl='http://heyjude.com/logo.png', \n\t\tUrl='http://heyjude.com/mucis.mp3'), req)\n\n##### WxNewsResponse, 图文消息\n\n\tWxNewsResponse(WxArticle(Title='test news', \n\t\tDescription='this is a test', \n\t\tPicurl='http://smpic.com/pic.jpg', \n\t\tUrl='http://github.com/jeffkit'), req)\n##### WxEmptyResponse, 无响应\n\t\n\tWxEmptyResponse(req)\n\n### 在Django中使用WxApplication\n\n\n下面以Django为例说明，实现一个微信回调的功能(view)，利用上面示例代码中的WxApp：\n\t\n\tfrom django.http import HttpResponse\n\n\tdef wechat(request):\n\t\tapp = WxApp()\n\t\tresult = app.process(request.GET, request.body)\n\t\treturn HttpResponse(result)\n\n配置 urls.py:\n\t\n\turlpatterns = patterns('',\n    \turl(r'^wechat/', 'myapp.views.wechat'),\n\t)\n\n\n### 在Flask中使用WxApplication\n\tfrom flask import request\n\tfrom flask import Flask\n\tapp = Flask(__name__)\n\t\n\t@app.route('/wechat')\n\tdef wechat():\n\t\tapp = WxApp()\n\t\treturn app.process(request.args, request.data)\n\n\nOK.就这么多，WxApplication本身与web框架无关，不管你使用哪个Framework都可以享受到它带来的便利。\n\n### 什么？你不喜欢写WxApplication的子类？！\n\n好吧，其实，你可以在任何地方写on_xxx的响应函数。然后在使用之前，告诉一个WxApplication你要用哪个函数来响应对应的事件就好。以Django为例：\n\n\t# 在任何地方写你自己的消息处理函数。\n\t# @any_decorator   # 添加任何装饰器。\n\tdef my_text_handler(req):\n\t\treturn WxTextResponse(req.Content, req)\n\t\n\t# 在web的程序里这样使用：\n\tdef wechat_view(request):\n\t\tapp = WxApplication()   # 实例化基类就好。\n\t\tapp.handlers = {'text': my_text_handler}  # 设置你自己的处理器\n\t\tresult = app.process(request.GET, request.body, \n\t\t\ttoken='xxxx', app_id='xxxx', aes_key='xxxx')\n\t\treturn HttpResponse(result)\n\t\n\t\t\n嗯，可以自定义消息的handlers，而如果要针对事件自定义handlers的话，要修改app.event_handlers，数据的格式是一样的。具体的消息和事件类型的key，就直接看看源码得了。卡卡。\n\t\n\n## 3. OAuth API\n\nOAuth API目前仅支持下列常用接口：\n\n- 发送消息\n- 用户管理\n- 自定义菜单管理\n- 多媒体上传下载\n- 二维码\n\n其他接口拟于未来的版本中支持，同时欢迎大家来增补。\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffkit%2Fwechat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffkit%2Fwechat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffkit%2Fwechat/lists"}