teamsupport 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +12 -0
- data/CHANGELOG.md +11 -0
- data/CONTRIBUTING.md +47 -0
- data/LICENSE.md +26 -0
- data/README.md +132 -0
- data/lib/teamsupport.rb +21 -0
- data/lib/teamsupport/arguments.rb +26 -0
- data/lib/teamsupport/base.rb +173 -0
- data/lib/teamsupport/client.rb +86 -0
- data/lib/teamsupport/creatable.rb +31 -0
- data/lib/teamsupport/customer.rb +66 -0
- data/lib/teamsupport/customer_product.rb +14 -0
- data/lib/teamsupport/error.rb +135 -0
- data/lib/teamsupport/headers.rb +51 -0
- data/lib/teamsupport/identity.rb +43 -0
- data/lib/teamsupport/null_object.rb +52 -0
- data/lib/teamsupport/product.rb +14 -0
- data/lib/teamsupport/rest/api.rb +19 -0
- data/lib/teamsupport/rest/client.rb +25 -0
- data/lib/teamsupport/rest/customers.rb +156 -0
- data/lib/teamsupport/rest/products.rb +113 -0
- data/lib/teamsupport/rest/request.rb +116 -0
- data/lib/teamsupport/rest/tickets.rb +134 -0
- data/lib/teamsupport/rest/utils.rb +325 -0
- data/lib/teamsupport/ticket.rb +81 -0
- data/lib/teamsupport/ticket_action.rb +16 -0
- data/lib/teamsupport/utils.rb +33 -0
- data/lib/teamsupport/version.rb +73 -0
- data/teamsupport.gemspec +27 -0
- metadata +158 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4802bcfd75dfbac4c1b74c4e76e83bfd80daffdf
|
4
|
+
data.tar.gz: 4e9a7133091888f556ab04e5bc3039f8c9cb2e45
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 16d923aceecaa410fd0ac83659f4a70bd7377cd7275d5e717e79447437a35bc32f1387d0054a0b4de7e03e68a30e98fd25f5ad288b1c4357523411c2b49258de
|
7
|
+
data.tar.gz: ea4add6266fa8f0db8f745dd07501e210336660152627fde974ac87f8dfb8f9f1c5c2cf99b879c5fd7ede6f55f9c6ceef6ca7e9a6866ae3ff59e1a382f388fda
|
data/.yardopts
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Change Log (http://keepachangelog.com/)
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
4
|
+
|
5
|
+
## Unreleased
|
6
|
+
- Backlog and Future Milestones are managed via [Github](https://github.com/jrbeilke/teamsupport/issues)
|
7
|
+
|
8
|
+
## 0.1.0 - 2016-09-22
|
9
|
+
### Added
|
10
|
+
- Initial release with support for customers, products, and tickets from the Teamsupport API.
|
11
|
+
- Based on code from [The Twitter Ruby Gem](https://github.com/sferik/twitter)
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
## Contributing
|
2
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
3
|
+
improve this project. Here are some ways *you* can contribute:
|
4
|
+
|
5
|
+
[free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
|
6
|
+
|
7
|
+
* Use alpha, beta, and pre-release versions.
|
8
|
+
* Report bugs.
|
9
|
+
* Suggest new features.
|
10
|
+
* Write or edit documentation.
|
11
|
+
* Write specifications.
|
12
|
+
* Write code (**no patch is too small**: fix typos, add comments, clean up
|
13
|
+
inconsistent whitespace).
|
14
|
+
* Refactor code.
|
15
|
+
* Fix [issues][].
|
16
|
+
* Review patches.
|
17
|
+
|
18
|
+
[issues]: https://github.com/jrbeilke/teamsupport/issues
|
19
|
+
|
20
|
+
## Submitting an Issue
|
21
|
+
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
22
|
+
submitting a bug report or feature request, check to make sure it hasn't
|
23
|
+
already been submitted. When submitting a bug report, please include a [Gist][]
|
24
|
+
that includes a stack trace and any details that may be necessary to reproduce
|
25
|
+
the bug, including your gem version, Ruby version, and operating system.
|
26
|
+
Ideally, a bug report should include a pull request with failing specs.
|
27
|
+
|
28
|
+
[gist]: https://gist.github.com/
|
29
|
+
|
30
|
+
## Submitting a Pull Request
|
31
|
+
1. [Fork the repository.][fork]
|
32
|
+
2. [Create a topic branch.][branch]
|
33
|
+
3. Add specs for your unimplemented feature or bug fix.
|
34
|
+
4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
|
35
|
+
5. Implement your feature or bug fix.
|
36
|
+
6. Run `bundle exec rake`. If your specs fail, return to step 5.
|
37
|
+
7. Run `open coverage/index.html`. If your changes are not completely covered
|
38
|
+
by your tests, return to step 3.
|
39
|
+
8. Add documentation for your feature or bug fix.
|
40
|
+
9. Run `bundle exec rake verify_measurements`. If your changes are not 100%
|
41
|
+
documented, go back to step 8.
|
42
|
+
10. Commit and push your changes.
|
43
|
+
11. [Submit a pull request.][pr]
|
44
|
+
|
45
|
+
[fork]: http://help.github.com/fork-a-repo/
|
46
|
+
[branch]: http://learn.github.com/p/branching.html
|
47
|
+
[pr]: http://help.github.com/send-pull-requests/
|
data/LICENSE.md
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
Teamsupport Ruby Gem: https://github.com/jrbeilke/teamsupport
|
2
|
+
|
3
|
+
Copyright (c) 2016 Jon Beilke
|
4
|
+
|
5
|
+
Based on the Twitter Ruby Gem: https://github.com/sferik/twitter/
|
6
|
+
|
7
|
+
Copyright (c) 2006-2016 Erik Michaels-Ober, John Nunemaker, Wynn Netherland, Steve Richert, Steve Agalloco
|
8
|
+
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
10
|
+
a copy of this software and associated documentation files (the
|
11
|
+
"Software"), to deal in the Software without restriction, including
|
12
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
13
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
14
|
+
permit persons to whom the Software is furnished to do so, subject to
|
15
|
+
the following conditions:
|
16
|
+
|
17
|
+
The above copyright notice and this permission notice shall be
|
18
|
+
included in all copies or substantial portions of the Software.
|
19
|
+
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
21
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
23
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
24
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
25
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
26
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# The Teamsupport Ruby Gem
|
2
|
+
|
3
|
+
[![Gem Version](http://img.shields.io/gem/v/teamsupport.svg)][gem]
|
4
|
+
[![Build Status](http://img.shields.io/travis/jrbeilke/teamsupport.svg)][travis]
|
5
|
+
[![Dependency Status](http://img.shields.io/gemnasium/jrbeilke/teamsupport.svg)][gemnasium]
|
6
|
+
[![Code Climate](http://img.shields.io/codeclimate/github/jrbeilke/teamsupport.svg)][codeclimate]
|
7
|
+
[![Coverage Status](http://img.shields.io/coveralls/jrbeilke/teamsupport.svg)][coveralls]
|
8
|
+
[![Inline docs](http://inch-ci.org/github/jrbeilke/teamsupport.svg?style=shields)][inchpages]
|
9
|
+
|
10
|
+
[gem]: https://rubygems.org/gems/teamsupport
|
11
|
+
[travis]: https://travis-ci.org/jrbeilke/teamsupport
|
12
|
+
[gemnasium]: https://gemnasium.com/jrbeilke/teamsupport
|
13
|
+
[codeclimate]: https://codeclimate.com/github/jrbeilke/teamsupport
|
14
|
+
[coveralls]: https://coveralls.io/r/jrbeilke/teamsupport
|
15
|
+
[inchpages]: http://inch-ci.org/github/jrbeilke/teamsupport
|
16
|
+
|
17
|
+
A Ruby interface to the Teamsupport API.
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
gem install twitter
|
21
|
+
|
22
|
+
## Documentation
|
23
|
+
[http://rdoc.info/gems/teamsupport][documentation]
|
24
|
+
|
25
|
+
[documentation]: http://rdoc.info/gems/teamsupport
|
26
|
+
|
27
|
+
To access custom fields you will need to use the attrs method along with the api field name:
|
28
|
+
```ruby
|
29
|
+
customer = client.customer(213747670)
|
30
|
+
customer.attrs[:CustomField1]
|
31
|
+
```
|
32
|
+
|
33
|
+
Caveat: The TeamSupport API currently returns boolean values as "True"/"False" strings. A workaround has been applied to the teamsupport gem that will return a boolean true/false for any of the standard TeamSupport values that should be a boolean (ie. IsActive on customers and IsClosed on tickets). Any additional custom fields that were created in TeamSupport will return the "True"/"False" string value instead of the proper boolean.
|
34
|
+
|
35
|
+
## Examples
|
36
|
+
[https://github.com/jrbeilke/teamsupport/tree/master/examples][examples]
|
37
|
+
|
38
|
+
[examples]: https://github.com/jrbeilke/teamsupport/tree/master/examples
|
39
|
+
|
40
|
+
## Configuration
|
41
|
+
The Teamsupport API requires you to authenticate via Basic Auth, using an
|
42
|
+
Organization ID (aka API Key) and an API Token (aka API Secret).
|
43
|
+
|
44
|
+
You'll need to configure these values before you make a request or else
|
45
|
+
you'll get the error:
|
46
|
+
|
47
|
+
Bad Authentication data
|
48
|
+
|
49
|
+
You can pass configuration options as a block to `Teamsupport::REST::Client.new`.
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
client = Teamsupport::REST::Client.new do |config|
|
53
|
+
config.api_key = "TEAMSUPPORT_ORGANIZATION_ID"
|
54
|
+
config.api_secret = "TEAMSUPPORT_API_TOKEN"
|
55
|
+
end
|
56
|
+
```
|
57
|
+
|
58
|
+
## Usage Examples
|
59
|
+
After configuring a `client`, you can do the following things.
|
60
|
+
|
61
|
+
**Fetch a single customer (by organization ID)**
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
client.customer(213747670)
|
65
|
+
```
|
66
|
+
|
67
|
+
**Fetch a list of customers with details (by organization ID, or by implicit authenticated parent organization)**
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
client.customers
|
71
|
+
```
|
72
|
+
|
73
|
+
**Fetch a single product (by product ID)**
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
client.product(213747670)
|
77
|
+
```
|
78
|
+
|
79
|
+
**Fetch a list of products with details (by product ID, or by implicit authenticated parent organization)**
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
client.products
|
83
|
+
```
|
84
|
+
|
85
|
+
**Fetch a list of products for a customer (by customer ID)**
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
client.customer_products(213747670)
|
89
|
+
```
|
90
|
+
|
91
|
+
**Fetch a single ticket (by ticket ID, or by ticket Number)**
|
92
|
+
|
93
|
+
```ruby
|
94
|
+
client.ticket(213747670)
|
95
|
+
```
|
96
|
+
|
97
|
+
**Fetch a list of tickets with details (by ticket ID, or by implicit authenticated parent organization)**
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
client.tickets
|
101
|
+
```
|
102
|
+
|
103
|
+
**Fetch a list of tickets for a customer (by customer ID)**
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
client.customer_tickets(213747670)
|
107
|
+
```
|
108
|
+
|
109
|
+
## Object Graph
|
110
|
+
![Entity-relationship diagram][erd]
|
111
|
+
|
112
|
+
[erd]: etc/erd.svg "Entity-relationship diagram"
|
113
|
+
|
114
|
+
This entity-relationship diagram is generated programatically. If you add or
|
115
|
+
remove any Teamsupport objects, please regenerate the ERD with the following
|
116
|
+
command:
|
117
|
+
|
118
|
+
bundle exec rake erd
|
119
|
+
|
120
|
+
## Supported Ruby Versions
|
121
|
+
This library aims to support and is [tested against][travis] the following Ruby versions:
|
122
|
+
|
123
|
+
* Ruby 2.0.0
|
124
|
+
* Ruby 2.1
|
125
|
+
* Ruby 2.2
|
126
|
+
* JRuby 9.1.1.0
|
127
|
+
|
128
|
+
## Copyright
|
129
|
+
Copyright (c) 2016 Jon Beilke.
|
130
|
+
See [LICENSE][] for details.
|
131
|
+
|
132
|
+
[license]: LICENSE.md
|
data/lib/teamsupport.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'teamsupport/rest/client'
|
3
|
+
|
4
|
+
# TODO: require 'teamsupport/asset'
|
5
|
+
# TODO: require 'teamsupport/asset_ticket'
|
6
|
+
# TODO: require 'teamsupport/contact'
|
7
|
+
# TODO: require 'teamsupport/contact_ticket'
|
8
|
+
require 'teamsupport/customer'
|
9
|
+
# TODO: require 'teamsupport/customer_contact'
|
10
|
+
require 'teamsupport/customer_product'
|
11
|
+
# TODO: require 'teamsupport/customer_ticket'
|
12
|
+
# TODO: require 'teamsupport/group'
|
13
|
+
require 'teamsupport/product'
|
14
|
+
# TODO: require 'teamsupport/product_customer'
|
15
|
+
# TODO: require 'teamsupport/property'
|
16
|
+
require 'teamsupport/ticket'
|
17
|
+
require 'teamsupport/ticket_action'
|
18
|
+
# TODO: require 'teamsupport/ticket_contact'
|
19
|
+
# TODO: require 'teamsupport/ticket_customer'
|
20
|
+
# TODO: require 'teamsupport/user'
|
21
|
+
# TODO: require 'teamsupport/wiki'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Teamsupport
|
2
|
+
class Arguments < Array
|
3
|
+
# Provide an options method for reading argument options
|
4
|
+
#
|
5
|
+
# @example
|
6
|
+
# teamsupport_arguments = Teamsupport::Arguments.new(args)
|
7
|
+
# teamsupport_arguments.options
|
8
|
+
#
|
9
|
+
# @return [Hash]
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
attr_reader :options
|
13
|
+
|
14
|
+
# Initializes a new Arguments object
|
15
|
+
#
|
16
|
+
# @param args [Hash]
|
17
|
+
#
|
18
|
+
# @return [Teamsupport::Arguments]
|
19
|
+
#
|
20
|
+
# @api private
|
21
|
+
def initialize(args)
|
22
|
+
@options = args.last.is_a?(::Hash) ? args.pop : {}
|
23
|
+
super(args.flatten)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'forwardable'
|
3
|
+
require 'teamsupport/null_object'
|
4
|
+
require 'teamsupport/utils'
|
5
|
+
|
6
|
+
module Teamsupport
|
7
|
+
class Base
|
8
|
+
extend Forwardable
|
9
|
+
include Teamsupport::Utils
|
10
|
+
# Provide an attrs method for reading object attributes
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# teamsupport_object = Teamsupport::Base.new(ID: 1)
|
14
|
+
# teamsupport_object.attrs[:ID]
|
15
|
+
#
|
16
|
+
# @return [Hash]
|
17
|
+
#
|
18
|
+
# @api public
|
19
|
+
attr_reader :attrs
|
20
|
+
alias to_h attrs
|
21
|
+
alias to_hash to_h
|
22
|
+
|
23
|
+
class << self
|
24
|
+
# Define methods for reading and checking existence of attributes
|
25
|
+
#
|
26
|
+
# @example
|
27
|
+
# attr_reader :attrs
|
28
|
+
#
|
29
|
+
# @param attrs [Array, Symbol]
|
30
|
+
#
|
31
|
+
# @return [Object, Boolean, nil]
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
def attr_reader(*attrs)
|
35
|
+
attrs.each do |attr|
|
36
|
+
define_attribute_method(attr)
|
37
|
+
define_predicate_method(attr)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Define methods for checking existence of attributes
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# predicate_attr_reader :favorited
|
45
|
+
#
|
46
|
+
# @return [Boolean]
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
def predicate_attr_reader(*attrs)
|
50
|
+
attrs.each do |attr|
|
51
|
+
define_predicate_method(attr)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Define methods for reading and checking existence of attributes within an object
|
56
|
+
#
|
57
|
+
# @example
|
58
|
+
# object_attr_reader :User, :user, :status
|
59
|
+
#
|
60
|
+
# @param klass [Symbol]
|
61
|
+
# @param key1 [Symbol]
|
62
|
+
# @param key2 [Symbol]
|
63
|
+
#
|
64
|
+
# @return [Object, Boolean, nil]
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
def object_attr_reader(klass, key1, key2 = nil)
|
68
|
+
define_attribute_method(key1, klass, key2)
|
69
|
+
define_predicate_method(key1)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Dynamically define a method for getting the value of an attribute
|
73
|
+
#
|
74
|
+
# @example
|
75
|
+
# define_attribute_method(key1, klass, key2)
|
76
|
+
#
|
77
|
+
# @param key1 [Symbol]
|
78
|
+
# @param klass [Symbol]
|
79
|
+
# @param key2 [Symbol]
|
80
|
+
#
|
81
|
+
# @return [Object, nil]
|
82
|
+
#
|
83
|
+
# @api public
|
84
|
+
def define_attribute_method(key1, klass = nil, key2 = nil)
|
85
|
+
define_method(key1) do
|
86
|
+
if attr_falsey_or_empty?(key1)
|
87
|
+
NullObject.new
|
88
|
+
else
|
89
|
+
klass.nil? ? @attrs[key1] : Teamsupport.const_get(klass).new(attrs_for_object(key1, key2))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Dynamically define a method for checking existence of an attribute
|
95
|
+
#
|
96
|
+
# @example
|
97
|
+
# define_predicate_method(key1)
|
98
|
+
#
|
99
|
+
# @param key1 [Symbol]
|
100
|
+
# @param key2 [Symbol]
|
101
|
+
#
|
102
|
+
# @return [Boolean]
|
103
|
+
#
|
104
|
+
# @api public
|
105
|
+
def define_predicate_method(key1, key2 = key1)
|
106
|
+
define_method(:"#{key1}?") do
|
107
|
+
!attr_falsey_or_empty?(key2)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Initializes a new object
|
113
|
+
#
|
114
|
+
# @param attrs [Hash]
|
115
|
+
#
|
116
|
+
# @return [Teamsupport::Base]
|
117
|
+
#
|
118
|
+
# @api private
|
119
|
+
def initialize(attrs = {})
|
120
|
+
@attrs = attrs || {}
|
121
|
+
end
|
122
|
+
|
123
|
+
# Fetches an attribute of an object using hash notation
|
124
|
+
#
|
125
|
+
# @example
|
126
|
+
# teamsupport_object = Teamsupport::Base.new(ID: 1)
|
127
|
+
# teamsupport_object[:ID]
|
128
|
+
#
|
129
|
+
# @param method [String, Symbol] Message to send to the object
|
130
|
+
#
|
131
|
+
# @return [String, nil]
|
132
|
+
#
|
133
|
+
# @api public
|
134
|
+
#
|
135
|
+
# @deprecated Please use ##{method} to fetch the value instead
|
136
|
+
def [](method)
|
137
|
+
warn "#{Kernel.caller.first}: [DEPRECATION] #[#{method.inspect}] is deprecated. Use ##{method} to fetch the value."
|
138
|
+
send(method.to_sym)
|
139
|
+
rescue NoMethodError
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
# Check to see if the value for an object attribute is falsey or empty
|
146
|
+
#
|
147
|
+
# @param key [Symbol]
|
148
|
+
#
|
149
|
+
# @return [Boolean]
|
150
|
+
#
|
151
|
+
# @api private
|
152
|
+
def attr_falsey_or_empty?(key)
|
153
|
+
!@attrs[key] || @attrs[key].respond_to?(:empty?) && @attrs[key].empty?
|
154
|
+
end
|
155
|
+
|
156
|
+
# Fetch and/or update the attributes for an object
|
157
|
+
#
|
158
|
+
# @param key1 [Symbol]
|
159
|
+
# @param key2 [Symbol]
|
160
|
+
#
|
161
|
+
# @return [Hash]
|
162
|
+
#
|
163
|
+
# @api private
|
164
|
+
def attrs_for_object(key1, key2 = nil)
|
165
|
+
if key2.nil?
|
166
|
+
@attrs[key1]
|
167
|
+
else
|
168
|
+
attrs = @attrs.dup
|
169
|
+
attrs.delete(key1).merge(key2 => attrs)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|