youzan_api 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 41788662990b40cc7eb653c9b57bf2f376d0c9cc
4
+ data.tar.gz: 7f8584abfc657e18e3e23ba1047a27febaf9d262
5
+ SHA512:
6
+ metadata.gz: e614029c04e7ce32293641c1557cccdb7bd4281fd84982d22cfe3a8852fcd6ae2ab1e34b62a20e4edb566d709d622a50a2f95345ae9019c632380c016f14a574
7
+ data.tar.gz: 76b78ec5952e4f3cf6647cd2249692cce0ea3de216c4d83a8a314357145fcfc0066da592869e2caec54893e54d276bf11a8046349e3caf1900867c3184cfbb84
@@ -0,0 +1,102 @@
1
+ require 'byebug'
2
+ require 'json'
3
+ require 'faraday'
4
+ require 'redis'
5
+ require 'dotenv/load'
6
+
7
+ module Youzan
8
+
9
+ CLIENT_ID = ENV['YOUZAN_CLIENT_ID']
10
+ CLIENT_SECRET = ENV['YOUZAN_CLIENT_SECRET']
11
+ KDT_ID = ENV['KDT_ID']
12
+ GRANT_TYPE = 'silent'
13
+
14
+ class InvalidTokenParameter < RuntimeError; end
15
+
16
+ def self.redis
17
+ # You can reuse existing redis connection and remove this method if require
18
+ $redis = Redis.new(host: ENV['REDIS_HOST'], port: 6379, db: 2) # use global redis
19
+ end
20
+
21
+ class TokenClient
22
+
23
+ attr_reader :client, :token_life_in_seconds, :got_token_at
24
+
25
+ def initialize
26
+ @random_generator = Random.new
27
+ end
28
+
29
+ def access_token
30
+ read_token_from_store
31
+ refresh if remain_life_seconds < @random_generator.rand(60..5 * 60)
32
+ @access_token
33
+ end
34
+
35
+ private
36
+
37
+ def connection
38
+ @client ||= Faraday.new
39
+ end
40
+
41
+ def read_token_from_store
42
+ td = read_token
43
+ @token_life_in_seconds = td.fetch('expires_in').to_i
44
+ @got_token_at = td.fetch('got_token_at').to_i
45
+ @access_token = td.fetch('access_token') # return access_token same time
46
+ rescue JSON::ParserError, Errno::ENOENT, KeyError, TypeError
47
+ refresh
48
+ end
49
+
50
+ def read_token
51
+ JSON.parse(Youzan.redis.get(youzan_token_key)) || {}
52
+ end
53
+
54
+ def remain_life_seconds
55
+ token_life_in_seconds - (Time.now.to_i - got_token_at)
56
+ end
57
+
58
+ def refresh
59
+ data = fetch_access_token
60
+ write_token_to_store(data)
61
+ read_token_from_store
62
+ end
63
+
64
+ def fetch_access_token
65
+ res = generate_oauth_token
66
+ JSON.parse(res.body)
67
+ end
68
+
69
+ def generate_oauth_token
70
+ connection.post do |req|
71
+ req.url oauth_token_url
72
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
73
+ req.body = {
74
+ 'client_id' => CLIENT_ID, 'client_secret' => CLIENT_SECRET,
75
+ 'grant_type' => GRANT_TYPE, 'kdt_id' => KDT_ID
76
+ }
77
+ end
78
+ end
79
+
80
+ def oauth_token_url
81
+ Youzan::Api::BASE_API_URL + '/oauth/token'
82
+ end
83
+
84
+ def write_token_to_store(token_hash)
85
+ raise InvalidTokenParameter unless token_hash.is_a?(Hash) && token_hash['access_token']
86
+
87
+ token_hash['got_token_at'.freeze] = Time.now.to_i
88
+ token_hash['expires_in'.freeze] = token_hash.delete('expires_in')
89
+ write_token(token_hash)
90
+ end
91
+
92
+ def write_token(token_hash)
93
+ Youzan.redis.set youzan_token_key, token_hash.to_json
94
+ end
95
+
96
+ def youzan_token_key
97
+ "youzan_token_#{CLIENT_ID}"
98
+ end
99
+
100
+
101
+ end
102
+ end
data/lib/youzan_api.rb ADDED
@@ -0,0 +1,113 @@
1
+ require 'byebug'
2
+ require 'faraday'
3
+ require 'youzan/token_client'
4
+
5
+ module Youzan
6
+ class Api
7
+
8
+ BASE_API_URL = 'https://open.youzan.com'.freeze
9
+
10
+ attr_reader :api_path, :api_version, :request_method, :token_client
11
+
12
+ def initialize(api_path = nil, api_version = nil, request_method = nil)
13
+ @api_path = api_path
14
+ @api_version = api_version
15
+ @request_method = request_method
16
+ end
17
+
18
+ # This is a common method to call the youzan's service API
19
+ # But you need to initialize the `api_path`, `api_version` and `request_method`
20
+ def call_api(options)
21
+ res = call_youzan_api(options)
22
+ parse_response_data(res)
23
+ end
24
+
25
+ # 获取单笔交易的信息
26
+ # API name: youzan.trade.get
27
+ def get_youzan_trade(tid)
28
+ @api_path = 'youzan.trade.get'
29
+ @api_version = '4.0.0'
30
+ @request_method = 'GET'
31
+ res = call_youzan_api(tid: tid)
32
+ parse_response_data(res)
33
+ end
34
+
35
+ # 使用购买虚拟商品获得的码
36
+ # API name: youzan.trade.virtualcode.apply
37
+ #
38
+ # Success Response
39
+ #
40
+ # { "response": { "is_success": true } }
41
+ #
42
+ # Error Response
43
+ #
44
+ # { "error_response": { "code": 101300000, "msg": "订单不存在" } }
45
+ # { "error_response": { "code": 101600002, "msg": "订单已被关闭无法核销" } }
46
+ # { "error_response": { "code": 101600002, "msg": "订单已被核销,重复核销无效" } }
47
+ def apply_virtual_code(code)
48
+ @api_path = 'youzan.trade.virtualcode.apply'
49
+ @api_version = '3.0.0'
50
+ @request_method = 'GET'
51
+ res = call_youzan_api(code: code)
52
+ parse_response_data(res)
53
+ end
54
+
55
+ private
56
+
57
+
58
+ def access_token
59
+ @token_client ||= Youzan::TokenClient.new
60
+ @token_client.access_token
61
+ end
62
+
63
+ def connection
64
+ @client ||= Faraday.new
65
+ end
66
+
67
+ def call_youzan_api(param_hash)
68
+ raise InvalidRequestMethod unless %w[GET POST].include?(request_method)
69
+
70
+ param_hash.merge!(access_token: access_token)
71
+
72
+ case request_method
73
+ when 'GET'
74
+ api_via_get_method(param_hash)
75
+ when 'POST'
76
+ api_via_post_method(param_hash)
77
+ end
78
+ end
79
+
80
+ def api_via_get_method(parameters)
81
+ raise InvalidHashParameter unless parameters.is_a?(Hash)
82
+ connection.get do |req|
83
+ req.url api_oauthentry_url
84
+ req.params.merge!(parameters)
85
+ end
86
+ end
87
+
88
+ def api_via_post_method(parameters)
89
+ raise InvalidHashParameter unless parameters.is_a?(Hash)
90
+ connection.post do |req|
91
+ req.url api_oauthentry_url
92
+ req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
93
+ req.body = parameters
94
+ end
95
+ end
96
+
97
+ def parse_response_data(response)
98
+ JSON.parse(response.body)
99
+ end
100
+
101
+ def api_oauthentry_url
102
+ raise InvokeApiError unless api_path_valid?
103
+ result = /((?:\w+\.)+)(\w+)/.match(api_path).to_a
104
+ api_action = result.last
105
+ api_name = result[-2].chop
106
+ Youzan::Api::BASE_API_URL + '/api/oauthentry/' + "#{api_name}/" + api_version + "/#{api_action}"
107
+ end
108
+
109
+ def api_path_valid?
110
+ api_path =~ /((?:\w+\.)+)(\w+)/
111
+ end
112
+ end
113
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: youzan_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Keon Ye
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2010-09-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: byebug
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 10.0.2
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '10.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 10.0.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: dotenv
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.3'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.3.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.3'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.3.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: redis
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '4.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 4.0.2
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '4.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 4.0.2
73
+ - !ruby/object:Gem::Dependency
74
+ name: faraday
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: 0.15.2
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - "~>"
85
+ - !ruby/object:Gem::Version
86
+ version: 0.15.2
87
+ description: An easy way to call the youzan API's gem
88
+ email: staven.vanderbilt@gmail.com
89
+ executables: []
90
+ extensions: []
91
+ extra_rdoc_files: []
92
+ files:
93
+ - lib/youzan/token_client.rb
94
+ - lib/youzan_api.rb
95
+ homepage: https://github.com/keonjeo/youzan_api
96
+ licenses:
97
+ - MIT
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project:
115
+ rubygems_version: 2.6.14
116
+ signing_key:
117
+ specification_version: 4
118
+ summary: Youzan API
119
+ test_files: []