wework 0.3.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +0 -1
- data/README.md +7 -0
- data/lib/wework.rb +15 -10
- data/lib/wework/api/agent.rb +15 -79
- data/lib/wework/api/base.rb +24 -32
- data/lib/wework/api/contact.rb +1 -75
- data/lib/wework/api/corp.rb +29 -0
- data/lib/wework/api/methods/agent.rb +49 -0
- data/lib/wework/api/methods/approval.rb +16 -0
- data/lib/wework/api/methods/batch.rb +34 -0
- data/lib/wework/api/methods/checkin.rb +19 -0
- data/lib/wework/api/methods/department.rb +27 -0
- data/lib/wework/api/methods/media.rb +20 -0
- data/lib/wework/api/methods/menu.rb +21 -0
- data/lib/wework/api/methods/message.rb +52 -0
- data/lib/wework/api/methods/provider.rb +16 -0
- data/lib/wework/api/methods/suite.rb +53 -0
- data/lib/wework/api/methods/user.rb +35 -0
- data/lib/wework/api/provider.rb +13 -0
- data/lib/wework/api/suite.rb +72 -0
- data/lib/wework/cipher.rb +3 -0
- data/lib/wework/mock_api.rb +34 -0
- data/lib/wework/request.rb +3 -1
- data/lib/wework/token/app_token.rb +21 -0
- data/lib/wework/token/base.rb +59 -0
- data/lib/wework/token/corp_token.rb +20 -0
- data/lib/wework/token/js_ticket.rb +25 -0
- data/lib/wework/token/provider_token.rb +21 -0
- data/lib/wework/token/suite_token.rb +21 -0
- data/lib/wework/version.rb +1 -1
- data/mock_responses/agent/get.json +29 -0
- data/mock_responses/agent/list.json +16 -0
- data/mock_responses/agent/set.json +4 -0
- data/mock_responses/batch/getresult.json +8 -0
- data/mock_responses/department/list.json +24 -0
- data/mock_responses/error.json +4 -0
- data/mock_responses/files/party.csv +12 -0
- data/mock_responses/files/sample.amr +0 -0
- data/mock_responses/files/sample.mp4 +0 -0
- data/mock_responses/files/sample.txt +1 -0
- data/mock_responses/files/user.csv +2 -0
- data/mock_responses/files/zhiren.png +0 -0
- data/mock_responses/get_jsapi_ticket.json +6 -0
- data/mock_responses/gettoken.json +6 -0
- data/mock_responses/menu/get.json +24 -0
- data/mock_responses/service/get.json +0 -0
- data/mock_responses/service/get_corp_token.json +4 -0
- data/mock_responses/service/get_login_info.json +34 -0
- data/mock_responses/service/get_permanent_code.json +54 -0
- data/mock_responses/service/get_pre_auth_code.json +6 -0
- data/mock_responses/service/get_provider_token.json +4 -0
- data/mock_responses/service/get_suite_token.json +4 -0
- data/mock_responses/success.json +4 -0
- data/mock_responses/user/convert_to_openid.json +6 -0
- data/mock_responses/user/convert_to_userid.json +5 -0
- data/mock_responses/user/get.json +18 -0
- data/mock_responses/user/getuserdetail.json +10 -0
- data/mock_responses/user/getuserinfo.json +8 -0
- data/mock_responses/user/list.json +22 -0
- data/mock_responses/user/simplelist.json +11 -0
- data/wework.gemspec +6 -2
- metadata +114 -19
- data/lib/wework/engine.rb +0 -31
- data/lib/wework/js_ticket/redis_store.rb +0 -41
- data/lib/wework/js_ticket/store.rb +0 -36
- data/lib/wework/provider.rb +0 -39
- data/lib/wework/token/redis_store.rb +0 -41
- data/lib/wework/token/store.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9599e4575016ec45c4efe18b2e9d80cb27873f3cb8675ff379e7a1f9da774954
|
4
|
+
data.tar.gz: fc49b09c054faecde4feb2e9eab2754e39b6340b1a1be78b6ab81c3bc1260679
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 54a4da5b3fcd4f14c58ecb1f95e44348b95f80b970fc4ddf9b15491e80db824bcf39763ecce2473379c41500f308c8b51056120a26c8a1b9ba51b4dd74245859
|
7
|
+
data.tar.gz: 557479ed57faeae92f92f9633ca3a68fa0584a8529e2cc1a54afa273f1fb64a2f3fdf66a4e79692c5aa0e34d7080979487ecf36c0985cda26758fb881e5816d6
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
Wework is a ruby API wrapper for work wechat.
|
4
4
|
|
5
|
+
[](https://circleci.com/gh/mycolorway/wework/tree/suite)
|
6
|
+
|
7
|
+
## Version 1.1.0
|
8
|
+
* 支持第三方应用接口
|
9
|
+
* 支持小程序接口
|
10
|
+
|
11
|
+
|
5
12
|
## Version 0.1.4
|
6
13
|
* 异步任务接口 [doc](https://work.weixin.qq.com/api/doc#10138)
|
7
14
|
|
data/lib/wework.rb
CHANGED
@@ -2,22 +2,27 @@ require 'redis'
|
|
2
2
|
require 'active_support/all'
|
3
3
|
#require 'active_support/core_ext/object/blank'
|
4
4
|
|
5
|
-
|
6
|
-
require path
|
7
|
-
end
|
5
|
+
LIB_PATH = "#{File.dirname(__FILE__)}/wework"
|
6
|
+
Dir["#{LIB_PATH}/api/methods/*.rb", "#{LIB_PATH}/token/*.rb"].each { |path| require path }
|
8
7
|
|
8
|
+
require 'wework/version'
|
9
|
+
require 'wework/cipher'
|
10
|
+
require 'wework/config'
|
9
11
|
require 'wework/api/base'
|
10
12
|
require 'wework/api/agent'
|
11
13
|
require 'wework/api/contact'
|
14
|
+
require 'wework/api/suite'
|
15
|
+
require 'wework/api/corp'
|
16
|
+
require 'wework/api/provider'
|
17
|
+
|
12
18
|
|
13
19
|
module Wework
|
14
|
-
API_ENDPOINT
|
15
|
-
AUTHORIZE_ENDPOINT
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
SUCCESS_CODE = 0
|
20
|
+
API_ENDPOINT = 'https://qyapi.weixin.qq.com/cgi-bin/'.freeze
|
21
|
+
AUTHORIZE_ENDPOINT = 'https://open.weixin.qq.com/connect/oauth2/authorize'.freeze
|
22
|
+
SSO_AUTHORIZE_ENDPOINT = 'https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect'.freeze
|
23
|
+
APP_AUTHORIZE_ENDPOINT = 'https://open.work.weixin.qq.com/3rdapp/install'.freeze
|
24
|
+
HTTP_OK_STATUS = [200, 201].freeze
|
25
|
+
SUCCESS_CODE = 0
|
21
26
|
|
22
27
|
# Exceptions
|
23
28
|
class RedisNotConfigException < RuntimeError; end
|
data/lib/wework/api/agent.rb
CHANGED
@@ -1,94 +1,30 @@
|
|
1
|
-
require "erb"
|
2
|
-
|
3
1
|
module Wework
|
4
2
|
module Api
|
5
3
|
class Agent < Base
|
6
|
-
# user agent: UA is mozilla/5.0 (iphone; cpu iphone os 10_2 like mac os x) applewebkit/602.3.12 (khtml, like gecko) mobile/14c92 wxwork/1.3.2 micromessenger/6.2
|
7
|
-
|
8
|
-
def authorize_url(redirect_uri, scope="snsapi_base", state="wxwork")
|
9
|
-
uri = ERB::Util.url_encode(redirect_uri)
|
10
|
-
"#{AUTHORIZE_ENDPOINT}?appid=#{corp_id}&redirect_uri=#{uri}&response_type=code&scope=#{scope}&agentid=#{app_id}&state=#{state}#wechat_redirect"
|
11
|
-
end
|
12
|
-
|
13
|
-
def get_oauth_userinfo code
|
14
|
-
get 'user/getuserinfo', params: {code: code}
|
15
|
-
end
|
16
|
-
|
17
|
-
def get_jssign_package url
|
18
|
-
timestamp = Time.now.to_i
|
19
|
-
noncestr = SecureRandom.hex(8)
|
20
|
-
str = "jsapi_ticket=#{jsapi_ticket}&noncestr=#{noncestr}×tamp=#{timestamp}&url=#{url}"
|
21
|
-
{
|
22
|
-
"appId" => corp_id,
|
23
|
-
"nonceStr" => noncestr,
|
24
|
-
"timestamp" => timestamp,
|
25
|
-
"url" => url,
|
26
|
-
"signature" => Digest::SHA1.hexdigest(str),
|
27
|
-
"rawString" => str
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
def get_info
|
32
|
-
get 'agent/get', params: {agentid: agent_id}
|
33
|
-
end
|
34
|
-
|
35
|
-
def set_info data={}
|
36
|
-
post 'agent/set', data.merge(agentid: agent_id)
|
37
|
-
end
|
38
|
-
|
39
|
-
def menu_create menu
|
40
|
-
post 'menu/create', menu, params: {agentid: agent_id}
|
41
|
-
end
|
42
|
-
|
43
|
-
def menu_get
|
44
|
-
get 'menu/get', params: {agentid: agent_id}
|
45
|
-
end
|
46
|
-
|
47
|
-
def menu_delete
|
48
|
-
get 'menu/delete', params: {agentid: agent_id}
|
49
|
-
end
|
50
|
-
|
51
|
-
def message_send user_ids, department_ids, payload={}
|
52
|
-
payload[:agentid] = agent_id
|
53
|
-
payload[:touser] = Array.wrap(user_ids).join('|') if user_ids.present?
|
54
|
-
payload[:toparty] = Array.wrap(department_ids).join('|') if department_ids.present?
|
55
|
-
post 'message/send', payload
|
56
|
-
end
|
57
|
-
|
58
|
-
def text_message_send user_ids, department_ids, content
|
59
|
-
message_send user_ids, department_ids, {text: {content: content}, msgtype: 'text'}
|
60
|
-
end
|
61
4
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
message_send user_ids, department_ids, {voice: {media_id: media_id}, msgtype: 'voice'}
|
68
|
-
end
|
5
|
+
include Methods::Agent
|
6
|
+
include Methods::Message
|
7
|
+
include Methods::Menu
|
8
|
+
include Methods::Checkin
|
9
|
+
include Methods::Approval
|
69
10
|
|
70
|
-
|
71
|
-
message_send user_ids, department_ids, {file: {media_id: media_id}, msgtype: 'file'}
|
72
|
-
end
|
11
|
+
attr_reader :agent_id
|
73
12
|
|
74
|
-
def
|
75
|
-
|
13
|
+
def initialize(options={})
|
14
|
+
@agent_id = options.delete(:agent_id)
|
15
|
+
@agent_id = @agent_id.to_i if @agent_id && @agent_id.match?(/\A\d+\Z/)
|
16
|
+
super(options)
|
76
17
|
end
|
77
18
|
|
78
|
-
def
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
def news_message_send user_ids, department_ids, news=[]
|
83
|
-
message_send user_ids, department_ids, {news: {articles: news}, msgtype: 'news'}
|
19
|
+
def jsapi_ticket
|
20
|
+
jsticket_store.ticket
|
84
21
|
end
|
85
22
|
|
86
23
|
private
|
87
24
|
|
88
|
-
def
|
89
|
-
@
|
25
|
+
def jsticket_store
|
26
|
+
@jsticket_store ||= Token::JsTicket.new self
|
90
27
|
end
|
91
|
-
|
92
28
|
end
|
93
29
|
end
|
94
|
-
end
|
30
|
+
end
|
data/lib/wework/api/base.rb
CHANGED
@@ -1,24 +1,19 @@
|
|
1
|
-
require 'wework/
|
2
|
-
require 'wework/token/redis_store'
|
3
|
-
|
4
|
-
require 'wework/js_ticket/store'
|
5
|
-
require 'wework/js_ticket/redis_store'
|
1
|
+
require 'wework/request'
|
6
2
|
|
7
3
|
module Wework
|
8
4
|
module Api
|
9
5
|
class Base
|
10
|
-
include Wework::Cipher
|
11
6
|
|
12
|
-
|
13
|
-
|
7
|
+
include Methods::Media
|
8
|
+
include Methods::User
|
9
|
+
include Methods::Department
|
14
10
|
|
15
|
-
|
16
|
-
delegate :jsapi_ticket, to: :jsticket_store
|
11
|
+
attr_accessor :corp_id, :secret, :options
|
17
12
|
|
18
|
-
def initialize
|
19
|
-
@corp_id = corp_id
|
20
|
-
@
|
21
|
-
@
|
13
|
+
def initialize options={}
|
14
|
+
@corp_id = options.delete(:corp_id)
|
15
|
+
@secret = options.delete(:secret)
|
16
|
+
@token_store = options.delete(:token_store)
|
22
17
|
@options = options
|
23
18
|
end
|
24
19
|
|
@@ -27,58 +22,55 @@ module Wework
|
|
27
22
|
end
|
28
23
|
|
29
24
|
def valid?
|
30
|
-
|
25
|
+
return false if corp_id.nil?
|
26
|
+
token_store.token.present?
|
31
27
|
rescue AccessTokenExpiredError
|
32
28
|
false
|
33
29
|
rescue => e
|
34
|
-
Rails.logger.error "[WEWORK] (valid?) fetch access token error(#{corp_id}
|
30
|
+
Rails.logger.error "[WEWORK] (valid?) fetch access token error(#{corp_id}): #{e.inspect}" if defined?(Rails)
|
35
31
|
false
|
36
32
|
end
|
37
33
|
|
38
34
|
def get(path, headers = {})
|
39
|
-
|
35
|
+
with_token(headers[:params]) do |params|
|
40
36
|
request.get path, headers.merge(params: params)
|
41
37
|
end
|
42
38
|
end
|
43
39
|
|
44
40
|
def post(path, payload, headers = {})
|
45
|
-
|
41
|
+
with_token(headers[:params]) do |params|
|
46
42
|
request.post path, payload, headers.merge(params: params)
|
47
43
|
end
|
48
44
|
end
|
49
45
|
|
50
46
|
def post_file(path, file, headers = {})
|
51
|
-
|
47
|
+
with_token(headers[:params]) do |params|
|
52
48
|
request.post_file path, file, headers.merge(params: params)
|
53
49
|
end
|
54
50
|
end
|
55
51
|
|
56
|
-
|
57
|
-
|
58
|
-
post_file 'media/upload', file, params: { type: type }
|
59
|
-
end
|
60
|
-
|
61
|
-
def media_get(media_id)
|
62
|
-
get 'media/get', params: { media_id: media_id }, as: :file
|
52
|
+
def access_token
|
53
|
+
token_store.token
|
63
54
|
end
|
64
55
|
|
65
56
|
private
|
66
57
|
|
67
|
-
def
|
58
|
+
def with_token(params = {}, tries = 2)
|
68
59
|
params ||= {}
|
69
|
-
yield(params.merge(
|
60
|
+
yield(params.merge(token_params))
|
70
61
|
rescue AccessTokenExpiredError
|
71
|
-
token_store.
|
62
|
+
token_store.update_token
|
72
63
|
retry unless (tries -= 1).zero?
|
73
64
|
end
|
74
65
|
|
75
66
|
def token_store
|
76
|
-
@token_store ||= Token::
|
67
|
+
@token_store ||= Token::AppToken.new self
|
77
68
|
end
|
78
69
|
|
79
|
-
def
|
80
|
-
|
70
|
+
def token_params
|
71
|
+
{access_token: access_token}
|
81
72
|
end
|
73
|
+
|
82
74
|
end
|
83
75
|
end
|
84
76
|
end
|
data/lib/wework/api/contact.rb
CHANGED
@@ -1,81 +1,7 @@
|
|
1
1
|
module Wework
|
2
2
|
module Api
|
3
3
|
class Contact < Base
|
4
|
-
|
5
|
-
def initialize(corp_id, corp_secret)
|
6
|
-
super(corp_id, CONTACT_AGENT_ID, corp_secret)
|
7
|
-
end
|
8
|
-
|
9
|
-
def user_create data={}
|
10
|
-
post 'user/create', data
|
11
|
-
end
|
12
|
-
|
13
|
-
def user_get userid
|
14
|
-
get 'user/get', params: {userid: userid}
|
15
|
-
end
|
16
|
-
|
17
|
-
def user_update userid, data={}
|
18
|
-
post 'user/update', data.merge(userid: userid)
|
19
|
-
end
|
20
|
-
|
21
|
-
def user_delete userid
|
22
|
-
get 'user/delete', params: {userid: userid}
|
23
|
-
end
|
24
|
-
|
25
|
-
def user_batchdelete useridlist=[]
|
26
|
-
post 'user/batchdelete', {useridlist: useridlist}
|
27
|
-
end
|
28
|
-
|
29
|
-
def user_simplelist department_id, fetch_child=0
|
30
|
-
get 'user/simplelist', params: {department_id: department_id, fetch_child: fetch_child}
|
31
|
-
end
|
32
|
-
|
33
|
-
def user_list department_id, fetch_child=0
|
34
|
-
get 'user/list', params: {department_id: department_id, fetch_child: fetch_child}
|
35
|
-
end
|
36
|
-
|
37
|
-
def department_create data={}
|
38
|
-
post 'department/create', data
|
39
|
-
end
|
40
|
-
|
41
|
-
def department_update department_id, data={}
|
42
|
-
post 'department/update', data.merge(id: department_id)
|
43
|
-
end
|
44
|
-
|
45
|
-
def department_delete department_id
|
46
|
-
get 'department/delete', params: {id: department_id}
|
47
|
-
end
|
48
|
-
|
49
|
-
def department_list department_id=0
|
50
|
-
get 'department/list', params: {id: department_id}
|
51
|
-
end
|
52
|
-
|
53
|
-
def batch_syncuser media_id, callback_url=nil, token=nil, encodingaeskey=nil
|
54
|
-
post 'batch/syncuser', batch_params(media_id, callback_url, token, encodingaeskey)
|
55
|
-
end
|
56
|
-
|
57
|
-
def batch_replaceuser media_id, callback_url=nil, token=nil, encodingaeskey=nil
|
58
|
-
post 'batch/replaceuser', batch_params(media_id, callback_url, token, encodingaeskey)
|
59
|
-
end
|
60
|
-
|
61
|
-
def batch_replaceparty media_id, callback_url=nil, token=nil, encodingaeskey=nil
|
62
|
-
post 'batch/replaceparty', batch_params(media_id, callback_url, token, encodingaeskey)
|
63
|
-
end
|
64
|
-
|
65
|
-
def batch_getresult job_id
|
66
|
-
get 'batch/getresult', params: {jobid: job_id}
|
67
|
-
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
def batch_params media_id, callback_url, token, encodingaeskey
|
72
|
-
params = {media_id: media_id}
|
73
|
-
if callback_url.present? && token.present? && encodingaeskey.present?
|
74
|
-
params[:callback] = {url: callback_url, token: token, encodingaeskey: encodingaeskey}
|
75
|
-
end
|
76
|
-
|
77
|
-
params
|
78
|
-
end
|
4
|
+
include Methods::Batch
|
79
5
|
end
|
80
6
|
end
|
81
7
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Wework
|
2
|
+
module Api
|
3
|
+
class Corp < Base
|
4
|
+
|
5
|
+
include Wework::Cipher
|
6
|
+
include Methods::User
|
7
|
+
include Methods::Department
|
8
|
+
|
9
|
+
attr_reader :suite, :permanent_code
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
@suite = options.delete(:suite)
|
13
|
+
@permanent_code = options.delete(:permanent_code)
|
14
|
+
super(options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def agent(agent_id)
|
18
|
+
Wework::Api::Agent.new(corp_id: corp_id, agent_id: agent_id, token_store: token_store)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def token_store
|
24
|
+
@token_store ||= Token::CorpToken.new self
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "erb"
|
2
|
+
|
3
|
+
module Wework
|
4
|
+
module Api
|
5
|
+
module Methods
|
6
|
+
module Agent
|
7
|
+
def authorize_url(redirect_uri, scope="snsapi_base", state="wxwork")
|
8
|
+
# user agent: UA is mozilla/5.0 (iphone; cpu iphone os 10_2 like mac os x) applewebkit/602.3.12 (khtml, like gecko) mobile/14c92 wxwork/1.3.2 micromessenger/6.2
|
9
|
+
uri = ERB::Util.url_encode(redirect_uri)
|
10
|
+
"#{AUTHORIZE_ENDPOINT}?appid=#{corp_id}&redirect_uri=#{uri}&response_type=code&scope=#{scope}&agentid=#{agent_id}&state=#{state}#wechat_redirect"
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_oauth_userinfo code
|
14
|
+
get 'user/getuserinfo', params: {code: code}
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_user_detail user_ticket
|
18
|
+
post 'user/getuserdetail', {user_ticket: user_ticket}
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_jssign_package url
|
22
|
+
timestamp = Time.now.to_i
|
23
|
+
noncestr = SecureRandom.hex(8)
|
24
|
+
str = "jsapi_ticket=#{jsapi_ticket}&noncestr=#{noncestr}×tamp=#{timestamp}&url=#{url}"
|
25
|
+
{
|
26
|
+
"appId" => corp_id,
|
27
|
+
"nonceStr" => noncestr,
|
28
|
+
"timestamp" => timestamp,
|
29
|
+
"url" => url,
|
30
|
+
"signature" => Digest::SHA1.hexdigest(str),
|
31
|
+
"rawString" => str
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_session_with_jscode(js_code, grant_type='authorization_code')
|
36
|
+
post 'miniprogram/jscode2session', {}, params: {js_code: js_code, grant_type: grant_type}
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_agent
|
40
|
+
get 'agent/get', params: {agentid: agent_id}
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_agent data={}
|
44
|
+
post 'agent/set', data.merge(agentid: agent_id)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|