__init__.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import, unicode_literals
  3. import time
  4. from wechatpy.client.base import BaseWeChatClient
  5. from wechatpy.client import api
  6. class WeChatClient(BaseWeChatClient):
  7. """
  8. 微信 API 操作类
  9. 通过这个类可以操作微信 API,发送主动消息、群发消息和创建自定义菜单等。
  10. """
  11. API_BASE_URL = 'https://api.weixin.qq.com/cgi-bin/'
  12. card = api.WeChatCard()
  13. customservice = api.WeChatCustomService()
  14. datacube = api.WeChatDataCube()
  15. device = api.WeChatDevice()
  16. group = api.WeChatGroup()
  17. invoice = api.WeChatInvoice()
  18. jsapi = api.WeChatJSAPI()
  19. material = api.WeChatMaterial()
  20. media = api.WeChatMedia()
  21. menu = api.WeChatMenu()
  22. merchant = api.WeChatMerchant()
  23. message = api.WeChatMessage()
  24. misc = api.WeChatMisc()
  25. poi = api.WeChatPoi()
  26. qrcode = api.WeChatQRCode()
  27. scan = api.WeChatScan()
  28. semantic = api.WeChatSemantic()
  29. shakearound = api.WeChatShakeAround()
  30. tag = api.WeChatTag()
  31. template = api.WeChatTemplate()
  32. user = api.WeChatUser()
  33. wifi = api.WeChatWiFi()
  34. wxa = api.WeChatWxa()
  35. marketing = api.WeChatMarketing()
  36. def __init__(self, appid, secret, access_token=None,
  37. session=None, timeout=None, auto_retry=True):
  38. super(WeChatClient, self).__init__(
  39. appid, access_token, session, timeout, auto_retry
  40. )
  41. self.appid = appid
  42. self.secret = secret
  43. def fetch_access_token(self):
  44. """
  45. 获取 access token
  46. 详情请参考 http://mp.weixin.qq.com/wiki/index.php?title=通用接口文档
  47. :return: 返回的 JSON 数据包
  48. """
  49. return self._fetch_access_token(
  50. url='https://api.weixin.qq.com/cgi-bin/token',
  51. params={
  52. 'grant_type': 'client_credential',
  53. 'appid': self.appid,
  54. 'secret': self.secret
  55. }
  56. )
  57. class WeChatComponentClient(WeChatClient):
  58. """
  59. 开放平台代公众号调用客户端
  60. """
  61. def __init__(self, appid, component, access_token=None,
  62. refresh_token=None, session=None, timeout=None):
  63. # 未用到secret,所以这里没有
  64. super(WeChatComponentClient, self).__init__(
  65. appid, '', '', session, timeout
  66. )
  67. self.appid = appid
  68. self.component = component
  69. # 如果公众号是刚授权,外部还没有缓存access_token和refresh_token
  70. # 可以传入这两个值,session 会缓存起来。
  71. # 如果外部已经缓存,这里只需要传入 appid,component和session即可
  72. cache_access_token = self.session.get(self.access_token_key)
  73. if access_token and (not cache_access_token or cache_access_token != access_token):
  74. self.session.set(self.access_token_key, access_token, 7200)
  75. if refresh_token:
  76. self.session.set(self.refresh_token_key, refresh_token)
  77. @property
  78. def access_token_key(self):
  79. return '{0}_access_token'.format(self.appid)
  80. @property
  81. def refresh_token_key(self):
  82. return '{0}_refresh_token'.format(self.appid)
  83. @property
  84. def access_token(self):
  85. access_token = self.session.get(self.access_token_key)
  86. if not access_token:
  87. self.fetch_access_token()
  88. access_token = self.session.get(self.access_token_key)
  89. return access_token
  90. @property
  91. def refresh_token(self):
  92. return self.session.get(self.refresh_token_key)
  93. def fetch_access_token(self):
  94. """
  95. 获取 access token
  96. 详情请参考 https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list\
  97. &t=resource/res_list&verify=1&id=open1419318587&token=&lang=zh_CN
  98. 这是内部刷新机制。请不要完全依赖!
  99. 因为有可能在缓存期间没有对此公众号的操作,造成refresh_token失效。
  100. :return: 返回的 JSON 数据包
  101. """
  102. expires_in = 7200
  103. result = self.component.refresh_authorizer_token(
  104. self.appid, self.refresh_token)
  105. if 'expires_in' in result:
  106. expires_in = result['expires_in']
  107. self.session.set(
  108. self.access_token_key,
  109. result['authorizer_access_token'],
  110. expires_in
  111. )
  112. self.expires_at = int(time.time()) + expires_in
  113. return result