wework 0.3.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/README.md +7 -0
  4. data/lib/wework.rb +15 -10
  5. data/lib/wework/api/agent.rb +15 -79
  6. data/lib/wework/api/base.rb +24 -32
  7. data/lib/wework/api/contact.rb +1 -75
  8. data/lib/wework/api/corp.rb +29 -0
  9. data/lib/wework/api/methods/agent.rb +49 -0
  10. data/lib/wework/api/methods/approval.rb +16 -0
  11. data/lib/wework/api/methods/batch.rb +34 -0
  12. data/lib/wework/api/methods/checkin.rb +19 -0
  13. data/lib/wework/api/methods/department.rb +27 -0
  14. data/lib/wework/api/methods/media.rb +20 -0
  15. data/lib/wework/api/methods/menu.rb +21 -0
  16. data/lib/wework/api/methods/message.rb +52 -0
  17. data/lib/wework/api/methods/provider.rb +16 -0
  18. data/lib/wework/api/methods/suite.rb +53 -0
  19. data/lib/wework/api/methods/user.rb +35 -0
  20. data/lib/wework/api/provider.rb +13 -0
  21. data/lib/wework/api/suite.rb +72 -0
  22. data/lib/wework/cipher.rb +3 -0
  23. data/lib/wework/mock_api.rb +34 -0
  24. data/lib/wework/request.rb +3 -1
  25. data/lib/wework/token/app_token.rb +21 -0
  26. data/lib/wework/token/base.rb +59 -0
  27. data/lib/wework/token/corp_token.rb +20 -0
  28. data/lib/wework/token/js_ticket.rb +25 -0
  29. data/lib/wework/token/provider_token.rb +21 -0
  30. data/lib/wework/token/suite_token.rb +21 -0
  31. data/lib/wework/version.rb +1 -1
  32. data/mock_responses/agent/get.json +29 -0
  33. data/mock_responses/agent/list.json +16 -0
  34. data/mock_responses/agent/set.json +4 -0
  35. data/mock_responses/batch/getresult.json +8 -0
  36. data/mock_responses/department/list.json +24 -0
  37. data/mock_responses/error.json +4 -0
  38. data/mock_responses/files/party.csv +12 -0
  39. data/mock_responses/files/sample.amr +0 -0
  40. data/mock_responses/files/sample.mp4 +0 -0
  41. data/mock_responses/files/sample.txt +1 -0
  42. data/mock_responses/files/user.csv +2 -0
  43. data/mock_responses/files/zhiren.png +0 -0
  44. data/mock_responses/get_jsapi_ticket.json +6 -0
  45. data/mock_responses/gettoken.json +6 -0
  46. data/mock_responses/menu/get.json +24 -0
  47. data/mock_responses/service/get.json +0 -0
  48. data/mock_responses/service/get_corp_token.json +4 -0
  49. data/mock_responses/service/get_login_info.json +34 -0
  50. data/mock_responses/service/get_permanent_code.json +54 -0
  51. data/mock_responses/service/get_pre_auth_code.json +6 -0
  52. data/mock_responses/service/get_provider_token.json +4 -0
  53. data/mock_responses/service/get_suite_token.json +4 -0
  54. data/mock_responses/success.json +4 -0
  55. data/mock_responses/user/convert_to_openid.json +6 -0
  56. data/mock_responses/user/convert_to_userid.json +5 -0
  57. data/mock_responses/user/get.json +18 -0
  58. data/mock_responses/user/getuserdetail.json +10 -0
  59. data/mock_responses/user/getuserinfo.json +8 -0
  60. data/mock_responses/user/list.json +22 -0
  61. data/mock_responses/user/simplelist.json +11 -0
  62. data/wework.gemspec +6 -2
  63. metadata +114 -19
  64. data/lib/wework/engine.rb +0 -31
  65. data/lib/wework/js_ticket/redis_store.rb +0 -41
  66. data/lib/wework/js_ticket/store.rb +0 -36
  67. data/lib/wework/provider.rb +0 -39
  68. data/lib/wework/token/redis_store.rb +0 -41
  69. data/lib/wework/token/store.rb +0 -36
@@ -0,0 +1,16 @@
1
+ require "erb"
2
+
3
+ module Wework
4
+ module Api
5
+ module Methods
6
+ module Approval
7
+ def get_approval_data start_time, end_time, next_spnum=nil
8
+ # https://work.weixin.qq.com/api/doc#11228
9
+ payload = {starttime: start_time, endtime: end_time}
10
+ payload[:next_spnum] = next_spnum unless next_spnum.nil?
11
+ post 'corp/getapprovaldata', payload
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ module Wework
2
+ module Api
3
+ module Methods
4
+ module Batch
5
+ def batch_syncuser media_id, callback_url=nil, token=nil, encodingaeskey=nil
6
+ post 'batch/syncuser', batch_params(media_id, callback_url, token, encodingaeskey)
7
+ end
8
+
9
+ def batch_replaceuser media_id, callback_url=nil, token=nil, encodingaeskey=nil
10
+ post 'batch/replaceuser', batch_params(media_id, callback_url, token, encodingaeskey)
11
+ end
12
+
13
+ def batch_replaceparty media_id, callback_url=nil, token=nil, encodingaeskey=nil
14
+ post 'batch/replaceparty', batch_params(media_id, callback_url, token, encodingaeskey)
15
+ end
16
+
17
+ def batch_getresult job_id
18
+ get 'batch/getresult', params: {jobid: job_id}
19
+ end
20
+
21
+ private
22
+
23
+ def batch_params media_id, callback_url, token, encodingaeskey
24
+ params = {media_id: media_id}
25
+ if callback_url.present? && token.present? && encodingaeskey.present?
26
+ params[:callback] = {url: callback_url, token: token, encodingaeskey: encodingaeskey}
27
+ end
28
+
29
+ params
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ require "erb"
2
+
3
+ module Wework
4
+ module Api
5
+ module Methods
6
+ module Checkin
7
+ def get_checkin_data start_time, end_time, userid_list=[], checkin_type=3
8
+ # https://work.weixin.qq.com/api/doc#11196
9
+ post 'checkin/getcheckindata', {
10
+ opencheckindatatype: checkin_type,
11
+ starttime: start_time,
12
+ endtime: end_time,
13
+ useridlist: userid_list,
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ module Wework
2
+ module Api
3
+ module Methods
4
+ module Department
5
+ def department_create data={}
6
+ post 'department/create', data
7
+ end
8
+
9
+ def department_update department_id, data={}
10
+ post 'department/update', data.merge(id: department_id)
11
+ end
12
+
13
+ def department_delete department_id
14
+ get 'department/delete', params: {id: department_id}
15
+ end
16
+
17
+ def department_list department_id=nil
18
+ if department_id.nil?
19
+ get 'department/list'
20
+ else
21
+ get 'department/list', params: {id: department_id}
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module Wework
2
+ module Api
3
+ module Methods
4
+ module Media
5
+ # public API
6
+ def media_upload(type, file)
7
+ post_file 'media/upload', file, params: { type: type }
8
+ end
9
+
10
+ def media_get(media_id)
11
+ get 'media/get', params: { media_id: media_id }, as: :file
12
+ end
13
+
14
+ def get_media_url(media_id)
15
+ "#{API_ENDPOINT}media/get?access_token=#{access_token}&media_id=#{media_id}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ require "erb"
2
+
3
+ module Wework
4
+ module Api
5
+ module Methods
6
+ module Menu
7
+ def menu_create menu
8
+ post 'menu/create', menu, params: {agentid: agent_id}
9
+ end
10
+
11
+ def menu_get
12
+ get 'menu/get', params: {agentid: agent_id}
13
+ end
14
+
15
+ def menu_delete
16
+ get 'menu/delete', params: {agentid: agent_id}
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,52 @@
1
+ require "erb"
2
+
3
+ module Wework
4
+ module Api
5
+ module Methods
6
+ module Message
7
+ def miniprogram_message_send user_id, miniprogram_notice={}
8
+ notice = miniprogram_notice.merge(appid: agent_id)
9
+ post 'message/send', { touser: user_id, msgtype: 'miniprogram_notice', miniprogram_notice: notice }
10
+ end
11
+
12
+ def text_message_send user_ids, department_ids, content
13
+ message_send user_ids, department_ids, {text: {content: content}, msgtype: 'text'}
14
+ end
15
+
16
+ def image_message_send user_ids, department_ids, media_id
17
+ message_send user_ids, department_ids, {image: {media_id: media_id}, msgtype: 'image'}
18
+ end
19
+
20
+ def voice_message_send user_ids, department_ids, media_id
21
+ message_send user_ids, department_ids, {voice: {media_id: media_id}, msgtype: 'voice'}
22
+ end
23
+
24
+ def file_message_send user_ids, department_ids, media_id
25
+ message_send user_ids, department_ids, {file: {media_id: media_id}, msgtype: 'file'}
26
+ end
27
+
28
+ def video_message_send user_ids, department_ids, video={}
29
+ message_send user_ids, department_ids, {video: video, msgtype: 'video'}
30
+ end
31
+
32
+ def textcard_message_send user_ids, department_ids, textcard={}
33
+ message_send user_ids, department_ids, {textcard: textcard, msgtype: 'textcard'}
34
+ end
35
+
36
+ def news_message_send user_ids, department_ids, news=[]
37
+ message_send user_ids, department_ids, {news: {articles: news}, msgtype: 'news'}
38
+ end
39
+
40
+ private
41
+
42
+ def message_send user_ids, department_ids, payload={}
43
+ payload[:agentid] = agent_id
44
+ payload[:touser] = Array.wrap(user_ids).join('|') if user_ids.present?
45
+ payload[:toparty] = Array.wrap(department_ids).join('|') if department_ids.present?
46
+
47
+ post 'message/send', payload
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,16 @@
1
+ module Wework
2
+ module Api
3
+ module Methods
4
+ module Provider
5
+ def sso_authorize_url(redirect_uri, user_type='admin', state='qywxlogin')
6
+ uri = ERB::Util.url_encode(redirect_uri)
7
+ "#{SSO_AUTHORIZE_ENDPOINT}?appid=#{corp_id}&redirect_uri=#{uri}&state=#{state}&usertype=#{user_type}"
8
+ end
9
+
10
+ def get_login_info auth_code
11
+ post 'service/get_login_info', {auth_code: auth_code}
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ module Wework
2
+ module Api
3
+ module Methods
4
+ module Suite
5
+ def corp_authorize_url(redirect_uri, state="corp_authorize")
6
+ "#{APP_AUTHORIZE_ENDPOINT}?suite_id=#{suite_id}&pre_auth_code=#{get_pre_auth_code}&redirect_uri=#{redirect_uri}&state=#{state}"
7
+ end
8
+
9
+ def get_pre_auth_code
10
+ result = get 'service/get_pre_auth_code'
11
+ return result.pre_auth_code if result.success?
12
+ end
13
+
14
+ def set_session_info pre_auth_code, session_info={}
15
+ post 'service/set_session_info', {pre_auth_code: pre_auth_code, session_info: session_info}
16
+ end
17
+
18
+ def get_permanent_code auth_code
19
+ post 'service/get_permanent_code', {auth_code: auth_code}
20
+ end
21
+
22
+ def get_auth_info auth_corpid, permanent_code
23
+ post 'service/get_auth_info', {auth_corpid: auth_corpid, permanent_code: permanent_code}
24
+ end
25
+
26
+ def get_corp_token auth_corpid, permanent_code
27
+ post 'service/get_corp_token', {suite_id: suite_id, auth_corpid: auth_corpid, permanent_code: permanent_code}
28
+ end
29
+
30
+ def get_admin_list auth_corpid, agentid
31
+ post 'service/get_admin_list', {auth_corpid: auth_corpid, agentid: agentid}
32
+ end
33
+
34
+ def authorize_url(redirect_uri, scope="snsapi_base", state="wxwork")
35
+ uri = ERB::Util.url_encode(redirect_uri)
36
+ "#{AUTHORIZE_ENDPOINT}?appid=#{suite_id}&redirect_uri=#{uri}&response_type=code&scope=#{scope}&state=#{state}#wechat_redirect"
37
+ end
38
+
39
+ def get_oauth_userinfo(code)
40
+ get 'service/getuserinfo3rd', params: {access_token: access_token, code: code}
41
+ end
42
+
43
+ def get_user_detail(user_ticket)
44
+ post "service/getuserdetail3rd?access_token=#{access_token}", {user_ticket: user_ticket}
45
+ end
46
+
47
+ def get_session_with_jscode(js_code, grant_type='authorization_code')
48
+ post 'service/miniprogram/jscode2session', {}, params: {js_code: js_code, grant_type: grant_type}
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,35 @@
1
+ module Wework
2
+ module Api
3
+ module Methods
4
+ module User
5
+ def user_create data={}
6
+ post 'user/create', data
7
+ end
8
+
9
+ def user_get userid
10
+ get 'user/get', params: {userid: userid}
11
+ end
12
+
13
+ def user_update userid, data={}
14
+ post 'user/update', data.merge(userid: userid)
15
+ end
16
+
17
+ def user_delete userid
18
+ get 'user/delete', params: {userid: userid}
19
+ end
20
+
21
+ def user_batchdelete useridlist=[]
22
+ post 'user/batchdelete', {useridlist: useridlist}
23
+ end
24
+
25
+ def user_simplelist department_id, fetch_child=0
26
+ get 'user/simplelist', params: {department_id: department_id, fetch_child: fetch_child}
27
+ end
28
+
29
+ def user_list department_id, fetch_child=0
30
+ get 'user/list', params: {department_id: department_id, fetch_child: fetch_child}
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ module Wework
2
+ module Api
3
+ class Provider < Base
4
+ include Methods::Provider
5
+
6
+ private
7
+
8
+ def token_store
9
+ @token_store ||= Token::ProviderToken.new self
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,72 @@
1
+ require 'builder'
2
+
3
+ module Wework
4
+ module Api
5
+ class Suite < Base
6
+
7
+ include Wework::Cipher
8
+ include Methods::Suite
9
+
10
+ attr_reader :encoding_aes_key, :suite_id, :suite_secret, :suite_token
11
+
12
+ def initialize(options={})
13
+ @suite_id = options.delete(:suite_id)
14
+ @suite_secret = options.delete(:suite_secret)
15
+ @suite_token = options.delete(:suite_token)
16
+ @encoding_aes_key = options.delete(:encoding_aes_key)
17
+ super(options)
18
+ end
19
+
20
+ def msg_decrypt message
21
+ unpack(decrypt(Base64.decode64(message), encoding_aes_key))[0]
22
+ end
23
+
24
+ def msg_encrypt message
25
+ Base64.strict_encode64(encrypt(pack(message, corp_id), encoding_aes_key))
26
+ end
27
+
28
+ def signature(timestamp, nonce, encrypt)
29
+ array = [suite_token, timestamp, nonce]
30
+ array << encrypt unless encrypt.nil?
31
+ Digest::SHA1.hexdigest array.compact.collect(&:to_s).sort.join
32
+ end
33
+
34
+ def generate_xml(msg, timestamp, nonce)
35
+ encrypt = msg_encrypt(msg)
36
+ {
37
+ Encrypt: encrypt,
38
+ MsgSignature: signature(timestamp, nonce, encrypt),
39
+ TimeStamp: timestamp,
40
+ Nonce: nonce
41
+ }.to_xml(root: 'xml', children: 'item', skip_instruct: true, skip_types: true)
42
+ end
43
+
44
+ def suite_ticket= ticket
45
+ Wework.redis.set ticket_key, ticket
46
+ end
47
+
48
+ def suite_ticket
49
+ Wework.redis.get ticket_key
50
+ end
51
+
52
+ def corp(corp_id, permanent_code)
53
+ Wework::Api::Corp.new(suite: self, corp_id: corp_id, permanent_code: permanent_code)
54
+ end
55
+
56
+ private
57
+
58
+ def token_params
59
+ {suite_access_token: access_token}
60
+ end
61
+
62
+ def ticket_key
63
+ "SUITE_TICKET_#{suite_id}"
64
+ end
65
+
66
+ def token_store
67
+ @token_store ||= Token::SuiteToken.new self
68
+ end
69
+
70
+ end
71
+ end
72
+ end
data/lib/wework/cipher.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  require 'openssl/cipher'
2
2
  require 'base64'
3
3
 
4
+ # the file copy from here
5
+ # https://github.com/Eric-Guo/wechat/blob/master/lib/wechat/cipher.rb
6
+
4
7
  module Wework
5
8
  module Cipher
6
9
  extend ActiveSupport::Concern
@@ -0,0 +1,34 @@
1
+ require 'json'
2
+ require 'sinatra/base'
3
+
4
+ module Wework
5
+ class MockApi < Sinatra::Base
6
+ get '/cgi-bin/media/get' do
7
+ send_file mock_file_path('files/zhiren.png'), :type => :jpg
8
+ end
9
+
10
+ get '/cgi-bin/*' do |api|
11
+ json_response "#{api}.json"
12
+ end
13
+
14
+ %i(get post).each do |http_method|
15
+ send http_method, '/cgi-bin/*/*' do |category, api|
16
+ json_response "#{category}/#{api}.json"
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def json_response file_name
23
+ content_type :json
24
+ status 200
25
+ file_path = mock_file_path(file_name)
26
+ file_path = mock_file_path('success.json') unless File.exist?(file_path)
27
+ File.open(file_path, 'rb').read
28
+ end
29
+
30
+ def mock_file_path path
31
+ File.join(File.expand_path('../../../mock_responses/', __FILE__), path)
32
+ end
33
+ end
34
+ end