teamsupport 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.
@@ -0,0 +1,86 @@
1
+ require 'teamsupport/error'
2
+ require 'teamsupport/utils'
3
+ require 'teamsupport/version'
4
+
5
+ module Teamsupport
6
+ class Client
7
+ # Provide api_key and api_secret methods for accessing Client API values
8
+ #
9
+ # @example
10
+ # teamsupport_client = Teamsupport::Client.new(api_key: 'AK', api_secret: 'AS')
11
+ # teamsupport_client.api_key
12
+ # teamsupport_client.api_secret
13
+ #
14
+ # @return [String]
15
+ #
16
+ # @api public
17
+ attr_accessor :api_key, :api_secret
18
+
19
+ # Provide user_agent method for overriding default Client user_agent value
20
+ #
21
+ # @example
22
+ # teamsupport_client = Teamsupport::Client.new(api_key: 'AK', api_secret: 'AS')
23
+ # teamsupport_client.user_agent = 'MyTeamsupportClient/1.0.0'
24
+ #
25
+ # @return [String]
26
+ #
27
+ # @api public
28
+ attr_writer :user_agent
29
+
30
+ # Initializes a new Client object
31
+ #
32
+ # @param options [Hash]
33
+ #
34
+ # @return [Teamsupport::Client]
35
+ #
36
+ # @api private
37
+ def initialize(options = {})
38
+ options.each do |key, value|
39
+ instance_variable_set("@#{key}", value)
40
+ end
41
+ yield(self) if block_given?
42
+ end
43
+
44
+ # Returns user agent string for the Client
45
+ #
46
+ # @example
47
+ # teamsupport_client = Teamsupport::Client.new(api_key: 'AK', api_secret: 'AS')
48
+ # teamsupport_client.user_agent
49
+ #
50
+ # @return [String]
51
+ #
52
+ # @api public
53
+ def user_agent
54
+ @user_agent ||= "TeamsupportRubyGem/#{Teamsupport::Version}"
55
+ end
56
+
57
+ # Returns authentication hash for the Client
58
+ #
59
+ # @example
60
+ # teamsupport_client = Teamsupport::Client.new(api_key: 'AK', api_secret: 'AS')
61
+ # teamsupport_client.auth
62
+ #
63
+ # @return [Hash]
64
+ #
65
+ # @api public
66
+ def auth
67
+ {
68
+ user: api_key,
69
+ password: api_secret,
70
+ }
71
+ end
72
+
73
+ # Checks for the existence of an authentication hash on the Client
74
+ #
75
+ # @example
76
+ # teamsupport_client = Teamsupport::Client.new(api_key: 'AK', api_secret: 'AS')
77
+ # teamsupport_client.auth?
78
+ #
79
+ # @return [Boolean]
80
+ #
81
+ # @api public
82
+ def auth?
83
+ auth.values.all?
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,31 @@
1
+ require 'time'
2
+
3
+ module Teamsupport
4
+ module Creatable
5
+ # Time when object was created on TeamSupport
6
+ #
7
+ # @example
8
+ # teamsupport_object = Teamsupport::Creatable.new(DateCreated: '4/4/2015 9:45 AM')
9
+ # teamsupport_object.DateCreated
10
+ #
11
+ # @return [Time]
12
+ #
13
+ # @api public
14
+ def DateCreated # rubocop:disable Style/MethodName
15
+ Time.strptime(@attrs[:DateCreated], '%m/%d/%Y %l:%M %p').utc unless @attrs[:DateCreated].nil?
16
+ end
17
+
18
+ # Time when object was last modified on TeamSupport
19
+ #
20
+ # @example
21
+ # teamsupport_object = Teamsupport::Creatable.new(DateModified: '4/4/2015 10:00 AM')
22
+ # teamsupport_object.DateModified
23
+ #
24
+ # @return [Time]
25
+ #
26
+ # @api public
27
+ def DateModified # rubocop:disable Style/MethodName
28
+ Time.strptime(@attrs[:DateModified], '%m/%d/%Y %l:%M %p').utc unless @attrs[:DateModified].nil?
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,66 @@
1
+ require 'teamsupport/base'
2
+ require 'teamsupport/creatable'
3
+ require 'teamsupport/identity'
4
+
5
+ module Teamsupport
6
+ class Customer < Teamsupport::Identity
7
+ include Teamsupport::Creatable
8
+
9
+ # @return [Integer]
10
+ attr_reader :ID, :PrimaryUserID, :CreatorID, :ModifierID, :SlaLevelID, :DefaultSupportGroupID, :DefaultSupportUserID, :SupportHoursMonth, :SupportHoursUsed, :SupportHoursRemaining
11
+ # @return [String]
12
+ attr_reader :Name, :Description, :Website, :InActiveReason, :PrimaryContact, :Domains, :CreatedBy, :LastModifiedBy, :SlaName, :CRMLinkId, :DefaultWikiArticle, :DefaultSupportGroup, :DefaultSupportUser
13
+
14
+ # Boolean indicating whether a Customer is active on Teamsupport
15
+ #
16
+ # @example
17
+ # teamsupport_customer = Teamsupport::Customer.new(IsActive: true)
18
+ # teamsupport_customer.IsActive
19
+ #
20
+ # @return [Boolean]
21
+ #
22
+ # @api public
23
+ def IsActive # rubocop:disable Style/MethodName
24
+ @attrs[:IsActive] == 'True' ? true : false
25
+ end
26
+
27
+ # Boolean indicating whether a Customer has portal access on Teamsupport
28
+ #
29
+ # @example
30
+ # teamsupport_customer = Teamsupport::Customer.new(HasPortalAccess: true)
31
+ # teamsupport_customer.HasPortalAccess
32
+ #
33
+ # @return [Boolean]
34
+ #
35
+ # @api public
36
+ def HasPortalAccess # rubocop:disable Style/MethodName
37
+ @attrs[:HasPortalAccess] == 'True' ? true : false
38
+ end
39
+
40
+ # Boolean indicating whether a Customer needs indexing on Teamsupport
41
+ #
42
+ # @example
43
+ # teamsupport_customer = Teamsupport::Customer.new(NeedsIndexing: true)
44
+ # teamsupport_customer.NeedsIndexing
45
+ #
46
+ # @return [Boolean]
47
+ #
48
+ # @api public
49
+ def NeedsIndexing # rubocop:disable Style/MethodName
50
+ @attrs[:NeedsIndexing] == 'True' ? true : false
51
+ end
52
+
53
+ # Time when the Customer's Service Agreement expires on Teamsupport
54
+ #
55
+ # @example
56
+ # teamsupport_customer = Teamsupport::Customer.new(SAExpirationDate: '4/4/2015 10:15 AM')
57
+ # teamsupport_customer.SAExpirationDate
58
+ #
59
+ # @return [Time]
60
+ #
61
+ # @api public
62
+ def SAExpirationDate # rubocop:disable Style/MethodName
63
+ Time.strptime(@attrs[:SAExpirationDate], '%m/%d/%Y %l:%M %p').utc unless @attrs[:SAExpirationDate].nil?
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,14 @@
1
+ require 'teamsupport/base'
2
+ require 'teamsupport/creatable'
3
+ require 'teamsupport/product'
4
+
5
+ module Teamsupport
6
+ class CustomerProduct < Teamsupport::Product
7
+ include Teamsupport::Creatable
8
+
9
+ # @return [Integer]
10
+ attr_reader :ID, :CreatorID, :ModifierID, :OrganizationID, :ProductID
11
+ # @return [String]
12
+ attr_reader :Name, :Description
13
+ end
14
+ end
@@ -0,0 +1,135 @@
1
+ module Teamsupport
2
+ # Custom error class for rescuing from all Teamsupport errors
3
+ class Error < StandardError
4
+ # Provide a code method for reading HTTP status code from Error
5
+ #
6
+ # @example
7
+ # teamsupport_error = Teamsupport::Error.new(code: 404)
8
+ # teamsupport_error.code
9
+ #
10
+ # @return [Integer]
11
+ #
12
+ # @api public
13
+ attr_reader :code
14
+
15
+ # Raised when Teamsupport returns a 4xx HTTP status code
16
+ ClientError = Class.new(self)
17
+
18
+ # Raised when Teamsupport returns the HTTP status code 400
19
+ BadRequest = Class.new(ClientError)
20
+
21
+ # Raised when Teamsupport returns the HTTP status code 401
22
+ Unauthorized = Class.new(ClientError)
23
+
24
+ # Raised when Teamsupport returns the HTTP status code 403
25
+ Forbidden = Class.new(ClientError)
26
+
27
+ # Raised when Teamsupport returns the HTTP status code 404
28
+ NotFound = Class.new(ClientError)
29
+
30
+ # Raised when Teamsupport returns the HTTP status code 406
31
+ NotAcceptable = Class.new(ClientError)
32
+
33
+ # Raised when Teamsupport returns the HTTP status code 422
34
+ UnprocessableEntity = Class.new(ClientError)
35
+
36
+ # Raised when Teamsupport returns the HTTP status code 429
37
+ TooManyRequests = Class.new(ClientError)
38
+
39
+ # Raised when Teamsupport returns a 5xx HTTP status code
40
+ ServerError = Class.new(self)
41
+
42
+ # Raised when Teamsupport returns the HTTP status code 500
43
+ InternalServerError = Class.new(ServerError)
44
+
45
+ # Raised when Teamsupport returns the HTTP status code 502
46
+ BadGateway = Class.new(ServerError)
47
+
48
+ # Raised when Teamsupport returns the HTTP status code 503
49
+ ServiceUnavailable = Class.new(ServerError)
50
+
51
+ # Raised when Teamsupport returns the HTTP status code 504
52
+ GatewayTimeout = Class.new(ServerError)
53
+
54
+ ERRORS = {
55
+ 400 => Teamsupport::Error::BadRequest,
56
+ 401 => Teamsupport::Error::Unauthorized,
57
+ 403 => Teamsupport::Error::Forbidden,
58
+ 404 => Teamsupport::Error::NotFound,
59
+ 406 => Teamsupport::Error::NotAcceptable,
60
+ 422 => Teamsupport::Error::UnprocessableEntity,
61
+ 429 => Teamsupport::Error::TooManyRequests,
62
+ 500 => Teamsupport::Error::InternalServerError,
63
+ 502 => Teamsupport::Error::BadGateway,
64
+ 503 => Teamsupport::Error::ServiceUnavailable,
65
+ 504 => Teamsupport::Error::GatewayTimeout,
66
+ }.freeze
67
+
68
+ class << self
69
+ # Create a new error from an HTTP response
70
+ #
71
+ # @example
72
+ # teamsupport_error = Teamsupport::Error::ERRORS[code]
73
+ # teamsupport_error.from_response(body, headers) unless klass.nil?
74
+ #
75
+ # @param body [String]
76
+ # @param headers [Hash]
77
+ #
78
+ # @return [Teamsupport::Error]
79
+ #
80
+ # @api public
81
+ def from_response(body, _headers)
82
+ message, code = parse_error(body)
83
+ new(message, code)
84
+ end
85
+
86
+ private
87
+
88
+ # Parses response body for errors
89
+ #
90
+ # @param body [String]
91
+ #
92
+ # @return [Array, nil]
93
+ #
94
+ # @api private
95
+ def parse_error(body)
96
+ if body.nil? || body.empty?
97
+ ['', nil]
98
+ elsif body[:error]
99
+ [body[:error], nil]
100
+ elsif body[:errors]
101
+ extract_message_from_errors(body)
102
+ end
103
+ end
104
+
105
+ # Extracts error messages from response body
106
+ #
107
+ # @param body [String]
108
+ #
109
+ # @return [Array]
110
+ #
111
+ # @api private
112
+ def extract_message_from_errors(body)
113
+ first = Array(body[:errors]).first
114
+ if first.is_a?(Hash)
115
+ [first[:message].chomp, first[:code]]
116
+ else
117
+ [first.chomp, nil]
118
+ end
119
+ end
120
+ end
121
+
122
+ # Initializes a new Error object
123
+ #
124
+ # @param message [Exception, String]
125
+ # @param code [Integer]
126
+ #
127
+ # @return [Teamsupport::Error]
128
+ #
129
+ # @api private
130
+ def initialize(message = '', code = nil)
131
+ super(message)
132
+ @code = code
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,51 @@
1
+ require 'addressable/uri'
2
+ require 'base64'
3
+
4
+ module Teamsupport
5
+ class Headers
6
+ # Initializes a new Headers object
7
+ #
8
+ # @param client [Teamsupport::Client]
9
+ # @param request_method [String]
10
+ # @param url [String]
11
+ # @param options [Hash]
12
+ #
13
+ # @return [Teamsupport::Headers]
14
+ #
15
+ # @api private
16
+ def initialize(client, request_method, url, options = {})
17
+ @client = client
18
+ @request_method = request_method.to_sym
19
+ @uri = Addressable::URI.parse(url)
20
+ @options = options
21
+ end
22
+
23
+ # Returns HTTP request headers for the client
24
+ #
25
+ # @example
26
+ # teamsupport_client = Teamsupport::Client.new(api_key: 'AK', api_secret: 'AS')
27
+ # teamsupport_headers = Teamsupport::Headers.new(teamsupport_client, :get, 'https://app.teamsupport.com')
28
+ # teamsupport_headers.request_headers
29
+ #
30
+ # @return [Hash]
31
+ #
32
+ # @api public
33
+ def request_headers
34
+ headers = {'Content-Type' => 'application/json'}
35
+ headers[:user_agent] = @client.user_agent
36
+ headers[:authorization] = auth_header
37
+ headers
38
+ end
39
+
40
+ private
41
+
42
+ # Generates authentication header for TeamSupport API's basic auth
43
+ #
44
+ # @return [String]
45
+ #
46
+ # @api private
47
+ def auth_header
48
+ "Basic #{Base64.strict_encode64("#{@client.api_key}:#{@client.api_secret}")}"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,43 @@
1
+ require 'equalizer'
2
+ require 'teamsupport/base'
3
+
4
+ module Teamsupport
5
+ class Identity < Teamsupport::Base
6
+ include Equalizer.new(:ID)
7
+ # @return [Integer]
8
+
9
+ # Method for reading the TeamSupport ID of an object
10
+ #
11
+ # @example
12
+ # teamsupport_object = Teamsupport::Identity.new(ID: 1)
13
+ # teamsupport_object.ID
14
+ #
15
+ # @return [Integer]
16
+ #
17
+ # @api public
18
+ attr_reader :ID
19
+
20
+ # Initializes a new object
21
+ #
22
+ # @param attrs [Hash]
23
+ #
24
+ # @raise [ArgumentError] Error raised when supplied argument is missing an :ID key.
25
+ #
26
+ # @return [Teamsupport::Identity]
27
+ #
28
+ # @api private
29
+ def initialize(attrs = {})
30
+ # Workaround for dealing with TeamSupport API inconsistently sending ID for objects
31
+ unless attrs[:ID]
32
+ attrs[:ID] = attrs.fetch(:OrganizationID) if attrs[:OrganizationID]
33
+
34
+ attrs[:ID] = attrs.fetch(:ProductID) if attrs[:ProductID]
35
+
36
+ attrs[:ID] = attrs.fetch(:TicketID) if attrs[:TicketID]
37
+ end
38
+
39
+ attrs.fetch(:ID)
40
+ super
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,52 @@
1
+ require 'naught'
2
+
3
+ module Teamsupport
4
+ NullObject = Naught.build do |config|
5
+ include Comparable
6
+
7
+ config.black_hole
8
+ config.define_explicit_conversions
9
+ config.define_implicit_conversions
10
+ config.predicates_return false
11
+
12
+ def !
13
+ true
14
+ end
15
+
16
+ def respond_to?(*)
17
+ true
18
+ end
19
+
20
+ def respond_to?(*)
21
+ true
22
+ end
23
+
24
+ def instance_of?(klass)
25
+ raise(TypeError, 'class or module required') unless klass.is_a?(Class)
26
+ self.class == klass
27
+ end
28
+
29
+ def kind_of?(mod)
30
+ raise(TypeError, 'class or module required') unless mod.is_a?(Module)
31
+ self.class.ancestors.include?(mod)
32
+ end
33
+
34
+ alias_method :is_a?, :kind_of?
35
+
36
+ def <=>(other)
37
+ if other.is_a?(self.class)
38
+ 0
39
+ else
40
+ -1
41
+ end
42
+ end
43
+
44
+ def nil?
45
+ true
46
+ end
47
+
48
+ def as_json(*)
49
+ 'null'
50
+ end
51
+ end
52
+ end