HelpDeskAPI 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f17405bcdc7beb2c54da528e9ee8d13f6698b20a
4
+ data.tar.gz: 3de324b2dc16290b3e2669d7985913df8fbd2c04
5
+ SHA512:
6
+ metadata.gz: 951db8336563881cb0b0828c2f3c844e13608bd52bcf91895f6d808a92a5833cd2f8f14e35c215e8fdd78ace48d2ff7e11849b05ff1724ba389d2f0dcf3bd880
7
+ data.tar.gz: 52617eae9e72af8da7808b24d5bfff30bcb68ec4b26c7556d746866b2bc10d2f1732d8cdba2c9c7750f15dc3c61dd5a14f08bb4ee81e21bcd82f3b36c7b387c0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2017 Chase L Engel
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.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ Ruby library for Spiceworks Help Desk.
2
+
3
+ Currently only basic actions have been implemented.
4
+
5
+ ### Installation
6
+ ```
7
+ $ gem build helpdeskapi.gemspec
8
+ $ gem install ./HelpDeskAPI-1.0.0.gem
9
+ ```
10
+
11
+ Note: Some actions require administrator user
12
+ ### Signing in
13
+ ```
14
+ HelpDeskAPI::Client.new 'user@example.com', 'password'
15
+ ```
16
+ ### Tickets
17
+ ```
18
+ # All tickets
19
+ HelpDeskAPI::Tickets.all
20
+
21
+ # Open tickets
22
+ HelpDeskAPI::Tickets.open
23
+
24
+ # Closed tickets
25
+ HelpDeskAPI::Tickets.closed
26
+
27
+ # My tickets
28
+ HelpDeskAPI::Tickets.my
29
+
30
+ # Unassigned tickets
31
+ HelpDeskAPI::Tickets.unassigned
32
+
33
+ # Waiting tickets
34
+ HelpDeskAPI::Tickets.waiting
35
+
36
+ # Past due tickets
37
+ HelpDeskAPI::Tickets.past_due
38
+
39
+ # Search for a ticket
40
+ HelpDeskAPI::Tickets.search 'Summary'
41
+
42
+ # Ticket creation
43
+ ticket = HelpDeskAPI::Ticket.new 'Summary', 'Description', user.id, HelpDeskAPI::Ticket::Priority::HIGH
44
+ ticket.submit
45
+
46
+ # Delete ticket
47
+ ticket.delete
48
+ ```
49
+ ### Comments
50
+ ```
51
+ # Save comment
52
+ comment = ticket.comment 'This is a comment'
53
+ comment.save
54
+ # or
55
+ comment = HelpDeskAPI::Comment.new ticket.id, 'This is a comment'
56
+ comment.save
57
+
58
+ # Get all comment for a ticket
59
+ ticket.comments
60
+ # or
61
+ HelpDeskAPI::Comments.comments ticket.id
62
+ ```
63
+ ### Users
64
+ ```
65
+ # Get users (Administrators and Techs)
66
+ HelpDeskAPI::Users.users
67
+ ```
68
+ ### Organizations
69
+ ```
70
+ # All organizations
71
+ HelpDeskAPI::Organizations.organizations
72
+ ```
@@ -0,0 +1,11 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'HelpDeskAPI'
3
+ s.version = '1.0.0'
4
+ s.date = '2017-06-22'
5
+ s.summary = 'Ruby Library for the Spiceworks Help Desk API'
6
+ s.authors = ['Chase L Engel']
7
+ s.email = 'chaselengel@gmail.com'
8
+ s.files = `git ls-files -z`.split("\0")
9
+ s.homepage = 'https://github.com/ChaseLEngel/HelpDeskAPI'
10
+ s.license = 'MIT'
11
+ end
@@ -0,0 +1,68 @@
1
+ require 'rest-client'
2
+ require 'nokogiri'
3
+ require 'json'
4
+
5
+ require File.dirname(__FILE__) + '/helpdeskapi/authentication'
6
+ require File.dirname(__FILE__) + '/helpdeskapi/ticket'
7
+ require File.dirname(__FILE__) + '/helpdeskapi/request'
8
+ require File.dirname(__FILE__) + '/helpdeskapi/tickets'
9
+ require File.dirname(__FILE__) + '/helpdeskapi/users'
10
+ require File.dirname(__FILE__) + '/helpdeskapi/organizations'
11
+ require File.dirname(__FILE__) + '/helpdeskapi/endpoints'
12
+ require File.dirname(__FILE__) + '/helpdeskapi/exceptions'
13
+
14
+ module HelpDeskAPI
15
+ class Client
16
+
17
+ def initialize(username, password)
18
+ HelpDeskAPI::Authentication.username = username
19
+ HelpDeskAPI::Authentication.password = password
20
+ HelpDeskAPI::Authentication.authenticity_token = nil
21
+ HelpDeskAPI::Authentication.cookies = nil
22
+ sign_in
23
+ end
24
+
25
+ # Authenicate user and set cookies.
26
+ # This will be called automatically on endpoint request.
27
+ def sign_in
28
+ # Contact sign in page to set cookies.
29
+ begin
30
+ sign_in_res = RestClient.get(Endpoints::SIGN_IN)
31
+ rescue RestClient::ExceptionWithResponse => error
32
+ fail HelpDeskAPI::Exceptions.SignInError, "Error contacting #{Endpoints::SIGN_IN}: #{error}"
33
+ end
34
+
35
+ # Parse authenticity_token from sign in form.
36
+ page = Nokogiri::HTML(sign_in_res)
37
+ HelpDeskAPI::Authentication.authenticity_token = page.css('form').css('input')[1]['value']
38
+ unless HelpDeskAPI::Authentication.authenticity_token
39
+ fail HelpDeskAPI::Exceptions.AuthenticityTokenError, 'Error parsing authenticity_token: Token not found.'
40
+ end
41
+ # Parse sign_in HTML for csrf-token
42
+ page.css('meta').each do |tag|
43
+ HelpDeskAPI::Authentication.csrf_token = tag['content'] if tag['name'] == 'csrf-token'
44
+ end
45
+ unless HelpDeskAPI::Authentication.csrf_token
46
+ fail HelpDeskAPI::Exceptions.CsrfTokenError, 'No csrf-token found'
47
+ end
48
+
49
+ # Set cookies for later requests
50
+ HelpDeskAPI::Authentication.cookies = sign_in_res.cookies
51
+
52
+ # Simulate sign in form submit button.
53
+ body = {
54
+ 'authenticity_token': HelpDeskAPI::Authentication.authenticity_token,
55
+ 'user[email_address]': HelpDeskAPI::Authentication.username,
56
+ 'user[password]': HelpDeskAPI::Authentication.password
57
+ }
58
+ RestClient.post(Endpoints::SESSIONS, body, {:cookies => HelpDeskAPI::Authentication.cookies}) do |response, request, result, &block|
59
+ # Response should be a 302 redirect from /sessions
60
+ if Request::responseError?(response)
61
+ fail HelpDeskAPI::Exceptions.SessionsError, "Error contacting #{Endpoints::SESSIONS}: #{error}"
62
+ end
63
+ # Update cookies just incase
64
+ HelpDeskAPI::Authentication.cookies = response.cookies
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,54 @@
1
+ require 'singleton'
2
+ require File.dirname(__FILE__) + '/organizations'
3
+
4
+ module HelpDeskAPI
5
+ module Authentication
6
+
7
+ # Pass all function calls to Data singleton.
8
+ def self.method_missing(m, *args, &block)
9
+ Data.instance.send(m, *args)
10
+ end
11
+
12
+ private
13
+ class Data
14
+ include Singleton
15
+
16
+ attr_accessor :username, :password, :authenticity_token, :csrf_token, :cookies
17
+
18
+ def initialize
19
+ @username = nil
20
+ @password = nil
21
+ @authenticity_token = nil
22
+ @csrf_token = nil
23
+ @cookies = nil
24
+ @organization_id = nil
25
+ @creator_id = nil
26
+ end
27
+
28
+ def signed_in?
29
+ return !@cookies.nil?
30
+ end
31
+
32
+ # Returns creator_id for current user from users endpoint
33
+ def creator_id
34
+ return @creator_id if @creator_id
35
+
36
+ HelpDeskAPI::Users.users.each do |user|
37
+ if user.email == @username
38
+ @creator_id = user.id
39
+ return @creator_id
40
+ end
41
+ end
42
+
43
+ fail NoCreatorIdError, "Failed to find creator_id for user: #{@username}"
44
+ end
45
+
46
+ # Returns organization_id or contacts API to get
47
+ # id of first organization.
48
+ def organization_id
49
+ return @organization_id if @organization_id
50
+ @organization_id = HelpDeskAPI::Organizations.organizations.first.id
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,56 @@
1
+ require 'json'
2
+
3
+ module HelpDeskAPI
4
+ class Comment
5
+
6
+ KEYS = [
7
+ 'id',
8
+ 'activity_type',
9
+ 'created_at',
10
+ 'body',
11
+ 'attachment_ids',
12
+ 'ticket',
13
+ 'creator',
14
+ ]
15
+
16
+ def initialize(ticket_id = nil, body = nil)
17
+ @ticket_id = ticket_id
18
+ @body = body
19
+ end
20
+
21
+ def parse(comment_hash)
22
+ HelpDeskAPI::Utilities.validateHash(comment_hash, KEYS)
23
+ KEYS.each do |key|
24
+ instance_variable_set '@'+key, comment_hash[key]
25
+ self.class.class_eval { attr_accessor key }
26
+ end
27
+ return self
28
+ end
29
+
30
+ def save
31
+ payload = JSON.generate(
32
+ {
33
+ comment: {
34
+ activity_type: 'comment',
35
+ body: @body,
36
+ created_at: nil,
37
+ creator_id: nil,
38
+ creator_type: nil,
39
+ ticket_id: @ticket_id
40
+ },
41
+ ticket_comment: {
42
+ activity_type: 'comment',
43
+ body: @body,
44
+ created_at: nil,
45
+ creator_id: nil,
46
+ creator_type: nil,
47
+ initial_upload_ids: [],
48
+ ticket_id: @ticket_id
49
+ }
50
+ })
51
+ headers = {'authenticity_token': HelpDeskAPI::Authentication.authenticity_token, 'X-CSRF-Token': HelpDeskAPI::Authentication.csrf_token, 'Content-Type': 'application/json'}
52
+ response = HelpDeskAPI::Request.request('POST', Endpoints::TICKETS + "/#{@ticket_id}" + '/comments', payload, headers)
53
+ parse JSON.parse(response)['comment']
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/request'
2
+ require File.dirname(__FILE__) + '/utilities'
3
+
4
+ module HelpDeskAPI
5
+ module Comments
6
+ def self.comments(ticket_id)
7
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS + "/#{ticket_id}/comments"), 'ticket_comments', Comment
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ module HelpDeskAPI
2
+ module Endpoints
3
+ URL = 'https://on.spiceworks.com'
4
+ SIGN_IN = URL + '/sign_in'
5
+ SESSIONS = URL + '/sessions'
6
+
7
+ API_URL = URL + '/api'
8
+ TICKETS = '/tickets'
9
+ TICKETS_OPEN = TICKETS + '/open'
10
+ TICKETS_ALL = TICKETS + '/all'
11
+ TICKETS_CLOSED = TICKETS + '/closed'
12
+ TICKETS_MY_TICKETS = TICKETS + '/my'
13
+ TICKETS_UNASSIGNED = TICKETS + '/unassigned'
14
+ TICKETS_WAITING = TICKETS + '/waiting'
15
+ TICKETS_PAST_DUE = TICKETS + '/past_due'
16
+ USERS = '/users'
17
+ ORGANIZATIONS = '/organizations'
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ module HelpDeskAPI
2
+ module Exceptions
3
+ SignInError = Class.new(StandardError)
4
+ AuthenticityTokenError = Class.new(StandardError)
5
+ CsrfTokenError = Class.new(StandardError)
6
+ SessionsError = Class.new(StandardError)
7
+ NoCreatorIdError = Class.new(StandardError)
8
+ RequestError = Class.new(StandardError)
9
+ MissingKey = Class.new(StandardError)
10
+ end
11
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/utilities'
2
+
3
+ module HelpDeskAPI
4
+ class Organization
5
+
6
+ KEYS = [
7
+ 'id',
8
+ 'name',
9
+ 'host',
10
+ 'links',
11
+ 'domain_whitelist',
12
+ 'email_footer',
13
+ 'email_display_name',
14
+ 'portal_enabled',
15
+ 'ignore_subject',
16
+ 'ignore_body',
17
+ 'ignore_full_text',
18
+ 'notification_settings',
19
+ 'end_user_reopens_ticket',
20
+ 'wants_automatic_assignment',
21
+ 'category_ids',
22
+ 'custom_attribute_ids',
23
+ 'portal_setting_id',
24
+ 'ticket_monitor_ids',
25
+ 'active_directory_setting_id'
26
+ ]
27
+
28
+ def parse(organization_hash)
29
+ HelpDeskAPI::Utilities.validateHash organization_hash, KEYS
30
+ KEYS.each do |key|
31
+ instance_variable_set '@'+key, organization_hash[key]
32
+ self.class.class_eval { attr_accessor key }
33
+ end
34
+ return self
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/request'
2
+ require File.dirname(__FILE__) + '/endpoints'
3
+ require File.dirname(__FILE__) + '/utilities'
4
+ require File.dirname(__FILE__) + '/organization'
5
+
6
+ module HelpDeskAPI
7
+ module Organizations
8
+ def self.organizations
9
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::ORGANIZATIONS), 'organizations', Organization
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,40 @@
1
+ require 'rest-client'
2
+
3
+ require File.dirname(__FILE__) + '/authentication'
4
+ require File.dirname(__FILE__) + '/endpoints'
5
+ require File.dirname(__FILE__) + '/exceptions'
6
+
7
+ module HelpDeskAPI
8
+ module Request
9
+ @api = RestClient::Resource.new Endpoints::API_URL
10
+
11
+ # Contact API given endpoint and return JSON
12
+ def self.request(method, endpoint, payload = nil, headers = {})
13
+ headers = headers.merge({:cookies => HelpDeskAPI::Authentication.cookies})
14
+ endpoint_response = nil
15
+
16
+ case method
17
+ when 'POST'
18
+ @api[endpoint].post(payload, headers) { |response, _, _, _| endpoint_response = response }
19
+ when 'GET'
20
+ endpoint_response = @api[endpoint].get(headers)
21
+ when 'DELETE'
22
+ endpoint_response = @api[endpoint].delete(headers)
23
+ when 'PUT'
24
+ endpoint_response = @api[endpoint].put(payload, headers)
25
+ end
26
+
27
+ if responseError?(endpoint_response)
28
+ fail HelpDeskAPI::Exceptions.RequestError, "Error contacting #{endpoint_response.request.url} with HTTP code: #{endpoint_response.code}"
29
+ end
30
+
31
+ return endpoint_response
32
+ end
33
+
34
+ # Returns true if response contains HTTP error code.
35
+ def self.responseError?(response)
36
+ error_codes = [400, 401, 402, 403, 404, 500, 501, 502, 503]
37
+ error_codes.include? response.code
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,92 @@
1
+ require File.dirname(__FILE__) + '/endpoints'
2
+ require File.dirname(__FILE__) + '/utilities'
3
+ require File.dirname(__FILE__) + '/request'
4
+ require File.dirname(__FILE__) + '/comment'
5
+ require File.dirname(__FILE__) + '/comments'
6
+
7
+ module HelpDeskAPI
8
+ class Ticket
9
+
10
+ module Priority
11
+ HIGH = '1'
12
+ MEDIUM = '2'
13
+ LOW = '3'
14
+ end
15
+
16
+ KEYS = [
17
+ 'id',
18
+ 'created_at',
19
+ 'creator',
20
+ 'description',
21
+ 'due_at',
22
+ 'organization_id',
23
+ 'priority',
24
+ 'status',
25
+ 'summary',
26
+ 'updated_at',
27
+ 'custom_values',
28
+ 'assignee',
29
+ 'ticket_category',
30
+ ]
31
+
32
+ def initialize(summary = nil, description = nil, assignee_id = nil, priority = nil)
33
+ @summary = summary
34
+ @description = description
35
+ @assignee_id = assignee_id
36
+ @priority = priority
37
+ end
38
+
39
+ def parse(ticket_hash)
40
+ HelpDeskAPI::Utilities.validateHash(ticket_hash, KEYS)
41
+ KEYS.each do |key|
42
+ instance_variable_set '@'+key, ticket_hash[key]
43
+ self.class.class_eval { attr_accessor key }
44
+ end
45
+ return self
46
+ end
47
+
48
+ def submit
49
+ payload = JSON.generate({
50
+ ticket: {
51
+ summary: @summary,
52
+ description: @description,
53
+ priority: @priority,
54
+ due_at: nil,
55
+ updated_at: nil,
56
+ created_at: nil,
57
+ organization_id: HelpDeskAPI::Authentication.organization_id,
58
+ assignee_id: @assignee_id,
59
+ assignee_type: 'User',
60
+ creator_id: HelpDeskAPI::Authentication.creator_id,
61
+ creator_type: 'User',
62
+ custom_values: [],
63
+ ticket_category_id: nil,
64
+ ticket_category_type: nil,
65
+ watchers: []
66
+ }
67
+ })
68
+ headers = {'authenticity_token': HelpDeskAPI::Authentication.authenticity_token, 'X-CSRF-Token': HelpDeskAPI::Authentication.csrf_token, 'Content-Type': 'application/json'}
69
+ response = HelpDeskAPI::Request.request('POST', Endpoints::TICKETS, payload, headers)
70
+ parse JSON.parse(response)['tickets'].first
71
+ end
72
+
73
+ def close
74
+ end
75
+
76
+ def reopen
77
+ end
78
+
79
+ def delete
80
+ headers = {'authenticity_token': HelpDeskAPI::Authentication.authenticity_token, 'X-CSRF-Token': HelpDeskAPI::Authentication.csrf_token, 'Content-Type': 'application/json'}
81
+ HelpDeskAPI::Request.request('DELETE', Endpoints::TICKETS + "/#{@id}", nil, headers)
82
+ end
83
+
84
+ def comments
85
+ HelpDeskAPI::Comments.comments @id
86
+ end
87
+
88
+ def comment(body)
89
+ HelpDeskAPI::Comment.new @id, body
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,42 @@
1
+ require File.dirname(__FILE__) + '/request'
2
+ require File.dirname(__FILE__) + '/endpoints'
3
+ require File.dirname(__FILE__) + '/ticket'
4
+ require File.dirname(__FILE__) + '/utilities'
5
+
6
+ require 'uri'
7
+
8
+ module HelpDeskAPI
9
+ module Tickets
10
+ def self.search(query)
11
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_ALL+"?q=#{URI.escape query}"), 'tickets', Ticket
12
+ end
13
+
14
+ def self.all
15
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_ALL), 'tickets', Ticket
16
+ end
17
+
18
+ def self.open
19
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_OPEN), 'tickets', Ticket
20
+ end
21
+
22
+ def self.closed
23
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_CLOSED), 'tickets', Ticket
24
+ end
25
+
26
+ def self.my
27
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_MY_TICKETS), 'tickets', Ticket
28
+ end
29
+
30
+ def self.unassigned
31
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_UNASSIGNED), 'ticket', Ticket
32
+ end
33
+
34
+ def self.waiting
35
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_WAITING), 'ticket', Ticket
36
+ end
37
+
38
+ def self.past_due
39
+ HelpDeskAPI::Utilities.parse_response HelpDeskAPI::Request.request('GET', HelpDeskAPI::Endpoints::TICKETS_PAST_DUE), 'ticket', Ticket
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/utilities'
2
+ require File.dirname(__FILE__) + '/request'
3
+ require File.dirname(__FILE__) + '/authentication'
4
+
5
+ require 'json'
6
+
7
+ module HelpDeskAPI
8
+ class User
9
+
10
+ module Role
11
+ ADMIN = 'admin'
12
+ TECH = 'tech'
13
+ end
14
+
15
+ KEYS = [
16
+ 'id',
17
+ 'first_name',
18
+ 'last_name',
19
+ 'email',
20
+ 'avatar_url',
21
+ 'role',
22
+ 'hourly_rate',
23
+ 'spiceworks_user_id',
24
+ 'wants_alerts',
25
+ 'spiceworks_uid',
26
+ 'system_user',
27
+ 'verified',
28
+ 'archived_user_id'
29
+ ]
30
+
31
+ def initialize(first_name = nil, last_name = nil, email = nil, hourly_rate = nil)
32
+ @first_name = first_name
33
+ @last_name = last_name
34
+ @email = email
35
+ @hourly_rate = hourly_rate
36
+ end
37
+
38
+ def edit(hash)
39
+ editable = ['first_name', 'last_name', 'email', 'wants_alerts', 'hourly_rate']
40
+ hash.keep_if { |key, _| editable.include? key.to_s }
41
+ JSON.generate(
42
+ {
43
+ user: {
44
+ account_id: nil,
45
+ archived_user_id: @archived_user_id,
46
+ avatar_url: @avatar_url,
47
+ deleted: @deleted,
48
+ email: @email,
49
+ first_name: @first_name,
50
+ hourly_rate: @hourly_rate,
51
+ last_name: @last_name,
52
+ owned_account_id: nil,
53
+ role: @role,
54
+ spiceworks_uid: @spiceworks_uid,
55
+ spiceworks_user_id: @spiceworks_user_id,
56
+ system_user: @system_user,
57
+ verified: @verified,
58
+ wants_alerts: @wants_alerts
59
+ }
60
+ })
61
+ return # Missing account_id
62
+ headers = {'authenticity_token': HelpDeskAPI::Authentication.authenticity_token, 'X-CSRF-Token': HelpDeskAPI::Authentication.csrf_token, 'Content-Type': 'application/json'}
63
+ HelpDeskAPI::Request.request('PUT', Endpoints::USERS + "/#{@id}", payload, headers)
64
+ end
65
+
66
+ def save
67
+ end
68
+
69
+ def parse(user_hash)
70
+ HelpDeskAPI::Utilities.validateHash(user_hash, KEYS)
71
+ KEYS.each do |key|
72
+ instance_variable_set '@'+key, user_hash[key]
73
+ self.class.class_eval { attr_accessor key }
74
+ end
75
+ return self
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/request'
2
+ require File.dirname(__FILE__) + '/endpoints'
3
+ require File.dirname(__FILE__) + '/user'
4
+ require File.dirname(__FILE__) + '/utilities'
5
+
6
+ module HelpDeskAPI
7
+ module Users
8
+ def self.users
9
+ HelpDeskAPI::Utilities.parse_response Request::request('GET', HelpDeskAPI::Endpoints::USERS), 'users', User
10
+ end
11
+
12
+ private
13
+ def self.parse(hash)
14
+ hash['users'].map { |user_hash| User.new.parse(user_hash) }
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,23 @@
1
+ require 'json'
2
+
3
+ require File.dirname(__FILE__) + '/exceptions'
4
+
5
+ module HelpDeskAPI
6
+ module Utilities
7
+ # Makes sure all keys exist in hash
8
+ def self.validateHash(hash, keys)
9
+ keys.each do |key|
10
+ unless hash.has_key? key
11
+ fail HelpDeskAPI::Exceptions.MissingKey, "Missing key #{key} in hash:\n#{hash}\n"
12
+ end
13
+ end
14
+ end
15
+
16
+ # Converts response to JSON then creates given object and calls parse
17
+ # to handle parsing the response JSON
18
+ def self.parse_response(response, key, obj)
19
+ hash = JSON.parse response
20
+ hash[key].map { |object_hash| obj.new.parse(object_hash) }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,64 @@
1
+ require 'minitest/autorun'
2
+
3
+ require './lib/helpdeskapi'
4
+
5
+ class TestTickets < Minitest::Test
6
+
7
+ def setup
8
+ username = ENV['HELP_DESK_API_USERNAME']
9
+ password = ENV['HELP_DESK_API_PASSWORD']
10
+ @user_id = ENV['HELP_DESK_API_USER_ID'].to_s
11
+
12
+ if username.nil? || password.nil? || @user_id.nil?
13
+ puts "HELP_DESK_API_USERNAME or HELP_DESK_API_PASSWORD or HELP_DESK_API_USER_ID undefinded. Exiting."
14
+ exit
15
+ end
16
+
17
+ HelpDeskAPI::Client.new username, password
18
+ end
19
+
20
+ def test_ticket_submit
21
+ time = Time.now.to_i.to_s
22
+
23
+ ticket = HelpDeskAPI::Ticket.new time, time, @user_id, HelpDeskAPI::Ticket::Priority::LOW
24
+ ticket.submit
25
+
26
+ tickets = HelpDeskAPI::Tickets.all
27
+
28
+ tickets.keep_if { |t| t.summary == time }
29
+ refute_empty tickets
30
+
31
+ assert_equal tickets.first.summary, time
32
+ assert_equal tickets.first.description, time
33
+ assert_equal tickets.first.assignee["id"].to_s, @user_id.to_s
34
+ assert_equal tickets.first.priority, HelpDeskAPI::Ticket::Priority::LOW
35
+
36
+ end
37
+
38
+ def test_ticket_comment
39
+ time = Time.now.to_i.to_s
40
+
41
+ tickets = HelpDeskAPI::Tickets.all
42
+ ticket = tickets.first
43
+
44
+ comment = ticket.comment time
45
+ comment.save
46
+
47
+ comments = ticket.comments
48
+ refute_empty comments
49
+
50
+ comments.keep_if { |c| c.body == time }
51
+ refute_empty comments
52
+ end
53
+
54
+ def test_ticket_delete
55
+ tickets = HelpDeskAPI::Tickets.all
56
+ ticket = tickets.first
57
+
58
+ ticket.delete
59
+
60
+ tickets = HelpDeskAPI::Tickets.all
61
+ tickets.keep_if { |t| t.id == ticket.id }
62
+ assert_empty tickets
63
+ end
64
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: HelpDeskAPI
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Chase L Engel
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-22 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email: chaselengel@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - LICENSE.txt
20
+ - README.md
21
+ - helpdeskapi.gemspec
22
+ - lib/helpdeskapi.rb
23
+ - lib/helpdeskapi/authentication.rb
24
+ - lib/helpdeskapi/comment.rb
25
+ - lib/helpdeskapi/comments.rb
26
+ - lib/helpdeskapi/endpoints.rb
27
+ - lib/helpdeskapi/exceptions.rb
28
+ - lib/helpdeskapi/organization.rb
29
+ - lib/helpdeskapi/organizations.rb
30
+ - lib/helpdeskapi/request.rb
31
+ - lib/helpdeskapi/ticket.rb
32
+ - lib/helpdeskapi/tickets.rb
33
+ - lib/helpdeskapi/user.rb
34
+ - lib/helpdeskapi/users.rb
35
+ - lib/helpdeskapi/utilities.rb
36
+ - test/test_ticket.rb
37
+ homepage: https://github.com/ChaseLEngel/HelpDeskAPI
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.5.1
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: Ruby Library for the Spiceworks Help Desk API
61
+ test_files: []