teamsupport 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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