help-scout-docs 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +56 -0
- data/README.rdoc +62 -0
- data/help_scout_docs.gemspec +33 -0
- data/lib/help_scout_docs.rb +14 -0
- data/lib/help_scout_docs/client.rb +95 -0
- data/lib/help_scout_docs/configurable.rb +78 -0
- data/lib/help_scout_docs/default.rb +55 -0
- data/lib/help_scout_docs/error.rb +5 -0
- data/lib/help_scout_docs/error/authentication_error.rb +6 -0
- data/lib/help_scout_docs/error/configuration_error.rb +6 -0
- data/lib/help_scout_docs/error/errors.rb +6 -0
- data/lib/help_scout_docs/error/options_error.rb +6 -0
- data/lib/help_scout_docs/error/parser_error.rb +6 -0
- data/lib/help_scout_docs/error/resource_not_found_error.rb +6 -0
- data/lib/help_scout_docs/method.rb +54 -0
- data/lib/help_scout_docs/methods/article.rb +45 -0
- data/lib/help_scout_docs/methods/category.rb +16 -0
- data/lib/help_scout_docs/methods/collection.rb +15 -0
- data/lib/help_scout_docs/methods/methods.rb +6 -0
- data/lib/help_scout_docs/methods/site.rb +15 -0
- data/lib/help_scout_docs/response/parse_json.rb +33 -0
- data/lib/help_scout_docs/result.rb +31 -0
- data/lib/help_scout_docs/version.rb +3 -0
- data/spec/cassettes/HelpScoutDocs_Article/_get/should_return_the_article.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Article/_get/when_using_an_id/should_return_the_article.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Article/_list_by_category/should_return_the_list_of_articles_by_category.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Article/_list_by_collection/should_return_the_list_of_articles_by_collection.yml +47 -0
- data/spec/cassettes/HelpScoutDocs_Article/_related/should_return_related_articles.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Article/_revisions/should_return_article_revisions.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Category/_get/should_return_the_category.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Category/_list/should_return_the_list_of_categories.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Client/_get/for_a_missing_request/should_raise_an_exception.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Client/_get/should_return_back_a_result.yml +65 -0
- data/spec/cassettes/HelpScoutDocs_Client/_get/with_invalid_authentication_params/should_raise_an_exception.yml +38 -0
- data/spec/cassettes/HelpScoutDocs_Client/_get/with_valid_params/should_call_the_requested_method.yml +65 -0
- data/spec/cassettes/HelpScoutDocs_Collection/_get/should_return_the_collection.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Collection/_list/should_return_the_list_of_collections.yml +48 -0
- data/spec/cassettes/HelpScoutDocs_Site/_get/should_return_the_site.yml +46 -0
- data/spec/cassettes/HelpScoutDocs_Site/_list/should_return_the_list_of_sites.yml +65 -0
- data/spec/client_spec.rb +78 -0
- data/spec/method_spec.rb +26 -0
- data/spec/methods/article_spec.rb +71 -0
- data/spec/methods/category_spec.rb +24 -0
- data/spec/methods/collection_spec.rb +23 -0
- data/spec/methods/site_spec.rb +23 -0
- data/spec/result_spec.rb +21 -0
- data/spec/spec_helper.rb +18 -0
- metadata +245 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3951d0d359947e296adf2c26f393bfc614b836f8
|
4
|
+
data.tar.gz: f2fe077c8dbc7c6f7cca29ed1cf265de88687723
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7c5582f84ff736fc114dfef007290c6d42baaa4d422759cb8eecaccb82ccbc1f8514925fae19bc482943e51d8b5983505001ae86fd7ae07a5fc10da9dc1721a1
|
7
|
+
data.tar.gz: d093a2b0ddeb3ec679f3791e988c7e5e40144dc182ffe6842539492480b9339b33e1105d92270e7ad1f870077976c753bf99c360a04afa1eb5489331185f04f2
|
data/.rspec
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
help-scout-docs (0.1)
|
5
|
+
faraday_middleware (~> 0.9)
|
6
|
+
json (~> 1.8)
|
7
|
+
log4r (~> 1.1)
|
8
|
+
net-http-persistent (~> 2.9)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
addressable (2.3.6)
|
14
|
+
crack (0.4.2)
|
15
|
+
safe_yaml (~> 1.0.0)
|
16
|
+
diff-lcs (1.2.5)
|
17
|
+
faraday (0.9.0)
|
18
|
+
multipart-post (>= 1.2, < 3)
|
19
|
+
faraday_middleware (0.9.1)
|
20
|
+
faraday (>= 0.7.4, < 0.10)
|
21
|
+
json (1.8.1)
|
22
|
+
json_spec (1.1.2)
|
23
|
+
multi_json (~> 1.0)
|
24
|
+
rspec (>= 2.0, < 4.0)
|
25
|
+
log4r (1.1.10)
|
26
|
+
multi_json (1.10.1)
|
27
|
+
multipart-post (2.0.0)
|
28
|
+
net-http-persistent (2.9.4)
|
29
|
+
rspec (3.0.0)
|
30
|
+
rspec-core (~> 3.0.0)
|
31
|
+
rspec-expectations (~> 3.0.0)
|
32
|
+
rspec-mocks (~> 3.0.0)
|
33
|
+
rspec-core (3.0.4)
|
34
|
+
rspec-support (~> 3.0.0)
|
35
|
+
rspec-expectations (3.0.4)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.0.0)
|
38
|
+
rspec-mocks (3.0.4)
|
39
|
+
rspec-support (~> 3.0.0)
|
40
|
+
rspec-support (3.0.4)
|
41
|
+
safe_yaml (1.0.3)
|
42
|
+
vcr (2.9.2)
|
43
|
+
webmock (1.18.0)
|
44
|
+
addressable (>= 2.3.6)
|
45
|
+
crack (>= 0.3.2)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
help-scout-docs!
|
52
|
+
json_spec (~> 1.1)
|
53
|
+
multi_json (~> 1.8)
|
54
|
+
rspec (~> 3.0)
|
55
|
+
vcr (~> 2.9)
|
56
|
+
webmock (~> 1.15)
|
data/README.rdoc
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
= Help Scout Docs
|
2
|
+
|
3
|
+
This limited (read-only) Help Scout Docs API integration provides functionality for extracting existing documentation content
|
4
|
+
|
5
|
+
See: http://developer.helpscout.net/docs-api/
|
6
|
+
|
7
|
+
== Interfacing with the API directly
|
8
|
+
|
9
|
+
=== Configuration
|
10
|
+
|
11
|
+
In your initializer:
|
12
|
+
|
13
|
+
HelpScoutDocs.configure do |config|
|
14
|
+
config.api_key = "api-key"
|
15
|
+
end
|
16
|
+
|
17
|
+
Or set ENV['HELP_SCOUT_DOCS_API_KEY']
|
18
|
+
|
19
|
+
==== Create client
|
20
|
+
|
21
|
+
client = HelpScoutDocs::Client.new({api_key: "api-key"})
|
22
|
+
|
23
|
+
==== Articles
|
24
|
+
|
25
|
+
Supported methods: get, list (by_category, by_collection), related, revisions, get_revision
|
26
|
+
|
27
|
+
HelpScoutDocs::Article.new.get(1)
|
28
|
+
=> HelpScoutDoc::Result #response=>{article: {id: 1, number: "6239e556e4b0cf4cd3254852"} ...}
|
29
|
+
|
30
|
+
==== Categories
|
31
|
+
|
32
|
+
Supported methods: list, get
|
33
|
+
|
34
|
+
HelpScoutDocs::Category.new.list(1)
|
35
|
+
HelpScoutDocs::Category.new.get(1)
|
36
|
+
|
37
|
+
==== Collections
|
38
|
+
|
39
|
+
Supported methods: list, get
|
40
|
+
|
41
|
+
HelpScoutDocs::Collection.new.list
|
42
|
+
HelpScoutDocs::Collection.new.get(1)
|
43
|
+
|
44
|
+
==== Sites
|
45
|
+
|
46
|
+
Supported methods: list, get
|
47
|
+
|
48
|
+
HelpScoutDocs::Collection.new.list
|
49
|
+
HelpScoutDocs::Collection.new.get(1)
|
50
|
+
|
51
|
+
=== Passing parameters
|
52
|
+
|
53
|
+
Additional parameters are supported for each request (as well as ids in place of numbers), for example:
|
54
|
+
|
55
|
+
HelpScoutDocs::Collection.new.list("123", { siteId: 1, page: 2 })
|
56
|
+
|
57
|
+
|
58
|
+
== TODO
|
59
|
+
|
60
|
+
* Add objects for returned types (Asset, Article, Category, Collection, Site) and collections
|
61
|
+
* Add write methods (create, update etc.)
|
62
|
+
* Handle all error response codes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "help_scout_docs/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "help-scout-docs"
|
7
|
+
s.version = HelpScoutDocs::VERSION
|
8
|
+
s.license = "MIT"
|
9
|
+
s.authors = ["Mark Edmondson"]
|
10
|
+
s.email = ["mark@guestfolio.com"]
|
11
|
+
s.homepage = %q{https://github.com/Guestfolio/help-scout-docs}
|
12
|
+
s.summary = %q{Integration with Help Scout Docs API}
|
13
|
+
s.description = %q{This limited (read-only) Help Scout Docs API integration provides functionality for extracting existing documentation content}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.has_rdoc = true
|
21
|
+
|
22
|
+
s.add_development_dependency "multi_json", "~> 1.8"
|
23
|
+
|
24
|
+
s.add_development_dependency "rspec", "~> 3.0"
|
25
|
+
s.add_development_dependency "webmock", "~> 1.15"
|
26
|
+
s.add_development_dependency "vcr", "~> 2.9"
|
27
|
+
s.add_development_dependency "json_spec", "~> 1.1"
|
28
|
+
|
29
|
+
s.add_runtime_dependency "log4r", "~> 1.1"
|
30
|
+
s.add_runtime_dependency "faraday_middleware", "~> 0.9"
|
31
|
+
s.add_runtime_dependency "json", "~> 1.8"
|
32
|
+
s.add_runtime_dependency "net-http-persistent", "~> 2.9"
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'help_scout_docs/configurable'
|
3
|
+
require 'help_scout_docs/error/errors'
|
4
|
+
require 'help_scout_docs/client'
|
5
|
+
require 'help_scout_docs/methods/methods'
|
6
|
+
require 'help_scout_docs/result'
|
7
|
+
|
8
|
+
module HelpScoutDocs
|
9
|
+
class << self
|
10
|
+
include HelpScoutDocs::Configurable
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
HelpScoutDocs.setup
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module HelpScoutDocs
|
5
|
+
class Client
|
6
|
+
attr_reader :format, :logger
|
7
|
+
|
8
|
+
# Initializes a new Client object
|
9
|
+
#
|
10
|
+
# @param options [Hash]
|
11
|
+
# @return [HelpScoutDocs::Client]
|
12
|
+
#
|
13
|
+
def initialize(options={})
|
14
|
+
@logger = options.delete(:logger) || self.class.logger
|
15
|
+
HelpScoutDocs::Configurable.keys.each do |key|
|
16
|
+
instance_variable_set(:"@#{key}", options[key] || HelpScoutDocs.instance_variable_get(:"@#{key}"))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Perform an HTTP GET request
|
21
|
+
#
|
22
|
+
# @param action [Array]
|
23
|
+
#
|
24
|
+
def get(path=nil, params={})
|
25
|
+
@path ||= path
|
26
|
+
request(:get, params)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Perform an HTTP POST request
|
30
|
+
#
|
31
|
+
# @param action [Array]
|
32
|
+
#
|
33
|
+
def post(path=nil, params={})
|
34
|
+
@path ||= path
|
35
|
+
request(:post, params)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def self.logger
|
41
|
+
Log4r::Logger.new("help_scout_docs::client")
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Boolean]
|
45
|
+
#
|
46
|
+
def path
|
47
|
+
@path || raise(ArgumentError, "Required path missing")
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Boolean]
|
51
|
+
#
|
52
|
+
def authentication_params?
|
53
|
+
authentication_params.values.all?
|
54
|
+
end
|
55
|
+
|
56
|
+
# Add hash of authentication params
|
57
|
+
# @return [Hash]
|
58
|
+
#
|
59
|
+
def authentication_params
|
60
|
+
{
|
61
|
+
api_key: @api_key,
|
62
|
+
api_password: @api_password
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
# Setup the Faraday::Request headers
|
67
|
+
#
|
68
|
+
def headers
|
69
|
+
{
|
70
|
+
ACCEPT: "application/json",
|
71
|
+
ACCEPT_CHARSET: "utf-8"
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def request(method, params={})
|
76
|
+
response = connection.send(method.to_sym, path, params, headers)
|
77
|
+
Result.new(response.body) #.force_encoding('utf-8')
|
78
|
+
rescue JSON::ParserError => e
|
79
|
+
@logger.error "Unable to parse Help Scout Docs API response: #{e.message}"
|
80
|
+
@logger.debug response
|
81
|
+
raise HelpScoutDocs::Error::ParserError.new e.message
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns a Faraday::Connection object
|
85
|
+
#
|
86
|
+
# @return [Faraday::Connection]
|
87
|
+
#
|
88
|
+
def connection
|
89
|
+
raise ArgumentError, "Required authentication params missing" unless authentication_params?
|
90
|
+
@connection ||= Faraday.new(@endpoint, builder: @middleware).tap do |c|
|
91
|
+
c.basic_auth(authentication_params[:api_key], authentication_params[:api_password])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'help_scout_docs/default'
|
3
|
+
|
4
|
+
module HelpScoutDocs
|
5
|
+
module Configurable
|
6
|
+
extend Forwardable
|
7
|
+
attr_accessor :api_key, :api_password, :endpoint, :middleware
|
8
|
+
def_delegator :options, :hash
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
def keys
|
13
|
+
@keys ||= [
|
14
|
+
:api_key,
|
15
|
+
:api_password,
|
16
|
+
:endpoint,
|
17
|
+
:middleware
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
# Convenience method to allow configuration options to be set in a block
|
24
|
+
#
|
25
|
+
def configure
|
26
|
+
yield self
|
27
|
+
validate_credential_type!
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def reset!
|
32
|
+
HelpScoutDocs::Configurable.keys.each do |key|
|
33
|
+
instance_variable_set(:"@#{key}", HelpScoutDocs::Default.options[key])
|
34
|
+
end
|
35
|
+
self
|
36
|
+
end
|
37
|
+
alias setup reset!
|
38
|
+
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
def credentials?
|
42
|
+
credentials.values.all?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# @return [Hash]
|
48
|
+
#
|
49
|
+
def credentials
|
50
|
+
{
|
51
|
+
api_key: @api_key,
|
52
|
+
api_password: @api_password
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [Hash]
|
57
|
+
#
|
58
|
+
def options
|
59
|
+
Hash[HelpScoutDocs::Configurable.keys.map{|key| [key, instance_variable_get(:"@#{key}")]}]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Ensures that all credentials set during configuration are of a
|
63
|
+
# valid type. Valid types are String and Symbol.
|
64
|
+
#
|
65
|
+
# @raise [HelpScoutDocs::Error::ConfigurationError] Error is raised when
|
66
|
+
# supplied twitter credentials are not a String or Symbol.
|
67
|
+
def validate_credential_type!
|
68
|
+
credentials.each do |credential, value|
|
69
|
+
next if value.nil?
|
70
|
+
|
71
|
+
unless value.is_a?(String) || value.is_a?(Symbol)
|
72
|
+
raise(Error::ConfigurationError, "Invalid #{credential} specified: #{value} must be a string or symbol.")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'faraday/request/multipart'
|
3
|
+
require 'help_scout_docs/configurable'
|
4
|
+
require 'help_scout_docs/response/parse_json'
|
5
|
+
require 'help_scout_docs/version'
|
6
|
+
|
7
|
+
module HelpScoutDocs
|
8
|
+
module Default
|
9
|
+
# Faraday.default_adapter = :net_http_persistent
|
10
|
+
|
11
|
+
ENDPOINT = 'https://docsapi.helpscout.net/v1/'
|
12
|
+
MIDDLEWARE = Faraday::Builder.new do |builder|
|
13
|
+
# Encode request params as "www-form-urlencoded"
|
14
|
+
builder.use Faraday::Request::UrlEncoded
|
15
|
+
# Parse JSON response bodies
|
16
|
+
builder.use HelpScoutDocs::Response::ParseJson#, content_type: /\bjson$/
|
17
|
+
# Use Faraday logger
|
18
|
+
builder.use Faraday::Response::Logger if ENV['DEBUG']
|
19
|
+
# Set Faraday's HTTP adapter
|
20
|
+
builder.adapter Faraday.default_adapter
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
|
25
|
+
# @return [Hash]
|
26
|
+
def options
|
27
|
+
Hash[HelpScoutDocs::Configurable.keys.map{|key| [key, send(key)]}]
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String]
|
31
|
+
def api_key
|
32
|
+
ENV['HELP_SCOUT_DOCS_API_KEY']
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [String]
|
36
|
+
def api_password
|
37
|
+
ENV['HELP_SCOUT_DOCS_API_PASSWORD'] || "X"
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [String]
|
41
|
+
def endpoint
|
42
|
+
ENDPOINT
|
43
|
+
end
|
44
|
+
|
45
|
+
# @note Faraday's middleware stack implementation is comparable to that of Rack middleware. The order of middleware is important: the first middleware on the list wraps all others, while the last middleware is the innermost one.
|
46
|
+
# @see https://github.com/technoweenie/faraday#advanced-middleware-usage
|
47
|
+
# @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
|
48
|
+
# @return [Faraday::Builder]
|
49
|
+
def middleware
|
50
|
+
MIDDLEWARE
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
require 'help_scout_docs/error'
|
2
|
+
require 'help_scout_docs/error/authentication_error'
|
3
|
+
require 'help_scout_docs/error/configuration_error'
|
4
|
+
require 'help_scout_docs/error/options_error'
|
5
|
+
require 'help_scout_docs/error/parser_error'
|
6
|
+
require 'help_scout_docs/error/resource_not_found_error'
|