girlscout 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/girlscout.rb +2 -1
- data/lib/girlscout/access_token.rb +45 -0
- data/lib/girlscout/concerns/has_resource.rb +3 -7
- data/lib/girlscout/config.rb +4 -3
- data/lib/girlscout/conversation.rb +29 -8
- data/lib/girlscout/customer.rb +4 -10
- data/lib/girlscout/error.rb +1 -1
- data/lib/girlscout/list.rb +7 -1
- data/lib/girlscout/mailbox.rb +5 -35
- data/lib/girlscout/resource.rb +30 -15
- data/lib/girlscout/thread.rb +4 -13
- data/lib/girlscout/user.rb +4 -4
- data/lib/girlscout/version.rb +5 -0
- metadata +17 -15
- data/lib/girlscout/search.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e813cb84802b26b3db2298227a8414b2a14de4a6bec0b5538f6163d2ad6ae1d1
|
4
|
+
data.tar.gz: 5b1737b3c525b5193711848eaddd19056dfff7a77c7ab63fddc3f7b4765d99de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8f78b1ae310eeba7b0ecfc15e075e07edf297e778eb93eeef67ef83792b0e4d7afd304802d2bf4054ed172c851fd611d90fdb24370c0744a42df3226109df35
|
7
|
+
data.tar.gz: f2b7e5ac9f9702f8b26d49aa90592580b9817cba14dbf075b8ba031871da55b03a2e2b8652bdd9f0a51c44ee89054ddaab9569ced48dff732b072306d1720e96
|
data/lib/girlscout.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'excon'
|
4
4
|
|
5
|
+
require 'girlscout/version'
|
5
6
|
require 'girlscout/resource'
|
6
7
|
require 'girlscout/config'
|
7
8
|
|
@@ -10,6 +11,7 @@ require 'girlscout/concerns/has_resource'
|
|
10
11
|
require 'girlscout/object'
|
11
12
|
require 'girlscout/error'
|
12
13
|
|
14
|
+
require 'girlscout/access_token'
|
13
15
|
require 'girlscout/list'
|
14
16
|
require 'girlscout/folder'
|
15
17
|
require 'girlscout/mailbox'
|
@@ -18,4 +20,3 @@ require 'girlscout/attachment'
|
|
18
20
|
require 'girlscout/thread'
|
19
21
|
require 'girlscout/customer'
|
20
22
|
require 'girlscout/user'
|
21
|
-
require 'girlscout/search'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GirlScout
|
4
|
+
class AccessToken
|
5
|
+
include GirlScout::Concerns::HasAttributes
|
6
|
+
|
7
|
+
attr_reader :expires_at
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def refresh
|
11
|
+
response = Excon.post(
|
12
|
+
"#{Config.api_prefix}/oauth2/token",
|
13
|
+
body: credential,
|
14
|
+
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
|
15
|
+
)
|
16
|
+
raise GirlScout::Error, JSON.parse(response.body) if response.status >= 400
|
17
|
+
|
18
|
+
new(JSON.parse(response.body))
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def credential
|
24
|
+
URI.encode_www_form(
|
25
|
+
client_id: Config.client_id,
|
26
|
+
client_secret: Config.client_secret,
|
27
|
+
grant_type: 'client_credentials'
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(attr = {})
|
33
|
+
@attributes = normalize_attributes(attr)
|
34
|
+
@expires_at = Time.now + expires_in
|
35
|
+
end
|
36
|
+
|
37
|
+
def expired?
|
38
|
+
@expires_at.to_i <= Time.now.to_i
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
access_token
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -13,23 +13,19 @@ module GirlScout
|
|
13
13
|
@resource ||= build_resource
|
14
14
|
end
|
15
15
|
|
16
|
-
def resource_path
|
17
|
-
return self.class.resource_path if self.class.respond_to?(:resource_path)
|
18
|
-
@path
|
19
|
-
end
|
20
|
-
|
21
16
|
def resource_url
|
22
|
-
"#{GirlScout::Config.api_prefix}#{@
|
17
|
+
"#{GirlScout::Config.api_prefix}#{@endpoint}"
|
23
18
|
end
|
24
19
|
|
25
20
|
def endpoint(path)
|
26
|
-
@
|
21
|
+
@endpoint = path
|
27
22
|
end
|
28
23
|
|
29
24
|
private
|
30
25
|
|
31
26
|
def build_resource
|
32
27
|
return self.class.resource if self.class.respond_to?(:resource)
|
28
|
+
|
33
29
|
Resource.new(url: resource_url)
|
34
30
|
end
|
35
31
|
end
|
data/lib/girlscout/config.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module GirlScout
|
4
|
-
DEFAULT_API_PREFIX = 'https://api.helpscout.net/
|
4
|
+
DEFAULT_API_PREFIX = 'https://api.helpscout.net/v2'
|
5
5
|
|
6
6
|
class Config
|
7
7
|
class << self
|
8
|
-
attr_accessor :
|
8
|
+
attr_accessor :client_id, :client_secret
|
9
9
|
attr_writer :api_prefix
|
10
10
|
|
11
11
|
def api_prefix
|
@@ -13,7 +13,8 @@ module GirlScout
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def reset!
|
16
|
-
@
|
16
|
+
@client_id = nil
|
17
|
+
@client_secret = nil
|
17
18
|
@api_prefix = DEFAULT_API_PREFIX
|
18
19
|
end
|
19
20
|
end
|
@@ -6,35 +6,56 @@ module GirlScout
|
|
6
6
|
|
7
7
|
class << self
|
8
8
|
def find(id)
|
9
|
-
Conversation.new(resource["/#{id}"].get
|
9
|
+
Conversation.new(resource["/#{id}"].get)
|
10
|
+
end
|
11
|
+
|
12
|
+
def list(query = {})
|
13
|
+
List.new(resource.get(query: query), Conversation)
|
10
14
|
end
|
11
15
|
|
12
16
|
def create(attributes)
|
13
17
|
attributes = attributes.as_json if attributes.respond_to?(:as_json)
|
14
|
-
attributes
|
15
|
-
Conversation.new(resource.post(payload: attributes)['item'])
|
18
|
+
resource.post(payload: attributes)
|
16
19
|
end
|
17
20
|
end
|
18
21
|
|
19
22
|
def customer
|
20
|
-
@customer ||= Customer.new(self['customer'] || {})
|
23
|
+
@customer ||= Customer.new(self['customer'] || self['primary_customer'] || {})
|
21
24
|
end
|
22
25
|
|
23
26
|
def threads
|
24
|
-
|
27
|
+
# `threads` is a number in response but must be an array in request payload.
|
28
|
+
@threads ||= begin
|
29
|
+
if self['threads'].is_a?(Array)
|
30
|
+
(self['threads'] || []).map { |attr| Thread.new(attr) }
|
31
|
+
else
|
32
|
+
List.new(threads_resouce.get, Thread)
|
33
|
+
end
|
34
|
+
end
|
25
35
|
end
|
26
36
|
|
27
37
|
def mailbox
|
28
|
-
@mailbox ||=
|
38
|
+
@mailbox ||= begin
|
39
|
+
if self['mailbox'].is_a?(Hash)
|
40
|
+
Mailbox.new(self['mailbox'] || {})
|
41
|
+
else
|
42
|
+
Mailbox.new(Resource.new(url: self['Links']['mailbox']['href']).get)
|
43
|
+
end
|
44
|
+
end
|
29
45
|
end
|
30
46
|
|
31
47
|
def as_json
|
32
|
-
|
33
|
-
json = super.dup
|
48
|
+
json = super
|
34
49
|
json['customer'] = customer.as_json if key?('customer')
|
35
50
|
json['threads'] = threads.map(&:as_json) if key?('threads')
|
36
51
|
json['mailbox'] = mailbox.as_json if key?('mailbox')
|
37
52
|
json
|
38
53
|
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def threads_resouce
|
58
|
+
@threads_resouce ||= Resource.new(url: self['Links']['threads']['href'])
|
59
|
+
end
|
39
60
|
end
|
40
61
|
end
|
data/lib/girlscout/customer.rb
CHANGED
@@ -5,19 +5,13 @@ module GirlScout
|
|
5
5
|
endpoint '/customers'
|
6
6
|
|
7
7
|
class << self
|
8
|
-
def all
|
9
|
-
List.new(resource.get, Customer)
|
10
|
-
end
|
11
|
-
|
12
8
|
def find(id)
|
13
|
-
Customer.new(resource["/#{id}"].get
|
9
|
+
Customer.new(resource["/#{id}"].get)
|
14
10
|
end
|
15
|
-
end
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
json
|
12
|
+
def list(query = {})
|
13
|
+
List.new(resource.get(query: query), Customer)
|
14
|
+
end
|
21
15
|
end
|
22
16
|
end
|
23
17
|
end
|
data/lib/girlscout/error.rb
CHANGED
data/lib/girlscout/list.rb
CHANGED
@@ -14,7 +14,7 @@ module GirlScout
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def items
|
17
|
-
@items ||= (
|
17
|
+
@items ||= (embedded_items || []).map do |attr|
|
18
18
|
@item_class.new(attr)
|
19
19
|
end
|
20
20
|
end
|
@@ -26,5 +26,11 @@ module GirlScout
|
|
26
26
|
def each(&block)
|
27
27
|
items.each(&block)
|
28
28
|
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def embedded_items
|
33
|
+
@embedded_items ||= @attributes['Embedded'].values[0]
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
data/lib/girlscout/mailbox.rb
CHANGED
@@ -5,47 +5,17 @@ module GirlScout
|
|
5
5
|
endpoint '/mailboxes'
|
6
6
|
|
7
7
|
class << self
|
8
|
-
def
|
9
|
-
|
8
|
+
def find(id)
|
9
|
+
Mailbox.new(resource["/#{id}"].get)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def list
|
13
|
+
List.new(resource.get, Mailbox)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def folders
|
18
|
-
@folders ||= List.new(
|
19
|
-
end
|
20
|
-
|
21
|
-
def conversations
|
22
|
-
@conversations ||= List.new(conversation_resource.get, Conversation)
|
23
|
-
end
|
24
|
-
|
25
|
-
def users
|
26
|
-
@users ||= List.new(user_resource.get, User)
|
27
|
-
end
|
28
|
-
|
29
|
-
def customers
|
30
|
-
@customers ||= List.new(customer_resource.get, Customer)
|
31
|
-
end
|
32
|
-
|
33
|
-
protected
|
34
|
-
|
35
|
-
def folder_resource
|
36
|
-
@folder_resource ||= resource["/#{id}/folders"]
|
37
|
-
end
|
38
|
-
|
39
|
-
def conversation_resource
|
40
|
-
@conversation_resource ||= resource["/#{id}/conversations"]
|
41
|
-
end
|
42
|
-
|
43
|
-
def user_resource
|
44
|
-
@user_resource ||= resource["/#{id}/users"]
|
45
|
-
end
|
46
|
-
|
47
|
-
def customer_resource
|
48
|
-
@customer_resource ||= resource["/#{id}/customers"]
|
18
|
+
@folders ||= List.new(resource["/#{id}/folders"].get, Folder)
|
49
19
|
end
|
50
20
|
end
|
51
21
|
end
|
data/lib/girlscout/resource.rb
CHANGED
@@ -6,12 +6,11 @@ module GirlScout
|
|
6
6
|
class Resource
|
7
7
|
METHODS = %i[get put post patch delete].freeze
|
8
8
|
|
9
|
+
attr_accessor :url
|
10
|
+
|
9
11
|
def initialize(url: '')
|
10
12
|
@url = url
|
11
|
-
|
12
|
-
|
13
|
-
def url
|
14
|
-
"#{@url}.json"
|
13
|
+
@access_token = AccessToken.refresh
|
15
14
|
end
|
16
15
|
|
17
16
|
def [](path)
|
@@ -21,25 +20,41 @@ module GirlScout
|
|
21
20
|
METHODS.each do |method|
|
22
21
|
define_method(method) do |payload: nil, query: nil|
|
23
22
|
options = { method: method }
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
options[:query] = query if query
|
23
|
+
options[:headers] = {
|
24
|
+
'Content-Type' => 'application/json; charset=UTF-8',
|
25
|
+
'Authorization' => "Bearer #{access_token}"
|
26
|
+
}
|
27
|
+
options[:body] = JSON.generate(payload) if payload
|
28
|
+
options[:query] = URI.encode_www_form(query) if query
|
30
29
|
|
31
30
|
request(options)
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
34
|
+
private
|
35
|
+
|
36
|
+
def access_token
|
37
|
+
@access_token = AccessToken.refresh if @access_token&.expired?
|
38
|
+
@access_token
|
39
|
+
end
|
40
|
+
|
35
41
|
def request(options = {})
|
36
|
-
|
37
|
-
response
|
38
|
-
|
39
|
-
|
42
|
+
response = Excon.new(@url).request(options)
|
43
|
+
case response.status
|
44
|
+
when 200
|
45
|
+
JSON.parse(response.body)
|
46
|
+
when 201
|
47
|
+
response.headers['Resource-ID']
|
48
|
+
else
|
49
|
+
raise GirlScout::Error, message: error_message(response.body), code: response.status
|
40
50
|
end
|
51
|
+
end
|
41
52
|
|
42
|
-
|
53
|
+
def error_message(body)
|
54
|
+
body = JSON.parse(body)
|
55
|
+
body['message'] || body['error_description']
|
56
|
+
rescue JSON::ParserError
|
57
|
+
body
|
43
58
|
end
|
44
59
|
end
|
45
60
|
end
|
data/lib/girlscout/thread.rb
CHANGED
@@ -3,27 +3,18 @@
|
|
3
3
|
module GirlScout
|
4
4
|
class Thread < GirlScout::Object
|
5
5
|
def attachments
|
6
|
-
@attachments ||= (self['attachments'] || []).map do |attr|
|
6
|
+
@attachments ||= (self['Embedded']['attachments'] || []).map do |attr|
|
7
7
|
Attachment.new(attr)
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
@
|
13
|
-
return @created_by if @created_by
|
14
|
-
|
15
|
-
attr = @attributes['createdBy']
|
16
|
-
creator_type = begin
|
17
|
-
"GirlScout::#{attr['type'].capitalize}".constantize
|
18
|
-
rescue StandardError
|
19
|
-
User
|
20
|
-
end
|
21
|
-
@created_by ||= creator_type.new(attr)
|
11
|
+
def customer
|
12
|
+
@customer ||= Customer.new(self['customer'] || {})
|
22
13
|
end
|
23
14
|
|
24
15
|
def as_json
|
25
16
|
json = super
|
26
|
-
json['
|
17
|
+
json['customer'] = customer.as_json if key?('customer')
|
27
18
|
json
|
28
19
|
end
|
29
20
|
end
|
data/lib/girlscout/user.rb
CHANGED
@@ -5,12 +5,12 @@ module GirlScout
|
|
5
5
|
endpoint '/users'
|
6
6
|
|
7
7
|
class << self
|
8
|
-
def
|
9
|
-
|
8
|
+
def find(id)
|
9
|
+
User.new(resource["/#{id}"].get)
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
12
|
+
def list(query = {})
|
13
|
+
List.new(resource.get(query: query), User)
|
14
14
|
end
|
15
15
|
|
16
16
|
def me
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: girlscout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Phureewat Aphibansri <phureewat@omise.co>
|
8
|
+
- Chakrit Wichian <chakrit@omise.co>
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2019-07-05 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: excon
|
@@ -30,28 +31,28 @@ dependencies:
|
|
30
31
|
requirements:
|
31
32
|
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
34
|
+
version: '1.8'
|
34
35
|
type: :runtime
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
39
|
- - ">="
|
39
40
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
41
|
+
version: '1.8'
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
43
|
name: bundler
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
46
|
- - "~>"
|
46
47
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
48
|
+
version: '2.0'
|
48
49
|
type: :development
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
53
|
- - "~>"
|
53
54
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
+
version: '2.0'
|
55
56
|
- !ruby/object:Gem::Dependency
|
56
57
|
name: guard
|
57
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,21 +171,22 @@ dependencies:
|
|
170
171
|
requirements:
|
171
172
|
- - "~>"
|
172
173
|
- !ruby/object:Gem::Version
|
173
|
-
version: '
|
174
|
+
version: '5.0'
|
174
175
|
type: :development
|
175
176
|
prerelease: false
|
176
177
|
version_requirements: !ruby/object:Gem::Requirement
|
177
178
|
requirements:
|
178
179
|
- - "~>"
|
179
180
|
- !ruby/object:Gem::Version
|
180
|
-
version: '
|
181
|
-
description: Provides integration with HelpScout REST API
|
182
|
-
email:
|
181
|
+
version: '5.0'
|
182
|
+
description: Provides integration with HelpScout REST API v2
|
183
|
+
email:
|
183
184
|
executables: []
|
184
185
|
extensions: []
|
185
186
|
extra_rdoc_files: []
|
186
187
|
files:
|
187
188
|
- lib/girlscout.rb
|
189
|
+
- lib/girlscout/access_token.rb
|
188
190
|
- lib/girlscout/attachment.rb
|
189
191
|
- lib/girlscout/concerns/has_attributes.rb
|
190
192
|
- lib/girlscout/concerns/has_resource.rb
|
@@ -197,10 +199,10 @@ files:
|
|
197
199
|
- lib/girlscout/mailbox.rb
|
198
200
|
- lib/girlscout/object.rb
|
199
201
|
- lib/girlscout/resource.rb
|
200
|
-
- lib/girlscout/search.rb
|
201
202
|
- lib/girlscout/thread.rb
|
202
203
|
- lib/girlscout/user.rb
|
203
|
-
|
204
|
+
- lib/girlscout/version.rb
|
205
|
+
homepage: https://github.com/omise/girlscout
|
204
206
|
licenses:
|
205
207
|
- MIT
|
206
208
|
metadata: {}
|
@@ -220,8 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
222
|
version: '0'
|
221
223
|
requirements: []
|
222
224
|
rubyforge_project:
|
223
|
-
rubygems_version: 2.7.
|
225
|
+
rubygems_version: 2.7.6
|
224
226
|
signing_key:
|
225
227
|
specification_version: 4
|
226
|
-
summary: Integrate your support tooling with HelpScout API
|
228
|
+
summary: Integrate your support tooling with HelpScout API v2
|
227
229
|
test_files: []
|
data/lib/girlscout/search.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GirlScout
|
4
|
-
class Search < GirlScout::Object
|
5
|
-
endpoint '/search'
|
6
|
-
|
7
|
-
class << self
|
8
|
-
def conversations(query)
|
9
|
-
search(Conversation, query)
|
10
|
-
end
|
11
|
-
|
12
|
-
def customers(query)
|
13
|
-
search(Customer, query)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def search(klass, query)
|
19
|
-
result = resource[klass.resource_path].get(query: { query: query })
|
20
|
-
List.new(result, klass)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|