freshdesk_api 0.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 +7 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +97 -0
- data/Rakefile +17 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/freshdesk_api.gemspec +33 -0
- data/lib/freshdesk_api.rb +3 -0
- data/lib/freshdesk_api/actions.rb +194 -0
- data/lib/freshdesk_api/client.rb +113 -0
- data/lib/freshdesk_api/collection.rb +89 -0
- data/lib/freshdesk_api/configuration.rb +51 -0
- data/lib/freshdesk_api/error.rb +23 -0
- data/lib/freshdesk_api/helpers.rb +16 -0
- data/lib/freshdesk_api/resource.rb +80 -0
- data/lib/freshdesk_api/resources/solution_article.rb +31 -0
- data/lib/freshdesk_api/resources/solution_category.rb +29 -0
- data/lib/freshdesk_api/resources/solution_folder.rb +31 -0
- data/lib/freshdesk_api/version.rb +3 -0
- metadata +193 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: cba704113b86c43fdeab78e8cd4361dc661d1092
|
|
4
|
+
data.tar.gz: e839a871d07cd30b70810f1b072f1dce280bf7ea
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: dcb1084b51ccacb63daf5ea6389e2f950c0b054b1e68dd32cb9ce035a9d15f67e986b957401abc0131dde69df3bb75b812866ca67e674a57761f70a039c0b279
|
|
7
|
+
data.tar.gz: 1c02e24825451683e430ad138607db79412d6ec4fae42294a7b703272c8b1593aaba4258dfe857371241fc7cad6187516d22415e63e07e26da5bff4ad61600d6
|
data/.rspec
ADDED
data/.ruby-gemset
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
freshdesk_api
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby
|
data/Gemfile
ADDED
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 Anton Maminov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
data/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Freshdesk API Client
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
A Ruby API client that interfaces with freshdesk.com web service. This client supports regular CRUD operation.
|
|
5
|
+
|
|
6
|
+
Please see [API documentation](http://freshdesk.com/api) for more information.
|
|
7
|
+
|
|
8
|
+
As of now,it supports the following:
|
|
9
|
+
|
|
10
|
+
* Solution Category
|
|
11
|
+
* Solution Folder
|
|
12
|
+
* Solution Article
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
To experiment with that code, run `bin/console` for an interactive prompt.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
The Freshdesk API client can be installd using Bundler or Rubygems.
|
|
20
|
+
|
|
21
|
+
### Bundler
|
|
22
|
+
|
|
23
|
+
Add this line to your application's Gemfile:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
gem 'freshdesk_api'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
And then execute:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
$ bundle
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Rubygems
|
|
36
|
+
|
|
37
|
+
Or install it yourself as:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
$ gem install freshdesk_api
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Configuration
|
|
44
|
+
|
|
45
|
+
Configuration is done through a block returning an instance of `FreshdeskAPI::Client`. The block is mandatory and if not passed, an `ArgumentError` will be thrown.
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
require 'freshdesk_api'
|
|
49
|
+
|
|
50
|
+
client = FreshdeskAPI::Client.new do |config|
|
|
51
|
+
config.base_url = '<- your-freshdesk-url ->' # e.g. 'https://mydesk.freshdesk.com'
|
|
52
|
+
config.username = 'login.email@freshdesk.com'
|
|
53
|
+
config.password = 'your freshdesk password'
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Note: This FreshdeskAPI API client only supports basic authentication at the moment.
|
|
58
|
+
|
|
59
|
+
## Usage
|
|
60
|
+
|
|
61
|
+
The result of configuration is an instance of `FreshdeskAPI::Client` which can then be used in two different methods.
|
|
62
|
+
|
|
63
|
+
One way to use the client is to pass it in as an argument to individual classes.
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
FreshdeskAPI::SolutionCategory.create!(client, name: 'API', description: 'API related documents')
|
|
67
|
+
FreshdeskAPI::SolutionArticle.find!(client, id: 1, 1: category_id, folder_id: 1)
|
|
68
|
+
FreshdeskAPI::SolutionFolder.update!(client, id: 1, category_id: 1, name: 'Folder API')
|
|
69
|
+
FreshdeskAPI::SolutionArticle.destroy!(client, id: 1, category_id: 1, folder_id: 1)
|
|
70
|
+
```
|
|
71
|
+
Another way is to use the instance methods under client.
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
categories = client.solution_categories
|
|
75
|
+
category = categories.create!(name: 'API', description: 'API related documents')
|
|
76
|
+
category.update!(name: 'API v2', description: 'API related documents v2')
|
|
77
|
+
category = categories.find!(id: 1)
|
|
78
|
+
category.destroy!
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The methods under `FreshdeskAPI::Client` (such as `.solution_categories`) return an instance of `FreshdeskAPI::Collection` a lazy-loaded list of that resource.
|
|
82
|
+
|
|
83
|
+
Actual requests may not be sent until an explicit `FreshdeskAPI::Collection#all!`.
|
|
84
|
+
|
|
85
|
+
## Development
|
|
86
|
+
|
|
87
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
88
|
+
|
|
89
|
+
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` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
90
|
+
|
|
91
|
+
## Contributing
|
|
92
|
+
|
|
93
|
+
1. Fork it ( https://github.com/mamantoha/freshdesk_api_client_rb/fork )
|
|
94
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
95
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
96
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
97
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'rake/testtask'
|
|
2
|
+
require "bundler/gem_tasks"
|
|
3
|
+
|
|
4
|
+
begin
|
|
5
|
+
require 'rspec/core/rake_task'
|
|
6
|
+
rescue LoadError
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
if defined?(RSpec)
|
|
10
|
+
desc "Run specs"
|
|
11
|
+
RSpec::Core::RakeTask.new("spec") do |t|
|
|
12
|
+
t.pattern = "spec/core/**/*_spec.rb"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
desc 'Default: run specs.'
|
|
16
|
+
task default: 'spec'
|
|
17
|
+
end
|
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "freshdesk_api"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'freshdesk_api/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "freshdesk_api"
|
|
8
|
+
spec.version = FreshdeskAPI::VERSION
|
|
9
|
+
spec.authors = ["Anton Maminov"]
|
|
10
|
+
spec.email = ["anton.linux@gmail.com"]
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{Freshdesk REST API Client}
|
|
13
|
+
spec.description = %q{Ruby wrapper for the REST API at http://freshdesk.com. Documentation at http://freshdesk.com/api.}
|
|
14
|
+
spec.homepage = "https://github.com/mamantoha/freshdesk_api_client_rb"
|
|
15
|
+
|
|
16
|
+
spec.required_ruby_version = ">= 2.0.0"
|
|
17
|
+
|
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
19
|
+
spec.bindir = "exe"
|
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
21
|
+
spec.require_paths = ["lib"]
|
|
22
|
+
|
|
23
|
+
spec.add_runtime_dependency "activesupport"
|
|
24
|
+
spec.add_runtime_dependency "rest-client"
|
|
25
|
+
spec.add_runtime_dependency "multi_json"
|
|
26
|
+
spec.add_runtime_dependency "deep_merge"
|
|
27
|
+
|
|
28
|
+
spec.add_development_dependency "byebug"
|
|
29
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
|
30
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
31
|
+
spec.add_development_dependency "rspec"
|
|
32
|
+
spec.add_development_dependency "webmock"
|
|
33
|
+
end
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
module FreshdeskAPI
|
|
2
|
+
|
|
3
|
+
module ResponseHandler
|
|
4
|
+
def handle_response(response)
|
|
5
|
+
response = MultiJson.load(response, symbolize_keys: true)
|
|
6
|
+
if response[response_namespace]
|
|
7
|
+
@attributes.replace(@attributes.deep_merge(response[response_namespace]))
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module Read
|
|
13
|
+
def self.extended(klass)
|
|
14
|
+
klass.send(:include, ResponseHandler)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Finds a resource by an id and any options passed in
|
|
18
|
+
# @param [Client] client The {Client} object to be used
|
|
19
|
+
# @param [Hash] option Any additional GET parameters to be added
|
|
20
|
+
def find!(client, options = {})
|
|
21
|
+
@client = client # so we can use client.logger in rescue
|
|
22
|
+
raise ArgumentError, 'No :id given' unless options[:id]
|
|
23
|
+
|
|
24
|
+
path = api_url(options) + "/#{options[:id]}"
|
|
25
|
+
|
|
26
|
+
response = client.make_request!(path, :get)
|
|
27
|
+
|
|
28
|
+
new(@client).tap do |resource|
|
|
29
|
+
resource.attributes.merge!(options)
|
|
30
|
+
resource.handle_response(response)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Finds, returning nil if it fails
|
|
35
|
+
def find(client, options = {}, &block)
|
|
36
|
+
find!(client, options, &block)
|
|
37
|
+
rescue FreshdeskAPI::Error::ClientError => e
|
|
38
|
+
nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module Save
|
|
43
|
+
include ResponseHandler
|
|
44
|
+
|
|
45
|
+
# If this resource hasn't been deleted, then create or save it.
|
|
46
|
+
# Executes a POST if it is a {Data#new_record?}, otherwise a PUT.
|
|
47
|
+
# @return [Resource] created or updated object
|
|
48
|
+
def save!(options = {})
|
|
49
|
+
return false if respond_to?(:destroyed?) && destroyed?
|
|
50
|
+
|
|
51
|
+
options = { request_namespace => attributes }
|
|
52
|
+
|
|
53
|
+
if new_record?
|
|
54
|
+
method = :post
|
|
55
|
+
req_path = api_url(options)
|
|
56
|
+
else
|
|
57
|
+
method = :put
|
|
58
|
+
req_path = api_url(options) + "/#{id}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
response = @client.make_request!(req_path, method, options)
|
|
62
|
+
|
|
63
|
+
handle_response(response)
|
|
64
|
+
return self
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Saves, returning false if it fails and attachibg the errors
|
|
68
|
+
def save(options = {}, &block)
|
|
69
|
+
save!(options, &block)
|
|
70
|
+
rescue FreshdeskAPI::Error::RecordInvalid => e
|
|
71
|
+
@errors = e.errors
|
|
72
|
+
false
|
|
73
|
+
rescue FreshdeskAPI::Error::ClientError
|
|
74
|
+
false
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
module Create
|
|
79
|
+
include Save
|
|
80
|
+
|
|
81
|
+
def self.included(base)
|
|
82
|
+
base.extend(ClassMethods)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
module ClassMethods
|
|
86
|
+
# Create a resource given the attributes passed in.
|
|
87
|
+
# @param [Client] client The {Client} object to be used
|
|
88
|
+
# @param [Hash] attributes The attributes to create.
|
|
89
|
+
def create!(client, attributes = {}, &block)
|
|
90
|
+
response = nil
|
|
91
|
+
new(client, attributes).tap do |resource|
|
|
92
|
+
response = resource.save!(&block)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
response
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Create a resource, returning nil if it fails
|
|
99
|
+
def create(client, attributes = {}, &block)
|
|
100
|
+
create!(client, attributes, &block)
|
|
101
|
+
rescue FreshdeskAPI::Error::ClientError
|
|
102
|
+
nil
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
module Update
|
|
108
|
+
include Save
|
|
109
|
+
|
|
110
|
+
def self.included(base)
|
|
111
|
+
base.extend(ClassMethods)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def update!(attributes = {})
|
|
115
|
+
self.attributes.merge!(attributes)
|
|
116
|
+
self.save!
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def update(attributes = {})
|
|
120
|
+
update!(attributes = {})
|
|
121
|
+
rescue FreshdeskAPI::Error::ClientError
|
|
122
|
+
false
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
module ClassMethods
|
|
126
|
+
# Updates a resource given the id passed in
|
|
127
|
+
# @params [Client] client The {Client} object to be used
|
|
128
|
+
# @param [Hash] attributes The attributes to update. Default to {}
|
|
129
|
+
def update!(client, attributes = {}, &block)
|
|
130
|
+
response = nil
|
|
131
|
+
new(client, id: attributes.delete(:id)).tap do |resource|
|
|
132
|
+
resource.attributes.merge!(attributes)
|
|
133
|
+
response = resource.save!(&block)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
response
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Updates a resource, returning nil if it fails
|
|
140
|
+
def update(client, attributes = {}, &block)
|
|
141
|
+
update!(client, attributes, &block)
|
|
142
|
+
rescue FreshdeskAPI::Error::ClientError
|
|
143
|
+
false
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
module Destroy
|
|
149
|
+
def self.included(klass)
|
|
150
|
+
klass.extend(ClassMethods)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Has this object been deleted?
|
|
154
|
+
def destroyed?
|
|
155
|
+
@destroyed ||= false
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# If this resource hasn't already been deleted, then do so.
|
|
159
|
+
# instance method
|
|
160
|
+
# @return [Boolean] Success?
|
|
161
|
+
def destroy!
|
|
162
|
+
return false if destroyed? || new_record?
|
|
163
|
+
|
|
164
|
+
path = api_url + "/#{id}"
|
|
165
|
+
@client.make_request!(path, :delete)
|
|
166
|
+
|
|
167
|
+
@destroyed = true
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
# instance method
|
|
171
|
+
def destroy
|
|
172
|
+
destroy!
|
|
173
|
+
rescue FreshdeskAPI::Error::ClientError
|
|
174
|
+
false
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
module ClassMethods
|
|
178
|
+
# Deteles a resource given the id passed in.
|
|
179
|
+
# @params [Client] client The {Client} object to be used
|
|
180
|
+
# @param [Hash] attributes The optional parameters to pass. Defaults to {}
|
|
181
|
+
def destroy!(client, attributes = {}, &block)
|
|
182
|
+
new(client, attributes).destroy!(&block)
|
|
183
|
+
true
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def destroy(client, attributes = {}, &block)
|
|
187
|
+
destroy!(client, attributes, &block)
|
|
188
|
+
rescue FreshdeskAPI::Error::ClientError
|
|
189
|
+
false
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
end
|
|
194
|
+
end
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require 'active_support/core_ext/string'
|
|
2
|
+
require 'rest_client'
|
|
3
|
+
require 'multi_json'
|
|
4
|
+
require 'deep_merge'
|
|
5
|
+
|
|
6
|
+
require 'freshdesk_api/version'
|
|
7
|
+
require 'freshdesk_api/helpers'
|
|
8
|
+
require 'freshdesk_api/configuration'
|
|
9
|
+
require 'freshdesk_api/resource'
|
|
10
|
+
require 'freshdesk_api/collection'
|
|
11
|
+
require 'freshdesk_api/error'
|
|
12
|
+
|
|
13
|
+
# Supported API resources
|
|
14
|
+
require 'freshdesk_api/resources/solution_category'
|
|
15
|
+
require 'freshdesk_api/resources/solution_folder'
|
|
16
|
+
require 'freshdesk_api/resources/solution_article'
|
|
17
|
+
|
|
18
|
+
module FreshdeskAPI
|
|
19
|
+
# The top-level class that handles configuration and connection to the Freshdesk API.
|
|
20
|
+
class Client
|
|
21
|
+
# @return [Configuration] Config instance
|
|
22
|
+
attr_reader :config
|
|
23
|
+
|
|
24
|
+
# Handles resources such as 'tickets'.
|
|
25
|
+
# @return [Collection] Collection instance for resource
|
|
26
|
+
def method_missing(method, *args, &block)
|
|
27
|
+
method = method.to_s
|
|
28
|
+
method_class = method_as_class(method)
|
|
29
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
|
30
|
+
|
|
31
|
+
FreshdeskAPI::Collection.new(self, method_class, options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Creates a new {Client} instance and yields {#config}.
|
|
35
|
+
#
|
|
36
|
+
# Requires a block to be given.
|
|
37
|
+
#
|
|
38
|
+
# Does basic configuration constraints:
|
|
39
|
+
# * {Configuration#base_url} must be https unless {Configuration#allow_http} is set.
|
|
40
|
+
def initialize
|
|
41
|
+
raise ArgumentError, 'block not given' unless block_given?
|
|
42
|
+
|
|
43
|
+
@config = FreshdeskAPI::Configuration.new
|
|
44
|
+
|
|
45
|
+
yield config
|
|
46
|
+
|
|
47
|
+
check_url
|
|
48
|
+
set_default_logger
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Creates a connection if there is none, otherwise returns the existing connection.
|
|
52
|
+
#
|
|
53
|
+
# @return [RestClient::Resouce] RestClient connection for the client
|
|
54
|
+
def connection
|
|
55
|
+
@connection ||= build_connection
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def make_request!(path, method, options = {})
|
|
59
|
+
response = nil
|
|
60
|
+
connection[path].send(method, options) { |resp, req, result|
|
|
61
|
+
case resp.code
|
|
62
|
+
when 302
|
|
63
|
+
# Connection to the server failed. Please check username/password
|
|
64
|
+
when 404
|
|
65
|
+
raise Error::ResourceNotFound
|
|
66
|
+
when 406
|
|
67
|
+
raise Error::NotAcceptable
|
|
68
|
+
when 400...600
|
|
69
|
+
raise Error::NetworkError
|
|
70
|
+
end
|
|
71
|
+
response = resp
|
|
72
|
+
}
|
|
73
|
+
return response
|
|
74
|
+
rescue Exception => e
|
|
75
|
+
raise Error::ClientError.new(e)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
protected
|
|
79
|
+
|
|
80
|
+
# Called by {#connection} to build a connection.
|
|
81
|
+
#
|
|
82
|
+
# Request logger if logger is not nil
|
|
83
|
+
def build_connection
|
|
84
|
+
RestClient::Resource.new(config.base_url, config.options.merge(auth_options))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# HTTP Basic Authentication credentials
|
|
88
|
+
def auth_options
|
|
89
|
+
{ user: config.username, password: config.password }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def method_as_class(method)
|
|
95
|
+
klass_as_string = ("FreshdeskAPI::" + method.to_s.singularize.classify).constantize
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def check_url
|
|
99
|
+
if !config.allow_http && config.base_url !~ /^https/
|
|
100
|
+
raise ArgumentError, "freshdesk_api is ssl only; url must begin with https://"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def set_default_logger
|
|
105
|
+
if config.logger.nil? || config.logger == true
|
|
106
|
+
require 'logger'
|
|
107
|
+
config.logger = Logger.new($stderr)
|
|
108
|
+
config.logger.level = Logger::WARN
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module FreshdeskAPI
|
|
2
|
+
# Represents a collection of resources
|
|
3
|
+
class Collection
|
|
4
|
+
attr_reader :resources
|
|
5
|
+
attr_reader :resource_class
|
|
6
|
+
|
|
7
|
+
# Creates a new Collection instance. Does not fetch resources.
|
|
8
|
+
# @param [Client] client The {Client} to use.
|
|
9
|
+
# @param [String] resource The resource being collected.
|
|
10
|
+
# @param [Hash] options Any additional options to be passed in.
|
|
11
|
+
def initialize(client, resource, options = {})
|
|
12
|
+
@client = client
|
|
13
|
+
@resource_class = resource
|
|
14
|
+
@resource = resource.resource_name
|
|
15
|
+
@options = options
|
|
16
|
+
|
|
17
|
+
methods = %w{ create find update destroy }
|
|
18
|
+
methods += methods.map { |method| method + '!' }
|
|
19
|
+
methods.each do |deferrable|
|
|
20
|
+
# Passes arguments and the proper path to the resource class method.
|
|
21
|
+
# @param [Hash] options Options or attributes to pass
|
|
22
|
+
define_singleton_method deferrable do |*args|
|
|
23
|
+
unless @resource_class.respond_to?(deferrable)
|
|
24
|
+
raise NoMethodError.new("undefined method \"#{deferrable}\" for #{@resource_class}", deferrable, args)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
|
28
|
+
@resource_class.send(deferrable, @client, opts)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# The API path to this collection
|
|
35
|
+
def path
|
|
36
|
+
@resource_class.api_url(@options)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Execute actual GET from API and load resources into proper class.
|
|
40
|
+
# # @return [Array] All resource
|
|
41
|
+
def all!(options = {})
|
|
42
|
+
@options.merge!(options)
|
|
43
|
+
|
|
44
|
+
response = get_response(path)
|
|
45
|
+
handle_response(response.body)
|
|
46
|
+
|
|
47
|
+
@resources
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def get_response(path)
|
|
51
|
+
@client.connection[path].send(:get, @options)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def handle_response(response_body)
|
|
55
|
+
results = MultiJson.load(response_body, symbolize_keys: true)
|
|
56
|
+
|
|
57
|
+
if results.is_a?(Hash)
|
|
58
|
+
results = FreshdeskAPI::Helpers.deep_hash_access(results, @resource_class.collection_namespace)
|
|
59
|
+
elsif results.is_a?(Array)
|
|
60
|
+
results = results.map { |r| r[@resource_class.collection_namespace.to_sym] }
|
|
61
|
+
else
|
|
62
|
+
raise "Expected a Hash or Array for response body, got #{result.inspect}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
@resources = results.map do |res|
|
|
66
|
+
wrap_resource(res)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def wrap_resource(res)
|
|
71
|
+
@resource_class.new(@client, res)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @private
|
|
75
|
+
def to_s
|
|
76
|
+
if @resources
|
|
77
|
+
@resources.inspect
|
|
78
|
+
else
|
|
79
|
+
inspect = []
|
|
80
|
+
inspect << "options=#{@options.inspect}" if @options.any?
|
|
81
|
+
"#{@resource.singularize} collection [#{inspect.join(',')}]"
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
85
|
+
alias :inspect :to_s
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module FreshdeskAPI
|
|
2
|
+
# Holds the configuration options for the client and connection
|
|
3
|
+
class Configuration
|
|
4
|
+
# @return [String] The basic auth username
|
|
5
|
+
attr_accessor :username
|
|
6
|
+
|
|
7
|
+
# @return [String] The basic auth password.
|
|
8
|
+
attr_accessor :password
|
|
9
|
+
|
|
10
|
+
# @return [String] The basic auth token.
|
|
11
|
+
attr_accessor :apitoken
|
|
12
|
+
|
|
13
|
+
# @return [String] The API url. Must be https unless {#allow_http} is set.
|
|
14
|
+
attr_accessor :base_url
|
|
15
|
+
|
|
16
|
+
# @return [Logger] Logger to use when logging requests.
|
|
17
|
+
attr_accessor :logger
|
|
18
|
+
|
|
19
|
+
# @return [Hash] Client configurations
|
|
20
|
+
attr_accessor :client_options
|
|
21
|
+
|
|
22
|
+
# @return [Boolean] Whether to allow non-HTTPS connections for development purposes.
|
|
23
|
+
attr_accessor :allow_http
|
|
24
|
+
|
|
25
|
+
# :read_timeout and :open_timeout are how long to wait for a response and
|
|
26
|
+
# to open a connection, in seconds. Pass nil to disable the timeout.
|
|
27
|
+
attr_accessor :open_timeout
|
|
28
|
+
attr_accessor :read_timeout
|
|
29
|
+
|
|
30
|
+
def initialize
|
|
31
|
+
@client_options = {}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Sets accept and user_agent headers, and url
|
|
35
|
+
#
|
|
36
|
+
# @return [Hash] RestClient-formatted hash of options.
|
|
37
|
+
def options
|
|
38
|
+
{
|
|
39
|
+
headers: {
|
|
40
|
+
accept: :json,
|
|
41
|
+
content_type: :json,
|
|
42
|
+
accept_encoding: 'gzip ,deflate',
|
|
43
|
+
user_agent: "FreshdeskAPI API #{FreshdeskAPI::VERSION}"
|
|
44
|
+
},
|
|
45
|
+
read_timeout: nil,
|
|
46
|
+
open_timeout: nil,
|
|
47
|
+
base_url: @base_url
|
|
48
|
+
}.merge(client_options)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module FreshdeskAPI
|
|
2
|
+
module Error
|
|
3
|
+
class ClientError < StandardError; end
|
|
4
|
+
|
|
5
|
+
class RecordInvalid < ClientError
|
|
6
|
+
attr_accessor :response, :errors
|
|
7
|
+
|
|
8
|
+
def initialize(response)
|
|
9
|
+
@response = response
|
|
10
|
+
binding.pry
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def to_s
|
|
14
|
+
"#{self.class.name}: #{@errors.to_s}"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class NotAcceptable < ClientError; end
|
|
19
|
+
class ResourceNotFound < ClientError; end
|
|
20
|
+
class NetworkError < ClientError; end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module FreshdeskAPI
|
|
2
|
+
# @private
|
|
3
|
+
module Helpers
|
|
4
|
+
def self.deep_hash_access(hash, path)
|
|
5
|
+
path.split('/').each do |p|
|
|
6
|
+
if p.to_i.to_s == p
|
|
7
|
+
hash = hash[p.to_i]
|
|
8
|
+
else
|
|
9
|
+
hash = hash[p.to_s] || hash[p.to_sym]
|
|
10
|
+
end
|
|
11
|
+
break unless hash
|
|
12
|
+
end
|
|
13
|
+
hash
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'freshdesk_api/actions'
|
|
2
|
+
|
|
3
|
+
module FreshdeskAPI
|
|
4
|
+
# Represents a resource that only holds data.
|
|
5
|
+
class Data
|
|
6
|
+
# @return [Hash] The resource's attributes
|
|
7
|
+
attr_reader :attributes
|
|
8
|
+
|
|
9
|
+
# @return [Array] The last received errors
|
|
10
|
+
attr_accessor :errors
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# The singular resource name taken from the class name (e.g. FreshdeskAPI::SoulutionCategory -> solution_category)
|
|
14
|
+
def singular_resource_name
|
|
15
|
+
@singular_respurce_name ||= to_s.split('::').last.underscore
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The resource name taken from the class name (e.g. FreshdeskAPI::SolutionCatogory -> solution_categories)
|
|
20
|
+
def resource_name
|
|
21
|
+
@resource_name ||= singular_resource_name.pluralize
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Create a new resource instance.
|
|
26
|
+
# @param [Client] client The client to use
|
|
27
|
+
# @param [Hash] attributes The optional attributes that describe the resource
|
|
28
|
+
def initialize(client, attributes = {})
|
|
29
|
+
raise "Expected a Hash for attributes, got #{attributes.inspect}" unless attributes.is_a?(Hash)
|
|
30
|
+
@client = client
|
|
31
|
+
@attributes = attributes
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns the resource id of the object or nil
|
|
35
|
+
def id
|
|
36
|
+
attributes.key?(:id) ? attributes[:id] : nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Has this been object been created server-side? Does this by checking for an id.
|
|
40
|
+
def new_record?
|
|
41
|
+
id.nil?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @private
|
|
45
|
+
def to_s
|
|
46
|
+
"#{self.class.singular_resource_name}: #{attributes.inspect}"
|
|
47
|
+
end
|
|
48
|
+
alias :inspect :to_s
|
|
49
|
+
|
|
50
|
+
# @private
|
|
51
|
+
def inspect
|
|
52
|
+
"#<#{self.class.name} #{@attributes.to_hash.inspect}>"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Compares resources by class and id. If id is nil, then by object_id
|
|
56
|
+
def ==(other)
|
|
57
|
+
return true if other.object_id == self.object_id
|
|
58
|
+
|
|
59
|
+
if other && !other.is_a?(Data)
|
|
60
|
+
warn "Trying to compare #{other.class} to a Resource from #{caller.first}"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if other.is_a?(Data)
|
|
64
|
+
other.id && other.id == id
|
|
65
|
+
else
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Represents a resource that can CRUD (create, read, update, destroy)
|
|
73
|
+
class Resource < Data
|
|
74
|
+
include Create
|
|
75
|
+
extend Read
|
|
76
|
+
include Update
|
|
77
|
+
include Destroy
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'freshdesk_api/resource'
|
|
2
|
+
|
|
3
|
+
module FreshdeskAPI
|
|
4
|
+
class SolutionArticle < Resource
|
|
5
|
+
# Need to specify the category_id and folder_id in url
|
|
6
|
+
|
|
7
|
+
def api_url(options = {})
|
|
8
|
+
"/solution/categories/%{category_id}/folders/%{folder_id}/articles" % attributes
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def request_namespace
|
|
12
|
+
'solution_article'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def response_namespace
|
|
16
|
+
:article
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
def api_url(options = {})
|
|
21
|
+
"/solution/categories/%{category_id}/folders/%{folder_id}/articles" % options
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def collection_namespace
|
|
25
|
+
'folder/articles'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'freshdesk_api/resource'
|
|
2
|
+
|
|
3
|
+
module FreshdeskAPI
|
|
4
|
+
class SolutionCategory < Resource
|
|
5
|
+
def api_url(options = {})
|
|
6
|
+
"/solution/categories"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def request_namespace
|
|
10
|
+
'solution_category'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def response_namespace
|
|
14
|
+
:category
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
def api_url(options = {})
|
|
20
|
+
"/solution/categories"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def collection_namespace
|
|
24
|
+
'category'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'freshdesk_api/resource'
|
|
2
|
+
|
|
3
|
+
module FreshdeskAPI
|
|
4
|
+
class SolutionFolder < Resource
|
|
5
|
+
# Need to specify category_id in url
|
|
6
|
+
|
|
7
|
+
def api_url(options = {})
|
|
8
|
+
"/solution/categories/%{category_id}/folders" % attributes
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def request_namespace
|
|
12
|
+
'solution_folder'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def response_namespace
|
|
16
|
+
:folder
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
def api_url(options = {})
|
|
21
|
+
"/solution/categories/%{category_id}/folders" % options
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def collection_namespace
|
|
25
|
+
'category/folders'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: freshdesk_api
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Anton Maminov
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-05-07 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: activesupport
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rest-client
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ">="
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: multi_json
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: deep_merge
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - ">="
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - ">="
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: byebug
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - ">="
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - ">="
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: bundler
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '1.9'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '1.9'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rake
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '10.0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '10.0'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rspec
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '0'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - ">="
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: webmock
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - ">="
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0'
|
|
139
|
+
description: Ruby wrapper for the REST API at http://freshdesk.com. Documentation
|
|
140
|
+
at http://freshdesk.com/api.
|
|
141
|
+
email:
|
|
142
|
+
- anton.linux@gmail.com
|
|
143
|
+
executables: []
|
|
144
|
+
extensions: []
|
|
145
|
+
extra_rdoc_files: []
|
|
146
|
+
files:
|
|
147
|
+
- ".rspec"
|
|
148
|
+
- ".ruby-gemset"
|
|
149
|
+
- ".ruby-version"
|
|
150
|
+
- Gemfile
|
|
151
|
+
- LICENSE
|
|
152
|
+
- README.md
|
|
153
|
+
- Rakefile
|
|
154
|
+
- bin/console
|
|
155
|
+
- bin/setup
|
|
156
|
+
- freshdesk_api.gemspec
|
|
157
|
+
- lib/freshdesk_api.rb
|
|
158
|
+
- lib/freshdesk_api/actions.rb
|
|
159
|
+
- lib/freshdesk_api/client.rb
|
|
160
|
+
- lib/freshdesk_api/collection.rb
|
|
161
|
+
- lib/freshdesk_api/configuration.rb
|
|
162
|
+
- lib/freshdesk_api/error.rb
|
|
163
|
+
- lib/freshdesk_api/helpers.rb
|
|
164
|
+
- lib/freshdesk_api/resource.rb
|
|
165
|
+
- lib/freshdesk_api/resources/solution_article.rb
|
|
166
|
+
- lib/freshdesk_api/resources/solution_category.rb
|
|
167
|
+
- lib/freshdesk_api/resources/solution_folder.rb
|
|
168
|
+
- lib/freshdesk_api/version.rb
|
|
169
|
+
homepage: https://github.com/mamantoha/freshdesk_api_client_rb
|
|
170
|
+
licenses: []
|
|
171
|
+
metadata: {}
|
|
172
|
+
post_install_message:
|
|
173
|
+
rdoc_options: []
|
|
174
|
+
require_paths:
|
|
175
|
+
- lib
|
|
176
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - ">="
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: 2.0.0
|
|
181
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
182
|
+
requirements:
|
|
183
|
+
- - ">="
|
|
184
|
+
- !ruby/object:Gem::Version
|
|
185
|
+
version: '0'
|
|
186
|
+
requirements: []
|
|
187
|
+
rubyforge_project:
|
|
188
|
+
rubygems_version: 2.4.6
|
|
189
|
+
signing_key:
|
|
190
|
+
specification_version: 4
|
|
191
|
+
summary: Freshdesk REST API Client
|
|
192
|
+
test_files: []
|
|
193
|
+
has_rdoc:
|