Commit f040fbfcafde38a728dfdac79875fbfeb8d0cb1d
1 parent
c001062a
Exists in
master
添加jsticket、suite_token存储方案、日志配置
Showing
10 changed files
with
119 additions
and
68 deletions
Show diff stats
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}×tamp=#{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
lib/qy_wechat_api/handler/errors.rb
lib/qy_wechat_api/handler/result_handler.rb
lib/qy_wechat_api/storage/storage.rb