help_scout-sdk 1.0.2 → 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 +4 -4
- data/README.md +13 -0
- data/lib/help_scout/api.rb +1 -1
- data/lib/help_scout/api/access_token.rb +28 -22
- data/lib/help_scout/api/access_token/cache.rb +40 -0
- data/lib/help_scout/api/access_token/request.rb +36 -0
- data/lib/help_scout/api/client.rb +9 -8
- data/lib/help_scout/configuration.rb +10 -1
- data/lib/help_scout/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d4c58f9f96b57b2d1bbc0cd69ad741ffa6201244861167992e8212901d491d2
|
4
|
+
data.tar.gz: 055c66adf697283a7836ce6fdb91156cea27ea1cddf0fc6f8b2c05c07ed174a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2058da0b726acce0ef9993b40e827bb2be27f2947c78dfcb57216e51acb3fbcd4969b86a658e621e1bd63c1e6410f291a55cb2aaa03fd446374208e2376eeed0
|
7
|
+
data.tar.gz: 10b8bbca725910b62a0b3120247506d50b8c7e3f34ed50a39ae2ddeb340d9081803b66d2649e9a9b410de4d1af2eb346372f3b96bcb6e7543f38e6f7c790f163
|
data/README.md
CHANGED
@@ -95,6 +95,19 @@ HelpScout::User.list
|
|
95
95
|
user = HelpScout::User.get(id)
|
96
96
|
```
|
97
97
|
|
98
|
+
### Caching Access Tokens
|
99
|
+
|
100
|
+
Since short-lived access tokens aren't likely to be embedded into environment variables, it can be difficult to share them across processes. To work around this, you can configure a `token_cache` (and optional `token_cache_key`) to be used to store and retrieve the token until expiry. In general any object that conforms to the `ActiveSupport::Cache::Store` API should work. For example, using an application's Rails cache:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
HelpScout.configuration.token_cache = Rails.cache
|
104
|
+
HelpScout.configuration.token_cache_key
|
105
|
+
# => 'help_scout_token_cache'
|
106
|
+
HelpScout.configuration.token_cache_key = 'my-own-key'
|
107
|
+
```
|
108
|
+
|
109
|
+
With caching configured, whenever the gem attempts to create an access token, it will first attempt to read a value from the cache using the configured cache key. If it's a hit, the cached values will be used to create a new `AccessToken`. If it's a miss, then the gem will make a request to the Help Scout API to retrieve a new token, writing the token's details to the cache before returning the new token.
|
110
|
+
|
98
111
|
## Development
|
99
112
|
|
100
113
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/help_scout/api.rb
CHANGED
@@ -1,32 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'date'
|
4
|
+
require 'help_scout/api/access_token/cache'
|
5
|
+
require 'help_scout/api/access_token/request'
|
6
|
+
|
3
7
|
module HelpScout
|
4
8
|
class API
|
5
9
|
class AccessToken
|
6
10
|
class << self
|
7
11
|
def create
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
case response.status
|
12
|
-
when 200 then new HelpScout::Response.new(response).body
|
13
|
-
when 429 then raise HelpScout::API::ThrottleLimitReached, response.body&.dig('error')
|
14
|
-
else raise HelpScout::API::InternalError, "unexpected response (status #{response.status})"
|
15
|
-
end
|
16
|
-
end
|
12
|
+
cache = HelpScout::API::AccessToken::Cache.new
|
13
|
+
request = HelpScout::API::AccessToken::Request.new
|
17
14
|
|
18
|
-
|
19
|
-
HelpScout.api.access_token = create
|
15
|
+
cache.configured? ? cache.fetch_token { request.execute } : request.execute
|
20
16
|
end
|
21
17
|
|
22
|
-
|
18
|
+
def refresh!
|
19
|
+
return HelpScout.api.access_token unless HelpScout.access_token.nil? || HelpScout.access_token.stale?
|
23
20
|
|
24
|
-
|
25
|
-
@_token_request_params ||= {
|
26
|
-
grant_type: 'client_credentials',
|
27
|
-
client_id: HelpScout.app_id,
|
28
|
-
client_secret: HelpScout.app_secret
|
29
|
-
}
|
21
|
+
HelpScout.api.access_token = create
|
30
22
|
end
|
31
23
|
end
|
32
24
|
|
@@ -35,10 +27,20 @@ module HelpScout
|
|
35
27
|
|
36
28
|
def initialize(params)
|
37
29
|
@value = params[:access_token]
|
38
|
-
@expires_in = params[:expires_in]
|
39
|
-
return unless @expires_in
|
40
30
|
|
41
|
-
|
31
|
+
if params[:expires_at]
|
32
|
+
@expires_at = DateTime.parse(params[:expires_at].to_s).to_time.utc
|
33
|
+
elsif params[:expires_in]
|
34
|
+
@expires_in = params[:expires_in].to_i
|
35
|
+
@expires_at = (Time.now.utc + @expires_in)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def as_json(*)
|
40
|
+
{
|
41
|
+
access_token: value,
|
42
|
+
expires_at: expires_at
|
43
|
+
}
|
42
44
|
end
|
43
45
|
|
44
46
|
def expired?
|
@@ -48,10 +50,14 @@ module HelpScout
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def invalid?
|
51
|
-
invalid
|
53
|
+
!!invalid # rubocop:disable Style/DoubleNegation
|
52
54
|
end
|
53
55
|
|
54
56
|
def invalidate!
|
57
|
+
cache = HelpScout::API::AccessToken::Cache.new
|
58
|
+
|
59
|
+
cache.delete if cache.configured?
|
60
|
+
|
55
61
|
self.invalid = true
|
56
62
|
end
|
57
63
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HelpScout
|
4
|
+
class API
|
5
|
+
class AccessToken
|
6
|
+
class Cache
|
7
|
+
attr_reader :backend, :key
|
8
|
+
|
9
|
+
def initialize(backend: nil, key: nil)
|
10
|
+
@backend = backend || HelpScout.configuration.token_cache
|
11
|
+
@key = key || HelpScout.configuration.token_cache_key
|
12
|
+
end
|
13
|
+
|
14
|
+
def configured?
|
15
|
+
backend.present? && key.present?
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete
|
19
|
+
backend.delete(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def fetch_token(&token_request)
|
23
|
+
raise ArgumentError, 'A request fallback block is required' unless block_given?
|
24
|
+
|
25
|
+
if (cached_token_json = backend.read(key))
|
26
|
+
AccessToken.new(JSON.parse(cached_token_json, symbolize_names: true))
|
27
|
+
else
|
28
|
+
token_request.call.tap { |token| write(token) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def write(token)
|
35
|
+
backend.write(key, token.to_json, expires_in: token.expires_in)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HelpScout
|
4
|
+
class API
|
5
|
+
class AccessToken
|
6
|
+
class Request
|
7
|
+
attr_reader :response
|
8
|
+
|
9
|
+
def execute
|
10
|
+
@response = request_token
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def request_token
|
16
|
+
connection = API::Client.new(authorize: false).connection
|
17
|
+
http_response = connection.post('oauth2/token', token_request_params)
|
18
|
+
|
19
|
+
case http_response.status
|
20
|
+
when 200 then AccessToken.new(Response.new(http_response).body)
|
21
|
+
when 429 then raise API::ThrottleLimitReached, http_response.body&.dig('error')
|
22
|
+
else raise API::InternalError, "unexpected response (status #{http_response.status})"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def token_request_params
|
27
|
+
@_token_request_params ||= {
|
28
|
+
grant_type: 'client_credentials',
|
29
|
+
client_id: HelpScout.app_id,
|
30
|
+
client_secret: HelpScout.app_secret
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -10,14 +10,20 @@ module HelpScout
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def connection
|
13
|
-
@_connection ||=
|
14
|
-
|
15
|
-
|
13
|
+
@_connection ||= build_connection.tap do |conn|
|
14
|
+
if authorize?
|
15
|
+
HelpScout::API::AccessToken.refresh!
|
16
|
+
conn.authorization(:Bearer, access_token) if access_token
|
17
|
+
end
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
21
|
private
|
20
22
|
|
23
|
+
def access_token
|
24
|
+
HelpScout.access_token&.value
|
25
|
+
end
|
26
|
+
|
21
27
|
def authorize?
|
22
28
|
authorize
|
23
29
|
end
|
@@ -25,15 +31,10 @@ module HelpScout
|
|
25
31
|
def build_connection
|
26
32
|
Faraday.new(url: BASE_URL) do |conn|
|
27
33
|
conn.request :json
|
28
|
-
conn.authorization(:Bearer, HelpScout.access_token.value) if authorize? && HelpScout.access_token&.value
|
29
34
|
conn.response(:json, content_type: /\bjson$/)
|
30
35
|
conn.adapter(Faraday.default_adapter)
|
31
36
|
end
|
32
37
|
end
|
33
|
-
|
34
|
-
def token_needs_refresh?
|
35
|
-
HelpScout.access_token.nil? || HelpScout.access_token.stale?
|
36
|
-
end
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
@@ -2,13 +2,22 @@
|
|
2
2
|
|
3
3
|
module HelpScout
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :app_id, :app_secret, :default_mailbox
|
5
|
+
attr_accessor :app_id, :app_secret, :default_mailbox, :token_cache
|
6
6
|
attr_reader :access_token
|
7
|
+
attr_writer :token_cache_key
|
8
|
+
|
9
|
+
DEFAULT_CACHE_KEY = 'help_scout_token_cache'
|
7
10
|
|
8
11
|
def access_token=(token_value)
|
9
12
|
return unless token_value
|
10
13
|
|
11
14
|
@access_token = HelpScout::API::AccessToken.new(access_token: token_value)
|
12
15
|
end
|
16
|
+
|
17
|
+
def token_cache_key
|
18
|
+
return @token_cache_key if defined?(@token_cache_key)
|
19
|
+
|
20
|
+
@token_cache_key = DEFAULT_CACHE_KEY
|
21
|
+
end
|
13
22
|
end
|
14
23
|
end
|
data/lib/help_scout/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: help_scout-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TaxJar
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -234,6 +234,8 @@ files:
|
|
234
234
|
- lib/help_scout-sdk.rb
|
235
235
|
- lib/help_scout/api.rb
|
236
236
|
- lib/help_scout/api/access_token.rb
|
237
|
+
- lib/help_scout/api/access_token/cache.rb
|
238
|
+
- lib/help_scout/api/access_token/request.rb
|
237
239
|
- lib/help_scout/api/client.rb
|
238
240
|
- lib/help_scout/attachment.rb
|
239
241
|
- lib/help_scout/base.rb
|