Commit f040fbfcafde38a728dfdac79875fbfeb8d0cb1d

Authored by lanrion
1 parent c001062a
Exists in master

添加jsticket、suite_token存储方案、日志配置

README.md
... ... @@ -8,20 +8,38 @@ https://rubygems.org/gems/qy_wechat_api
8 8  
9 9 **企业号对应多个管理组,请前往 `设置` => `权限管理` 任意创建一个管理组,在管理组最下角即可获取 CorpID Secret**
10 10  
11   ->> 此gem目前仅支持在Rails框架下使用!
12   -
13 11 **有问题请及时提issue**
14 12  
15 13 ```ruby
16 14 gem "qy_wechat_api", git: "https://github.com/lanrion/qy_wechat_api.git"
17 15 ```
18 16  
19   -# Token 存储方案
  17 +# 配置
  18 +
  19 +## jsticket、suite_token存储方案
  20 +如果你是在Rails框架下,默认情况下直接使用Rails.cache,如果你想独立cache,请配置如下:
  21 +```ruby
  22 +QyWechatApi.configure do |config|
  23 + config.cache_store = YourCustomCacheStore
  24 +end
  25 +```
  26 +cache_store按照Rails.cache的接口实现,强烈建议使用ActiveSupport::Cache
  27 +
  28 +## 日志配置
  29 +如果你是在Rails框架下,默认情况下直接使用Rails.logger,如果你想独立cache,请配置如下:
  30 +```ruby
  31 +QyWechatApi.configure do |config|
  32 + config.logger = YourCustomLogger
  33 +end
  34 +```
  35 +logger按照Rails.logger的接口实现,强烈建议使用ActiveSupport::Logger
20 36  
21   -## 对象存储
  37 +## Token 存储方案(TODO: 待重构直接使用cache_store)
  38 +
  39 +### 对象存储
22 40 如果你是单个企业号,建议使用这个方案,无需任何配置即可使用。
23 41  
24   -## Redis 存储
  42 +### Redis 存储
25 43 ```ruby
26 44 redis = Redis.new(host: "127.0.0.1", port: "6379")
27 45  
... ... @@ -38,9 +56,6 @@ QyWechatApi.configure do |config|
38 56 end
39 57 ```
40 58  
41   -## 自定义存储方案
42   -TODO...
43   -
44 59 # API基本用法
45 60  
46 61 请务必结合:http://qydev.weixin.qq.com/wiki/index.php 理解以下API参数使用。
... ... @@ -49,6 +64,7 @@ TODO...
49 64  
50 65 ```ruby
51 66 group_client = QyWechatApi::Client.new(corpid, corpsecret)
  67 +
52 68 # 为了确保用户输入的corpid, corpsecret是准确的,请务必执行:
53 69 group_client.is_valid?
54 70 ```
... ... @@ -76,22 +92,31 @@ group_client.department.list
76 92 ```ruby
77 93 # 创建成员
78 94 group_client.user.create(user_id, name, options={})
  95 +
79 96 # 更新成员
80 97 group_client.user.update(user_id, options={})
  98 +
81 99 # 删除成员
82 100 group_client.user.delete(user_id)
  101 +
83 102 # 批量删除成员
84 103 group_client.user.batch_delete(user_ids)
  104 +
85 105 # 获取成员
86 106 group_client.user.get(user_id)
  107 +
87 108 # 获取部门成员
88 109 group_client.user.simple_list(department_id, fetch_child=nil, status=nil)
  110 +
89 111 # 获取部门成员(详情)
90 112 group_client.user.full_list(department_id, fetch_child=nil, status=nil)
  113 +
91 114 # 邀请成员关注
92 115 group_client.user.send_invitation(user_id, tips=nil)
  116 +
93 117 # userid转换成openid接口(企业支付需要使用到)
94 118 group_client.covert_to_open_id(user_id, agent_id="")
  119 +
95 120 # openid转换成userid接口
96 121 group_client.covert_to_user_id(open_id)
97 122 ```
... ... @@ -136,9 +161,9 @@ group_client.oauth.get_user_info("code", "app_id")
136 161 ## 发送消息
137 162  
138 163 ```ruby
139   - # params: (users, parties, tags, agent_id, content, safe=0)
140   - # users, parties, tags 如果是多个用户,传数组,如果是全部,则直接传 "@all"
141   - group_client.message.send_text("@all", "@all", "@all", app_id, text_message)
  164 +# params: (users, parties, tags, agent_id, content, safe=0)
  165 +# users, parties, tags 如果是多个用户,传数组,如果是全部,则直接传 "@all"
  166 +group_client.message.send_text("@all", "@all", "@all", app_id, text_message)
142 167 ```
143 168 **其他发送消息方法请查看 api/message.rb**
144 169  
... ... @@ -163,6 +188,7 @@ group_client.media.get_media_by_id(media_id)
163 188 "show_cover_pic": "0"
164 189 }
165 190 group_client.material.add_mpnews(agent_id, articles)
  191 +
166 192 # 更新图文素材
167 193 group_client.material.update_mpnews(agent_id, media_id, articles=[])
168 194  
... ... @@ -183,7 +209,7 @@ group_client.material.list(agent_id, type, offset, count=20)
183 209  
184 210 ## 第三方应用
185 211  
186   -这里特别注意:保留 suite_access_token的cache是直接利用了 Rails.cache,请务必在Rails框架下使用此gem
  212 +这里特别注意:保留 suite_access_token的cache是直接利用了前文配置的cache_store缓存
187 213  
188 214 ### api 使用介绍
189 215  
... ... @@ -215,57 +241,62 @@ suite_api.auth_url(code, uri, state="suite")
215 241 ## 企业号登录授权
216 242  
217 243 ```ruby
218   - # 获取登录授权URL
219   - # state default 'qy_wechat', option
220   - # 此处授权回调时会传递auth_code、expires_in,auth_code用于get_login_info(获取企业号管理员登录信息)接口使用
221   - group_client.auth_login.auth_login_url("redirect_uri", "state")
  244 +# 获取登录授权URL
  245 +# state default 'qy_wechat', option
  246 +# 此处授权回调时会传递auth_code、expires_in,auth_code用于get_login_info(获取企业号管理员登录信息)接口使用
  247 +group_client.auth_login.auth_login_url("redirect_uri", "state")
222 248  
223   - # 获取应用提供商凭证
224   - # provider_secret:提供商的secret,在提供商管理页面可见
225   - # 此处会返回:provider_access_token(已通过Rails.cache缓存7100s)
226   - group_client.auth_login.get_provider_token(provider_secret)
  249 +# 获取应用提供商凭证
  250 +# provider_secret:提供商的secret,在提供商管理页面可见
  251 +# 此处会返回:provider_access_token(已通过QyWechatApi.cache缓存7100s)
  252 +group_client.auth_login.get_provider_token(provider_secret)
227 253  
228   - # 通过传递provider_access_token,获取企业号管理员登录信息
229   - group_client.auth_login.get_login_info(auth_code, provider_access_token)
  254 +# 通过传递provider_access_token,获取企业号管理员登录信息
  255 +group_client.auth_login.get_login_info(auth_code, provider_access_token)
230 256  
231   - # 通过传递provider_secret,获取企业号管理员登录信息
232   - group_client.auth_login.get_login_info_by_secret(auth_code, provider_secret)
  257 +# 通过传递provider_secret,获取企业号管理员登录信息
  258 +group_client.auth_login.get_login_info_by_secret(auth_code, provider_secret)
233 259 ```
234 260  
235 261 ## 异步任务接口
236 262  
237 263 ```ruby
238   - # 邀请成员关注
239   - group_client.async_task.invite_user(callback, invite_info={})
240   - # 增量更新成员
241   - group_client.async_task.sync_user(callback, media_id)
242   - # 全量覆盖成员
243   - group_client.async_task.replace_user(callback, media_id)
244   - # 全量覆盖部门
245   - group_client.async_task.replace_party(callback, media_id)
246   - # 获取异步任务结果
247   - group_client.async_task.get_result(job_id)
  264 +# 邀请成员关注
  265 +group_client.async_task.invite_user(callback, invite_info={})
  266 +# 增量更新成员
  267 +group_client.async_task.sync_user(callback, media_id)
  268 +# 全量覆盖成员
  269 +group_client.async_task.replace_user(callback, media_id)
  270 +# 全量覆盖部门
  271 +group_client.async_task.replace_party(callback, media_id)
  272 +# 获取异步任务结果
  273 +group_client.async_task.get_result(job_id)
  274 +```
  275 +
  276 +## 获取js api签名包
  277 +```ruby
  278 +group_client.sign_package(request.url)
248 279 ```
249 280  
250 281 ## 管理企业号应用
251 282  
252 283 ```ruby
253   - # 获取应用概况列表
254   - group_client.agent.list
255   -
256   - # 设置企业号应用
257   - # agentid 企业应用的id
258   - # report_location_flag 企业应用是否打开地理位置上报 0:不上报;1:进入会话上报;2:持续上报
259   - # logo_mediaid 企业应用头像的mediaid,通过多媒体接口上传图片获得mediaid,上传后会自动裁剪成方形和圆形两个头像
260   - # name 企业应用名称
261   - # description 企业应用详情
262   - # redirect_domain 企业应用可信域名
263   - # isreportuser 是否接收用户变更通知。0:不接收;1:接收
264   - # isreportenter 是否上报用户进入应用事件。0:不接收;1:接收
265   - group_client.agent.set()
266   -
267   - ## 获取企业号应用
268   - group_client.agent.get(agent_id)
  284 +# 获取应用概况列表
  285 +group_client.agent.list
  286 +
  287 +# 设置企业号应用
  288 +# agentid 企业应用的id
  289 +# report_location_flag 企业应用是否打开地理位置上报 0:不上报;1:进入会话上报;2:持续上报
  290 +# logo_mediaid 企业应用头像的mediaid,通过多媒体接口上传图片获得mediaid,上传后会自动裁剪成方形和圆形两个头像
  291 +# name 企业应用名称
  292 +# description 企业应用详情
  293 +# redirect_domain 企业应用可信域名
  294 +# isreportuser 是否接收用户变更通知。0:不接收;1:接收
  295 +# isreportenter 是否上报用户进入应用事件。0:不接收;1:接收
  296 +group_client.agent.set()
  297 +
  298 +## 获取企业号应用
  299 +group_client.agent.get(agent_id)
269 300 ```
270 301  
271 302 ### 应用套件的回调通知处理
... ...
lib/qy_wechat_api.rb
... ... @@ -27,13 +27,13 @@ module QyWechatApi
27 27 class << self
28 28  
29 29 def http_get_without_token(url, params={})
30   - Rails.logger.info("url: #{url}--- params: #{params}")
  30 + logger.info("url: #{url}--- params: #{params}")
31 31 get_api_url = ENDPOINT_URL + url
32 32 load_json(RestClient.get(get_api_url, params: params))
33 33 end
34 34  
35 35 def http_post_without_token(url, payload={}, params={})
36   - Rails.logger.info("url: #{url}-- payload: #{payload}-- params: #{params}")
  36 + logger.info("url: #{url}-- payload: #{payload}-- params: #{params}")
37 37 post_api_url = ENDPOINT_URL + url
38 38 payload = JSON.dump(payload) if !payload[:media].is_a?(File)
39 39 load_json(RestClient.post(post_api_url, payload, params: params))
... ... @@ -51,5 +51,28 @@ module QyWechatApi
51 51 "https://open.weixin.qq.com#{url}"
52 52 end
53 53  
  54 + def cache
  55 + if config.cache_store
  56 + config.cache_store
  57 + elsif on_rails?
  58 + Rails.cache
  59 + else
  60 + raise ConfigException, "You should appoint cache_store, e.g. Rails.cache or lookup ActiveSupport::Cache#lookup_store"
  61 + end
  62 + end
  63 +
  64 + def logger
  65 + if config.logger
  66 + config.logger
  67 + elsif on_rails?
  68 + Rails.logger
  69 + else
  70 + raise ConfigException, "You should appoint one logger, e.g. Rails.logger or lookup ActiveSupport::Logger"
  71 + end
  72 + end
  73 +
  74 + def on_rails?
  75 + defined?(Rails)
  76 + end
54 77 end
55 78 end
... ...
lib/qy_wechat_api/api/auth_login.rb
... ... @@ -19,13 +19,13 @@ module QyWechatApi
19 19 # https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token
20 20 def get_provider_token(provider_secret)
21 21 cache_key = "auth_login-#{corp_id}-get_provider_token"
22   - Rails.cache.fetch(cache_key, expires_in: 7100.seconds) do
  22 + QyWechatApi.cache.fetch(cache_key, expires_in: 7100.seconds) do
23 23 payload = {corpid: corp_id, provider_secret: provider_secret}
24 24 url = base_url("get_provider_token")
25 25 res = QyWechatApi.http_post_without_token(url, payload)
26 26 token = res.result["provider_access_token"]
27 27 if token.blank?
28   - Rails.cache.delete(cache_key)
  28 + QyWechatApi.cache.delete(cache_key)
29 29 raise res.errors
30 30 else
31 31 token
... ...
lib/qy_wechat_api/api/js.rb
... ... @@ -3,7 +3,7 @@ module QyWechatApi
3 3 class Js < Base
4 4 def sign_package(url)
5 5 timestamp = Time.now.to_i
6   - noncestr = SecureRandom.hex(16)
  6 + noncestr = SecureRandom.hex(16)
7 7 str = "jsapi_ticket=#{get_jsticket}&noncestr=#{noncestr}&timestamp=#{timestamp}&url=#{url}";
8 8 signature = Digest::SHA1.hexdigest(str)
9 9 {
... ... @@ -16,11 +16,11 @@ module QyWechatApi
16 16 # https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=ACCESS_TOKE
17 17 def get_jsticket
18 18 cache_key = "jsticket-#{corp_id}"
19   - Rails.cache.fetch(cache_key, expires_in: 7100.seconds) do
  19 + QyWechatApi.cache.fetch(cache_key, expires_in: 7100.seconds) do
20 20 res = http_get("/get_jsapi_ticket", {waive_base_url: true})
21 21 ticket = res.result["ticket"]
22 22 if ticket.blank?
23   - Rails.cache.delete(cache_key)
  23 + QyWechatApi.cache.delete(cache_key)
24 24 raise res.errors
25 25 else
26 26 ticket
... ...
lib/qy_wechat_api/api/material.rb
... ... @@ -4,7 +4,7 @@ module QyWechatApi
4 4 module Api
5 5 class Material < Base
6 6  
7   - MATERIAL_TYPES = ["image", "voice", "video", "file"]
  7 + MATERIAL_TYPES = ["image", "voice", "video", "file"].freeze
8 8  
9 9 # 上传永久图文素材
10 10 # https://qyapi.weixin.qq.com/cgi-bin/material/add_mpnews?access_token=ACCESS_TOKEN
... ...
lib/qy_wechat_api/api/service/service_base.rb
... ... @@ -22,16 +22,16 @@ module QyWechatApi
22 22 suite_id: suite_id,
23 23 suite_secret: suite_secret
24 24 }
25   - Rails.cache.fetch(suite_id, expires_in: 7100.seconds) do
26   - Rails.logger.info("Invoke #{suite_id} get_suite_token to refresh")
  25 + QyWechatApi.cache.fetch(suite_id, expires_in: 7100.seconds) do
  26 + QyWechatApi.logger.info("Invoke #{suite_id} get_suite_token to refresh")
27 27 res = QyWechatApi.http_post_without_token(
28 28 request_url("get_suite_token", params),
29 29 params
30 30 )
31   - Rails.logger.info(res)
  31 + QyWechatApi.logger.info(res)
32 32 token = res.result["suite_access_token"]
33 33 if token.blank?
34   - Rails.cache.delete(suite_id)
  34 + QyWechatApi.cache.delete(suite_id)
35 35 raise res.errors
36 36 else
37 37 token
... ...
lib/qy_wechat_api/config.rb
... ... @@ -15,6 +15,6 @@ module QyWechatApi
15 15 end
16 16  
17 17 class Config
18   - attr_accessor :redis
  18 + attr_accessor :redis, :cache_store, :logger
19 19 end
20 20 end
... ...
lib/qy_wechat_api/handler/errors.rb
1 1 module QyWechatApi
2 2 module Errors
3 3 class ValidAccessTokenException < RuntimeError;end
  4 + class ConfigException < RuntimeError;end
4 5 end
5 6 end
... ...
lib/qy_wechat_api/handler/result_handler.rb
... ... @@ -39,7 +39,7 @@ module QyWechatApi
39 39 # result.result[:ok] #=> true
40 40 # result.result['ok'] #=> true
41 41 def package_result(result)
42   - if defined?(Rails)
  42 + if QyWechatApi.on_rails?
43 43 ActiveSupport::HashWithIndifferentAccess.new(result)
44 44 else
45 45 result
... ...
lib/qy_wechat_api/storage/storage.rb
... ... @@ -67,9 +67,5 @@ module QyWechatApi
67 67 raise Errors::ValidAccessTokenException, result_handler.full_error_message
68 68 end
69 69 end
70   -
71   - def weixin_redis
72   - QyWechatApi.weixin_redis
73   - end
74 70 end
75 71 end
... ...