wework 0.1.0 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +8 -10
- data/lib/wework/api/agent.rb +70 -0
- data/lib/wework/api/base.rb +54 -0
- data/lib/wework/api/contact.rb +54 -0
- data/lib/wework/config.rb +25 -0
- data/lib/wework/engine.rb +31 -0
- data/lib/wework/request.rb +101 -0
- data/lib/wework/token/redis_store.rb +40 -0
- data/lib/wework/token/store.rb +31 -0
- data/lib/wework/version.rb +1 -1
- data/lib/wework.rb +27 -2
- data/wework.gemspec +5 -1
- metadata +60 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da08105f38235bd4f06667e179d9c033a82146f1
|
4
|
+
data.tar.gz: cb7194f21cbb79a9c1ffa8e88e8e7362a167b663
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ca30a8f14e08e9a5e47a22e7bee4235da1849cbbae5044ea81a1385458880a1c6470f5428b66d47d912caa240639995f4a0e21a9ba28dba629870b837e1defb
|
7
|
+
data.tar.gz: 720dc74a741a7e828c577326aafe2f76764bda9077efc2dcd04315e8b627599dae4444365099dad454794412cfcc86303d4af99e572ce3ec0fcc95c7222aa630
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -20,20 +20,18 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
## Usage
|
22
22
|
|
23
|
-
TODO:
|
24
|
-
|
25
|
-
## Development
|
26
|
-
|
27
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
28
|
-
|
29
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
23
|
+
TODO: ...
|
30
24
|
|
31
25
|
## Contributing
|
32
26
|
|
33
|
-
|
34
|
-
|
27
|
+
* Fork `Wework` on GitHub
|
28
|
+
* Make your changes
|
29
|
+
* Ensure all tests pass (`bundle exec rake`)
|
30
|
+
* Send a pull request
|
31
|
+
* If we like them we'll merge them
|
32
|
+
* If we've accepted a patch, feel free to ask for commit access!
|
35
33
|
|
36
34
|
## License
|
37
35
|
|
38
|
-
|
36
|
+
Copyright (c) 2016 MyColorway. See LICENSE.txt for further details.
|
39
37
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Wework
|
2
|
+
module Api
|
3
|
+
class Agent < Base
|
4
|
+
# 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
|
5
|
+
|
6
|
+
def get_info
|
7
|
+
get 'agent/get', params: {agentid: agent_id}
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_info data={}
|
11
|
+
post 'agent/set', data.merge(agentid: agent_id)
|
12
|
+
end
|
13
|
+
|
14
|
+
def menu_create menu
|
15
|
+
post 'menu/create', menu, params: {agentid: agent_id}
|
16
|
+
end
|
17
|
+
|
18
|
+
def menu_delete
|
19
|
+
get 'menu/delete', params: {agentid: agent_id}
|
20
|
+
end
|
21
|
+
|
22
|
+
def media_upload type, file
|
23
|
+
post_file 'media/upload', file, params: { type: type }
|
24
|
+
end
|
25
|
+
|
26
|
+
def media_get(media_id)
|
27
|
+
get 'media/get', params: { media_id: media_id }, as: :file
|
28
|
+
end
|
29
|
+
|
30
|
+
def message_send user_ids, department_ids, payload={}
|
31
|
+
payload[:agentid] = agent_id
|
32
|
+
payload[:touser] = Array.wrap(user_ids).join('|') if user_ids.present?
|
33
|
+
payload[:toparty] = Array.wrap(department_ids).join('|') if department_ids.present?
|
34
|
+
post 'message/send', payload
|
35
|
+
end
|
36
|
+
|
37
|
+
def text_message_send user_ids, department_ids, content
|
38
|
+
message_send user_ids, department_ids, {text: {content: content}, msgtype: 'text'}
|
39
|
+
end
|
40
|
+
|
41
|
+
def image_message_send user_ids, department_ids, media_id
|
42
|
+
message_send user_ids, department_ids, {image: {media_id: media_id}, msgtype: 'image'}
|
43
|
+
end
|
44
|
+
|
45
|
+
def voice_message_send user_ids, department_ids, media_id
|
46
|
+
message_send user_ids, department_ids, {voice: {media_id: media_id}, msgtype: 'voice'}
|
47
|
+
end
|
48
|
+
|
49
|
+
def file_message_send user_ids, department_ids, media_id
|
50
|
+
message_send user_ids, department_ids, {file: {media_id: media_id}, msgtype: 'file'}
|
51
|
+
end
|
52
|
+
|
53
|
+
def video_message_send user_ids, department_ids, media_id, title='', description=''
|
54
|
+
message_send user_ids, department_ids, {video: {media_id: media_id, title: 'title', description: description}, msgtype: 'video'}
|
55
|
+
end
|
56
|
+
|
57
|
+
def textcard_message_send user_ids, department_ids, title, description, url, btntxt='详情'
|
58
|
+
message_send user_ids, department_ids, {textcard: {title: title, description: description, url: url, btntxt: btntxt}, msgtype: 'textcard'}
|
59
|
+
end
|
60
|
+
|
61
|
+
def news_message_send user_ids, department_ids, news=[]
|
62
|
+
message_send user_ids, department_ids, {news: {articles: news}, msgtype: 'news'}
|
63
|
+
end
|
64
|
+
|
65
|
+
def agent_id
|
66
|
+
@agent_id.to_i
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'wework/token/store'
|
2
|
+
require 'wework/token/redis_store'
|
3
|
+
|
4
|
+
module Wework
|
5
|
+
module Api
|
6
|
+
class Base
|
7
|
+
attr_reader :corp_id, :agent_id, :agent_secret
|
8
|
+
attr_accessor :options
|
9
|
+
|
10
|
+
delegate :access_token, to: :token_store
|
11
|
+
|
12
|
+
def initialize(corp_id, agent_id, agent_secret, options={})
|
13
|
+
@corp_id = corp_id
|
14
|
+
@agent_id = agent_id
|
15
|
+
@agent_secret = agent_secret
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def token_store
|
20
|
+
@token_store ||= Token::RedisStore.new self
|
21
|
+
end
|
22
|
+
|
23
|
+
def request
|
24
|
+
@request ||= Wework::Request.new(API_ENDPOINT, false)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get(path, headers = {})
|
28
|
+
with_access_token(headers[:params]) do |params|
|
29
|
+
request.get path, headers.merge(params: params)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def post(path, payload, headers = {})
|
34
|
+
with_access_token(headers[:params]) do |params|
|
35
|
+
request.post path, payload, headers.merge(params: params)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def post_file(path, file, headers = {})
|
40
|
+
with_access_token(headers[:params]) do |params|
|
41
|
+
request.post_file path, file, headers.merge(params: params)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def with_access_token(params = {}, tries = 2)
|
46
|
+
params ||= {}
|
47
|
+
yield(params.merge(access_token: access_token))
|
48
|
+
rescue AccessTokenExpiredError
|
49
|
+
token_store.refresh_token
|
50
|
+
retry unless (tries -= 1).zero?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Wework
|
2
|
+
module Api
|
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 userid, name, mobile, department, data={}
|
10
|
+
post 'user/create', data.merge(userid: userid, name: name, mobile: mobile, department: department)
|
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 name, parentid=0, data={}
|
38
|
+
post 'department/create', data.merge(name: name, parentid: parentid)
|
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
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Wework
|
2
|
+
|
3
|
+
class << self
|
4
|
+
attr_accessor :config
|
5
|
+
def configure
|
6
|
+
yield config
|
7
|
+
end
|
8
|
+
|
9
|
+
def config
|
10
|
+
@config ||= Config.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def redis
|
14
|
+
config.redis
|
15
|
+
end
|
16
|
+
|
17
|
+
def http_timeout_options
|
18
|
+
config.http_timeout_options || {write: 5, connect: 5, read: 5}
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Config
|
23
|
+
attr_accessor :redis, :http_timeout_options
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Wework
|
2
|
+
class Engine
|
3
|
+
|
4
|
+
attr_reader :corp_id, :corp_secret, :app_id, :app_secret
|
5
|
+
|
6
|
+
def initialize(options={})
|
7
|
+
@corp_id = options[:corp_id]
|
8
|
+
@corp_secret = options[:corp_secret]
|
9
|
+
@app_id = options[:app_id]
|
10
|
+
@app_secret = options[:app_secret]
|
11
|
+
end
|
12
|
+
|
13
|
+
def contract
|
14
|
+
@contract ||= Wework::Api::Contact.new(corp_id, corp_secret) if contract?
|
15
|
+
end
|
16
|
+
|
17
|
+
def agent
|
18
|
+
@agent ||= Wework::Api::Agent.new(corp_id, app_id, app_secret) if agent?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def agent?
|
24
|
+
corp_id.present? && app_id.present? && app_secret.present?
|
25
|
+
end
|
26
|
+
|
27
|
+
def contract?
|
28
|
+
corp_id.present? && corp_secret.present?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Reference this: https://github.com/Eric-Guo/wechat/blob/master/lib/wechat/http_client.rb
|
2
|
+
require 'http'
|
3
|
+
|
4
|
+
module Wework
|
5
|
+
class Request
|
6
|
+
attr_reader :base, :ssl_context, :httprb
|
7
|
+
|
8
|
+
def initialize(base, skip_verify_ssl)
|
9
|
+
@base = base
|
10
|
+
@httprb = HTTP.timeout(:global, **Wework.http_timeout_options)
|
11
|
+
@ssl_context = OpenSSL::SSL::SSLContext.new
|
12
|
+
@ssl_context.ssl_version = :TLSv1_client
|
13
|
+
@ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE if skip_verify_ssl
|
14
|
+
end
|
15
|
+
|
16
|
+
def get(path, get_header = {})
|
17
|
+
request(path, get_header) do |url, header|
|
18
|
+
params = header.delete(:params)
|
19
|
+
httprb.headers(header).get(url, params: params, ssl_context: ssl_context)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def post(path, post_body, post_header = {})
|
24
|
+
request(path, post_header) do |url, header|
|
25
|
+
params = header.delete(:params)
|
26
|
+
httprb.headers(header).post(url, params: params, json: post_body, ssl_context: ssl_context)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def post_file(path, file, post_header = {})
|
31
|
+
request(path, post_header) do |url, header|
|
32
|
+
params = header.delete(:params)
|
33
|
+
httprb.headers(header)
|
34
|
+
.post(url, params: params,
|
35
|
+
form: { media: HTTP::FormData::File.new(file),
|
36
|
+
hack: 'X' }, # Existing here for http-form_data 1.0.1 handle single param improperly
|
37
|
+
ssl_context: ssl_context)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def request(path, header = {}, &_block)
|
44
|
+
url_base = header.delete(:base) || base
|
45
|
+
as = header.delete(:as)
|
46
|
+
header['Accept'] = 'application/json'
|
47
|
+
response = yield("#{url_base}#{path}", header)
|
48
|
+
|
49
|
+
raise ResponseError.new(response.status) unless HTTP_OK_STATUS.include?(response.status)
|
50
|
+
|
51
|
+
parse_response(response, as || :json) do |parse_as, data|
|
52
|
+
break data unless parse_as == :json && data['errcode'].present?
|
53
|
+
result = Wework::Result.new(data)
|
54
|
+
raise AccessTokenExpiredError if result.token_expired?
|
55
|
+
result
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def parse_response(response, as)
|
60
|
+
content_type = response.headers[:content_type]
|
61
|
+
parse_as = {
|
62
|
+
%r{^application\/json} => :json,
|
63
|
+
%r{^image\/.*} => :file
|
64
|
+
}.each_with_object([]) { |match, memo| memo << match[1] if content_type =~ match[0] }.first || as || :text
|
65
|
+
|
66
|
+
case parse_as
|
67
|
+
when :file
|
68
|
+
file = Tempfile.new('tmp')
|
69
|
+
file.binmode
|
70
|
+
file.write(response.body)
|
71
|
+
file.close
|
72
|
+
data = file
|
73
|
+
|
74
|
+
when :json
|
75
|
+
data = JSON.parse response.body.to_s.gsub(/[\u0000-\u001f]+/, '')
|
76
|
+
else
|
77
|
+
data = response.body
|
78
|
+
end
|
79
|
+
|
80
|
+
yield(parse_as, data)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class Result < OpenStruct
|
85
|
+
def initialize(data)
|
86
|
+
data['full_message'] = "(#{data['errcode']}) #{data['errmsg']}"
|
87
|
+
super data
|
88
|
+
end
|
89
|
+
|
90
|
+
def token_expired?
|
91
|
+
# 42001: access_token timeout
|
92
|
+
# 40014: invalid access_token
|
93
|
+
# 40001, invalid credential, access_token is invalid or not latest hint
|
94
|
+
[42001, 40014, 40001].include?(errcode)
|
95
|
+
end
|
96
|
+
|
97
|
+
def success?
|
98
|
+
errcode == SUCCESS_CODE
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Wework
|
2
|
+
module Token
|
3
|
+
class RedisStore < Store
|
4
|
+
|
5
|
+
def initialize(agent)
|
6
|
+
raise RedisNotConfigException if redis.nil?
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def access_token
|
11
|
+
super
|
12
|
+
redis.hget(key, "access_token")
|
13
|
+
end
|
14
|
+
|
15
|
+
def expired?
|
16
|
+
redis.hvals(key).empty?
|
17
|
+
end
|
18
|
+
|
19
|
+
def refresh_token
|
20
|
+
result = super
|
21
|
+
|
22
|
+
expires_at = Time.now.to_i + result['expires_in'].to_i - 100
|
23
|
+
redis.hmset(
|
24
|
+
key,
|
25
|
+
"access_token", result['access_token'],
|
26
|
+
"expires_at", expires_at
|
27
|
+
)
|
28
|
+
|
29
|
+
redis.expireat(key, expires_at)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def redis
|
35
|
+
Wework.redis
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Wework
|
2
|
+
module Token
|
3
|
+
class Store
|
4
|
+
|
5
|
+
attr_accessor :agent
|
6
|
+
|
7
|
+
def initialize(agent)
|
8
|
+
@agent = agent
|
9
|
+
end
|
10
|
+
|
11
|
+
def access_token
|
12
|
+
refresh_token if expired?
|
13
|
+
end
|
14
|
+
|
15
|
+
def expired?
|
16
|
+
raise NotImplementedError, "Subclasses must implement a token_expired? method"
|
17
|
+
end
|
18
|
+
|
19
|
+
def refresh_token
|
20
|
+
agent.request.get 'gettoken', params: {corpid: agent.corp_id, corpsecret: agent.agent_secret}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def key
|
26
|
+
@key ||= Digest::MD5.hexdigest("#{ACCESS_TOKEN_PREFIX}_#{agent.agent_id}_#{agent.agent_secret}")
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/wework/version.rb
CHANGED
data/lib/wework.rb
CHANGED
@@ -1,5 +1,30 @@
|
|
1
|
-
require
|
1
|
+
require 'redis'
|
2
|
+
require 'active_support/all'
|
3
|
+
#require 'active_support/core_ext/object/blank'
|
4
|
+
|
5
|
+
Dir["#{File.dirname(__FILE__)}/wework/*.rb"].each do |path|
|
6
|
+
require path
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'wework/api/base'
|
10
|
+
require 'wework/api/agent'
|
11
|
+
require 'wework/api/contact'
|
2
12
|
|
3
13
|
module Wework
|
4
|
-
|
14
|
+
API_ENDPOINT = 'https://qyapi.weixin.qq.com/cgi-bin/'.freeze
|
15
|
+
ACCESS_TOKEN_PREFIX = 'WEWORK'.freeze
|
16
|
+
CONTACT_AGENT_ID = 'CONTACT'.freeze
|
17
|
+
HTTP_OK_STATUS = [200, 201].freeze
|
18
|
+
SUCCESS_CODE = 0
|
19
|
+
|
20
|
+
# Exceptions
|
21
|
+
class RedisNotConfigException < RuntimeError; end
|
22
|
+
class AccessTokenExpiredError < RuntimeError; end
|
23
|
+
class ResponseError < StandardError
|
24
|
+
attr_reader :error_code
|
25
|
+
def initialize(errcode, errmsg='')
|
26
|
+
@error_code = errcode
|
27
|
+
super "(#{error_code}) #{errmsg}"
|
28
|
+
end
|
29
|
+
end
|
5
30
|
end
|
data/wework.gemspec
CHANGED
@@ -20,7 +20,11 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.add_dependency 'http', '>= 1.0.4', '< 3'
|
24
|
+
spec.add_dependency 'activesupport', '~> 5.0'
|
25
|
+
spec.add_dependency 'redis', '~>3.2'
|
26
|
+
|
23
27
|
spec.add_development_dependency "bundler", "~> 1.13"
|
24
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
-
spec.add_development_dependency "minitest", "~> 5.
|
29
|
+
spec.add_development_dependency "minitest", "~> 5.10"
|
26
30
|
end
|
metadata
CHANGED
@@ -1,15 +1,63 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wework
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- seandong
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: http
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.4
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '3'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.0.4
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activesupport
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '5.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '5.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: redis
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.2'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.2'
|
13
61
|
- !ruby/object:Gem::Dependency
|
14
62
|
name: bundler
|
15
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -44,14 +92,14 @@ dependencies:
|
|
44
92
|
requirements:
|
45
93
|
- - "~>"
|
46
94
|
- !ruby/object:Gem::Version
|
47
|
-
version: '5.
|
95
|
+
version: '5.10'
|
48
96
|
type: :development
|
49
97
|
prerelease: false
|
50
98
|
version_requirements: !ruby/object:Gem::Requirement
|
51
99
|
requirements:
|
52
100
|
- - "~>"
|
53
101
|
- !ruby/object:Gem::Version
|
54
|
-
version: '5.
|
102
|
+
version: '5.10'
|
55
103
|
description: Ruby API wrapper for work wechat.
|
56
104
|
email:
|
57
105
|
- sindon@gmail.com
|
@@ -69,6 +117,14 @@ files:
|
|
69
117
|
- bin/console
|
70
118
|
- bin/setup
|
71
119
|
- lib/wework.rb
|
120
|
+
- lib/wework/api/agent.rb
|
121
|
+
- lib/wework/api/base.rb
|
122
|
+
- lib/wework/api/contact.rb
|
123
|
+
- lib/wework/config.rb
|
124
|
+
- lib/wework/engine.rb
|
125
|
+
- lib/wework/request.rb
|
126
|
+
- lib/wework/token/redis_store.rb
|
127
|
+
- lib/wework/token/store.rb
|
72
128
|
- lib/wework/version.rb
|
73
129
|
- wework.gemspec
|
74
130
|
homepage: https://github.com/seandong/wework
|