.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "RT::Client::REST 3pm" .TH RT::Client::REST 3pm "2018-12-26" "perl v5.28.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" RT::Client::REST \- Client for RT using REST API .SH "VERSION" .IX Header "VERSION" version 0.56 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& use Error qw(:try); \& use RT::Client::REST; \& \& my $rt = RT::Client::REST\->new( \& server => \*(Aqhttp://example.com/rt\*(Aq, \& timeout => 30, \& ); \& \& try { \& $rt\->login(username => $user, password => $pass); \& } catch Exception::Class::Base with { \& die "problem logging in: ", shift\->message; \& }; \& \& try { \& # Get ticket #10 \& $ticket = $rt\->show(type => \*(Aqticket\*(Aq, id => 10); \& } catch RT::Client::REST::UnauthorizedActionException with { \& print "You are not authorized to view ticket #10\en"; \& } catch RT::Client::REST::Exception with { \& # something went wrong. \& }; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBRT::Client::REST\fR is \fB/usr/bin/rt\fR converted to a Perl module. I needed to implement some \s-1RT\s0 interactions from my application, but did not feel that invoking a shell command is appropriate. Thus, I took \fBrt\fR tool, written by Abhijit Menon-Sen, and converted it to an object-oriented Perl module. .SH "USAGE NOTES" .IX Header "USAGE NOTES" This \s-1API\s0 mimics that of 'rt'. For a more OO-style APIs, please use RT::Client::REST::Object\-derived classes: RT::Client::REST::Ticket and RT::Client::REST::User. not implemented yet). .SH "METHODS" .IX Header "METHODS" .IP "new ()" 4 .IX Item "new ()" The constructor can take these options (note that these can also be called as their own methods): .RS 4 .IP "\fBserver\fR" 2 .IX Item "server" \&\fBserver\fR is a \s-1URI\s0 pointing to your \s-1RT\s0 installation. .Sp If you have already authenticated against \s-1RT\s0 in some other part of your program, you can use \fB_cookie\fR parameter to supply an object of type \fBHTTP::Cookies\fR to use for credentials information. .IP "\fBtimeout\fR" 2 .IX Item "timeout" \&\fBtimeout\fR is the number of seconds \s-1HTTP\s0 client will wait for the server to respond. Defaults to LWP::UserAgent's default timeout, which is 180 seconds (please check LWP::UserAgent's documentation for accurate timeout information). .IP "\fBbasic_auth_cb\fR" 2 .IX Item "basic_auth_cb" This callback is to provide the \s-1HTTP\s0 client (based on LWP::UserAgent) with username and password for basic authentication. It takes the same arguments as \f(CW\*(C`get_basic_credentials()\*(C'\fR of LWP::UserAgent and returns username and password: .Sp .Vb 5 \& $rt\->basic_auth_cb( sub { \& my ($realm, $uri, $proxy) = @_; \& # do some evil things \& return ($username, $password); \& } .Ve .IP "\fBlogger\fR" 2 .IX Item "logger" A logger object. It should be able to \fBdebug()\fR, \fBinfo()\fR, \fBwarn()\fR and \&\fBerror()\fR. It is not widely used in the code (yet), and so it is mostly useful for development. .Sp Something like this will get you started: .Sp .Vb 8 \& use Log::Dispatch; \& my $log = Log::Dispatch\->new( \& outputs => [ [ \*(AqScreen\*(Aq, min_level => \*(Aqdebug\*(Aq ] ], \& ); \& my $rt = RT::Client::REST\->new( \& server => ... etc ... \& logger => $log \& ); .Ve .RE .RS 4 .RE .IP "login (username => 'root', password => 'password') =item login (my_userfield => 'root', my_passfield => 'password')" 4 .IX Item "login (username => 'root', password => 'password') =item login (my_userfield => 'root', my_passfield => 'password')" Log in to \s-1RT.\s0 Throws an exception on error. .Sp Usually, if the other side uses basic \s-1HTTP\s0 authentication, you do not have to log in, but rather provide \s-1HTTP\s0 username and password instead. See \fBbasic_auth_cb\fR above. .ie n .IP "show (type => $type, id => $id)" 4 .el .IP "show (type => \f(CW$type\fR, id => \f(CW$id\fR)" 4 .IX Item "show (type => $type, id => $id)" Return a reference to a hash with key-value pair specifying object \f(CW$id\fR of type \f(CW$type\fR. The keys are the names of \s-1RT\s0's fields. Keys for custom fields are in the form of \*(L"\s-1CF\s0.{\s-1CUST_FIELD_NAME\s0}\*(R". .ie n .IP "edit (type => $type, id => $id, set => { status => 1 })" 4 .el .IP "edit (type => \f(CW$type\fR, id => \f(CW$id\fR, set => { status => 1 })" 4 .IX Item "edit (type => $type, id => $id, set => { status => 1 })" Set fields specified in parameter \fBset\fR in object \f(CW$id\fR of type \&\f(CW$type\fR. .ie n .IP "create (type => $type, set => \e%params, text => $text)" 4 .el .IP "create (type => \f(CW$type\fR, set => \e%params, text => \f(CW$text\fR)" 4 .IX Item "create (type => $type, set => %params, text => $text)" Create a new object of type \fB\f(CB$type\fB\fR and set initial parameters to \fB\f(CB%params\fB\fR. For a ticket object, 'text' parameter can be supplied to set the initial text of the ticket. Returns numeric \s-1ID\s0 of the new object. If numeric \s-1ID\s0 cannot be parsed from the response, \fBRT::Client::REST::MalformedRTResponseException\fR is thrown. .ie n .IP "search (type => $type, query => $query, %opts)" 4 .el .IP "search (type => \f(CW$type\fR, query => \f(CW$query\fR, \f(CW%opts\fR)" 4 .IX Item "search (type => $type, query => $query, %opts)" Search for object of type \f(CW$type\fR by using query \f(CW$query\fR. For example: .Sp .Vb 5 \& # Find all stalled tickets \& my @ids = $rt\->search( \& type => \*(Aqticket\*(Aq, \& query => "Status = \*(Aqstalled\*(Aq", \& ); .Ve .Sp \&\f(CW%opts\fR is a list of key-value pairs: .RS 4 .IP "\fBorderby\fR" 4 .IX Item "orderby" The value is the name of the field you want to sort by. Plus or minus sign in front of it signifies ascending order (plus) or descending order (minus). For example: .Sp .Vb 6 \& # Get all stalled tickets in reverse order: \& my @ids = $rt\->search( \& type => \*(Aqticket\*(Aq, \& query => "Status = \*(Aqstalled\*(Aq", \& orderby => \*(Aq\-id\*(Aq, \& ); .Ve .RE .RS 4 .Sp \&\f(CW\*(C`search\*(C'\fR returns the list of numeric IDs of objects that matched your query. You can then use these to retrieve object information using \f(CW\*(C`show()\*(C'\fR method: .Sp .Vb 8 \& my @ids = $rt\->search( \& type => \*(Aqticket\*(Aq, \& query => "Status = \*(Aqstalled\*(Aq", \& ); \& for my $id (@ids) { \& my ($ticket) = $rt\->show(type => \*(Aqticket\*(Aq, id => $id); \& print "Subject: ", $ticket\->{Subject}, "\en"; \& } .Ve .RE .ie n .IP "comment (ticket_id => $id, message => $message, %opts)" 4 .el .IP "comment (ticket_id => \f(CW$id\fR, message => \f(CW$message\fR, \f(CW%opts\fR)" 4 .IX Item "comment (ticket_id => $id, message => $message, %opts)" Comment on a ticket with \s-1ID\s0 \fB\f(CB$id\fB\fR. Optionally takes arguments \fBcc\fR and \fBbcc\fR which are references to lists of e\-mail addresses and \fBattachments\fR which is a list of filenames to be attached to the ticket. .Sp .Vb 5 \& $rt\->comment( \& ticket_id => 5, \& message => "Wild thing, you make my heart sing", \& cc => [qw(dmitri@localhost some@otherdude.com)], \& ); .Ve .ie n .IP "correspond (ticket_id => $id, message => $message, %opts)" 4 .el .IP "correspond (ticket_id => \f(CW$id\fR, message => \f(CW$message\fR, \f(CW%opts\fR)" 4 .IX Item "correspond (ticket_id => $id, message => $message, %opts)" Add correspondence to ticket \s-1ID\s0 \fB\f(CB$id\fB\fR. Takes optional \fBcc\fR, \&\fBbcc\fR, and \fBattachments\fR parameters (see \f(CW\*(C`comment\*(C'\fR above). .ie n .IP "get_attachment_ids (id => $id)" 4 .el .IP "get_attachment_ids (id => \f(CW$id\fR)" 4 .IX Item "get_attachment_ids (id => $id)" Get a list of numeric attachment IDs associated with ticket \f(CW$id\fR. .ie n .IP "get_attachments_metadata (id => $id)" 4 .el .IP "get_attachments_metadata (id => \f(CW$id\fR)" 4 .IX Item "get_attachments_metadata (id => $id)" Get a list of the metadata related to every attachment of the ticket <$id> Every member of the list is a hashref with the shape: .Sp .Vb 6 \& { \& id => $attachment_id, \& Filename => $attachment_filename, \& Type => $attachment_type, \& Size => $attachment_size, \& } .Ve .ie n .IP "get_attachment (parent_id => $parent_id, id => $id, undecoded => $bool)" 4 .el .IP "get_attachment (parent_id => \f(CW$parent_id\fR, id => \f(CW$id\fR, undecoded => \f(CW$bool\fR)" 4 .IX Item "get_attachment (parent_id => $parent_id, id => $id, undecoded => $bool)" Returns reference to a hash with key-value pair describing attachment \&\f(CW$id\fR of ticket \f(CW$parent_id\fR. (parent_id because \*(-- who knows? \*(-- maybe attachments won't be just for tickets anymore in the future). .Sp If the option undecoded is set to a true value, the attachment will be returned verbatim and undecoded (this is probably what you want with images and binary data). .ie n .IP "get_links (type => $type, id => $id)" 4 .el .IP "get_links (type => \f(CW$type\fR, id => \f(CW$id\fR)" 4 .IX Item "get_links (type => $type, id => $id)" Get link information for object of type \f(CW$type\fR whose id is \f(CW$id\fR. If type is not specified, 'ticket' is used. .ie n .IP "get_transaction_ids (parent_id => $id, %opts)" 4 .el .IP "get_transaction_ids (parent_id => \f(CW$id\fR, \f(CW%opts\fR)" 4 .IX Item "get_transaction_ids (parent_id => $id, %opts)" Get a list of numeric IDs associated with parent \s-1ID\s0 \f(CW$id\fR. \f(CW%opts\fR have the following options: .RS 4 .IP "\fBtype\fR" 2 .IX Item "type" Type of the object transactions are associated with. Defaults to \*(L"ticket\*(R" (I do not think server-side supports anything else). This is designed with the eye on the future, as transactions are not just for tickets, but for other objects as well. .IP "\fBtransaction_type\fR" 2 .IX Item "transaction_type" If not specified, IDs of all transactions are returned. If set to a scalar, only transactions of that type are returned. If you want to specify more than one type, pass an array reference. .Sp Transactions may be of the following types (case-sensitive): .RS 2 .IP "AddLink" 2 .IX Item "AddLink" .PD 0 .IP "AddWatcher" 2 .IX Item "AddWatcher" .IP "Comment" 2 .IX Item "Comment" .IP "Correspond" 2 .IX Item "Correspond" .IP "Create" 2 .IX Item "Create" .IP "CustomField" 2 .IX Item "CustomField" .IP "DeleteLink" 2 .IX Item "DeleteLink" .IP "DelWatcher" 2 .IX Item "DelWatcher" .IP "EmailRecord" 2 .IX Item "EmailRecord" .IP "Give" 2 .IX Item "Give" .IP "Set" 2 .IX Item "Set" .IP "Status" 2 .IX Item "Status" .IP "Steal" 2 .IX Item "Steal" .IP "Take" 2 .IX Item "Take" .IP "Told" 2 .IX Item "Told" .RE .RS 2 .RE .RE .RS 4 .RE .ie n .IP "get_transaction (parent_id => $id, id => $id, %opts)" 4 .el .IP "get_transaction (parent_id => \f(CW$id\fR, id => \f(CW$id\fR, \f(CW%opts\fR)" 4 .IX Item "get_transaction (parent_id => $id, id => $id, %opts)" .PD Get a hashref representation of transaction \f(CW$id\fR associated with parent object \f(CW$id\fR. You can optionally specify parent object type in \&\f(CW%opts\fR (defaults to 'ticket'). .ie n .IP "merge_tickets (src => $id1, dst => $id2)" 4 .el .IP "merge_tickets (src => \f(CW$id1\fR, dst => \f(CW$id2\fR)" 4 .IX Item "merge_tickets (src => $id1, dst => $id2)" Merge ticket \fB\f(CB$id1\fB\fR into ticket \fB\f(CB$id2\fB\fR. .ie n .IP "link_tickets (src => $id1, dst => $id2, link_type => $type)" 4 .el .IP "link_tickets (src => \f(CW$id1\fR, dst => \f(CW$id2\fR, link_type => \f(CW$type\fR)" 4 .IX Item "link_tickets (src => $id1, dst => $id2, link_type => $type)" Create a link between two tickets. A link type can be one of the following: .RS 4 .IP "\(bu" 2 DependsOn .IP "\(bu" 2 DependedOnBy .IP "\(bu" 2 RefersTo .IP "\(bu" 2 ReferredToBy .IP "\(bu" 2 HasMember .IP "\(bu" 2 MemberOf .RE .RS 4 .RE .ie n .IP "unlink_tickets (src => $id1, dst => $id2, link_type => $type)" 4 .el .IP "unlink_tickets (src => \f(CW$id1\fR, dst => \f(CW$id2\fR, link_type => \f(CW$type\fR)" 4 .IX Item "unlink_tickets (src => $id1, dst => $id2, link_type => $type)" Remove a link between two tickets (see \fB\fBlink_tickets()\fB\fR) .ie n .IP "take (id => $id)" 4 .el .IP "take (id => \f(CW$id\fR)" 4 .IX Item "take (id => $id)" Take ticket \f(CW$id\fR. This will throw \f(CW\*(C`RT::Client::REST::AlreadyTicketOwnerException\*(C'\fR if you are already the ticket owner. .ie n .IP "untake (id => $id)" 4 .el .IP "untake (id => \f(CW$id\fR)" 4 .IX Item "untake (id => $id)" Untake ticket \f(CW$id\fR. This will throw \f(CW\*(C`RT::Client::REST::AlreadyTicketOwnerException\*(C'\fR if Nobody is already the ticket owner. .ie n .IP "steal (id => $id)" 4 .el .IP "steal (id => \f(CW$id\fR)" 4 .IX Item "steal (id => $id)" Steal ticket \f(CW$id\fR. This will throw \f(CW\*(C`RT::Client::REST::AlreadyTicketOwnerException\*(C'\fR if you are already the ticket owner. .SH "EXCEPTIONS" .IX Header "EXCEPTIONS" When an error occurs, this module will throw exceptions. I recommend using Error.pm's \fBtry{}\fR mechanism to catch them, but you may also use simple \fBeval{}\fR. The former will give you flexibility to catch just the exceptions you want. .PP Please see RT::Client::REST::Exception for the full listing and description of all the exceptions. .SH "LIMITATIONS" .IX Header "LIMITATIONS" Beginning with version 0.14, methods \f(CW\*(C`edit()\*(C'\fR and \f(CW\*(C`show()\*(C'\fR only support operating on a single object. This is a conscious departure from semantics offered by the original tool, as I would like to have a precise behavior for exceptions. If you want to operate on a whole bunch of objects, please use a loop. .SH "DEPENDENCIES" .IX Header "DEPENDENCIES" The following modules are required: .IP "\(bu" 2 Error .IP "\(bu" 2 Exception::Class .IP "\(bu" 2 \&\s-1LWP\s0 .IP "\(bu" 2 HTTP::Cookies .IP "\(bu" 2 HTTP::Request::Common .SH "SEE ALSO" .IX Header "SEE ALSO" LWP::UserAgent, RT::Client::REST::Exception .SH "BUGS" .IX Header "BUGS" Most likely. Please report. .SH "VARIOUS NOTES" .IX Header "VARIOUS NOTES" \&\fBRT::Client::REST\fR does not (at the moment, see \s-1TODO\s0 file) retrieve forms from \&\s-1RT\s0 server, which is either good or bad, depending how you look at it. .SH "AUTHORS" .IX Header "AUTHORS" Original /usr/bin/rt was written by Abhijit Menon-Sen . rt was later converted to this module by Dmitri Tikhonov . In January of 2008, Damien \*(L"dams\*(R" Krotkine joined as the project's co-maintainer. \s-1JLMARTIN\s0 has become co-maintainer as of March 2010. \&\s-1SRVSH\s0 became a co-maintainer in November 2015. .SH "AUTHORS" .IX Header "AUTHORS" .IP "\(bu" 4 Abhijit Menon-Sen .IP "\(bu" 4 Dmitri Tikhonov .IP "\(bu" 4 Damien \*(L"dams\*(R" Krotkine .IP "\(bu" 4 Dean Hamstead .IP "\(bu" 4 Miquel Ruiz .IP "\(bu" 4 \&\s-1JLMARTIN\s0 .IP "\(bu" 4 \&\s-1SRVSH\s0 .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2018 by Dmitri Tikhonov. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.