File Coverage

blib/lib/Kayako/RestAPI.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Kayako::RestAPI;
2             $Kayako::RestAPI::VERSION = '0.01';
3             # ABSTRACT: Perl library for working with L
4              
5              
6 1     1   27261 use common::sense;
  1         10  
  1         6  
7 1     1   907 use Mojo::UserAgent;
  1         304700  
  1         17  
8 1     1   49 use Digest::SHA qw(hmac_sha256_base64);
  1         7  
  1         59  
9 1     1   721 use XML::XML2JSON;
  0            
  0            
10             use utf8;
11             use Data::Dumper;
12              
13             sub new {
14             my $class = shift;
15             my $o = {};
16             $o->{auth_hash} = shift;
17             $o->{xml2json_options} = shift;
18             $o->{xml2json_options} = { content_key => 'text', pretty => 1, attribute_prefix => 'attr_' } if not defined $o->{xml2json_options};
19             $o->{xml2json} = XML::XML2JSON->new(%{$o->{xml2json_options}});
20             $o->{ua} = Mojo::UserAgent->new;
21             bless $o, $class;
22             return $o;
23             }
24              
25             sub _prepare_request {
26             my $self = shift;
27             my @alphabet = (('a'..'z'), ('A'..'Z'), 0..9);
28             my $len = 10;
29             my $salt = join '', map {$alphabet[rand(@alphabet)]} 1..$len;
30             my $digest = hmac_sha256_base64($salt, $self->{auth_hash}{secret_key}).'=';
31             my $hash = {
32             "apikey" => $self->{auth_hash}{api_key},
33             "salt" => $salt,
34             "signature" => $digest
35             };
36             return $hash;
37             }
38              
39             sub xml2obj {
40             my ($self, $xml) = @_;
41             $self->{xml2json}->xml2obj($xml);
42             }
43              
44             # abstract api GET/POST/PUT/DELETE _query. return plain xml
45             sub _query {
46             my ($self, $method, $route, $params) = @_;
47             $params->{e} = $route;
48             my %hash = (%{$self->_prepare_request}, %$params);
49             my $xml = $self->{ua}->$method($self->{auth_hash}{api_url} => form => \%hash)->res->body;
50             $xml =~ s/([\x00-\x09]+)|([\x0B-\x1F]+)//g;
51             return $xml;
52             }
53              
54             sub get {
55             my ($self, $route, $params) = @_;
56             $self->_query('get', $route, $params);
57             }
58              
59             sub put {
60             my ($self, $route, $params) = @_;
61             $self->_query('put', $route, $params);
62             }
63              
64             sub post {
65             my ($self, $route, $params) = @_;
66             $self->_query('post', $route, $params);
67             }
68              
69             sub delete {
70             my ($self, $route, $params) = @_;
71             $self->_query('delete', $route, $params);
72             }
73              
74             # abstract api GET _query. return hash
75             # can potentially crash is returned xml isn't valid
76             sub get_hash {
77             my ($self, $route, $params) = @_;
78             my $xml = $self->get($route, $params);
79             return $self->{xml2json}->xml2obj($xml);
80             }
81              
82             # Get info about ticket in native XML
83             sub get_ticket_xml {
84             my ($self, $ticket_id, $params) = @_;
85             return $self->get("/Tickets/Ticket/".$ticket_id."/", $params);
86             }
87              
88             sub get_ticket_hash {
89             my ($self, $ticket_id) = @_;
90             my $xml = $self->get_ticket_xml($ticket_id);
91             my $hash = {};
92             if ($xml eq 'Ticket not Found' || $xml eq '') {
93             die "Ticket not Found";
94             # $hash->{'ticket_id'} = $ticket_id;
95             # $hash->{'is_found'} = 0;
96             } else {
97             $hash = $self->{xml2json}->xml2obj($xml)->{tickets}{ticket};
98             }
99             return $hash;
100             }
101              
102              
103             sub change_ticket_owner {
104             my ($self, $ticket_id, $new_owner_id) = @_;
105             my $content_key = $self->{xml2json_options}{content_key};
106             my $old_data = $self->get_ticket_hash($ticket_id);
107             $self->put("/Tickets/Ticket/".$ticket_id."/", { ownerstaffid => $new_owner_id });
108             my $new_data = $self->get_ticket_hash($ticket_id);
109             my $res = {
110             old => {
111             ownerstaffid => $old_data->{ownerstaffid}{$content_key},
112             ownerstaffname => $old_data->{ownerstaffname}{$content_key}
113             },
114             new => {
115             ownerstaffid => $new_data->{ownerstaffid}{$content_key},
116             ownerstaffname => $new_data->{ownerstaffname}{$content_key}
117             }
118             };
119             return $res;
120             }
121              
122              
123              
124             sub make_unassigned {
125             my ($self, $ticket_id) = @_;
126             $self->change_ticket_owner($ticket_id, 0);
127             }
128              
129              
130             sub create_ticket {
131             my ($self, $params) = @_;
132             my $xml = $self->post('/Tickets/Ticket/', $params);
133             $self->xml2obj($xml);
134             }
135              
136              
137              
138             sub filter_fields {
139             my ($self, $a) = @_; # array of hashes
140             my $key = $self->{xml2json_options}{content_key};
141             for my $j (@$a) {
142             $j = { map { $_ => $j->{$_}{$key} } grep { exists $j->{$_} } qw/id title module/ };
143             }
144             return $a;
145             }
146              
147              
148             sub get_departements {
149             my $self = shift;
150             my $xml = $self->get('/Base/Department/');
151             my $a = $self->xml2obj($xml)->{departments}{department}; # array
152             $self->filter_fields($a);
153             }
154              
155              
156              
157              
158             sub get_ticket_statuses {
159             my $self = shift;
160             my $xml = $self->get('/Tickets/TicketStatus/');
161             my $a = $self->xml2obj($xml)->{ticketstatuses}{ticketstatus}; # array
162             $self->filter_fields($a);
163             }
164              
165              
166             sub get_ticket_priorities {
167             my $self = shift;
168             my $xml = $self->get('/Tickets/TicketPriority/');
169             my $a = $self->xml2obj($xml)->{ticketpriorities}{ticketpriority}; # array
170             $self->filter_fields($a);
171             }
172              
173              
174             sub get_ticket_types {
175             my $self = shift;
176             my $xml = $self->get('/Tickets/TicketType/');
177             my $a = $self->xml2obj($xml)->{tickettypes}{tickettype}; # array
178             $self->filter_fields($a);
179             }
180              
181              
182             sub get_staff {
183             my $self = shift;
184             my $xml = $self->get('/Base/Staff/');
185             $self->xml2obj($xml)->{staffusers}{staff}; # array
186             }
187              
188             1;
189              
190             __END__