HelpDeskAPI 1.0.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 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: []