]> git.uio.no Git - usit-rt.git/blame - docs/automating_rt.pod
Merge branch 'master' of git.uio.no:usit-rt
[usit-rt.git] / docs / automating_rt.pod
CommitLineData
320f0092
MKG
1=head1 Automating Tasks in RT
2
3As RT tickets are created, worked on, and resolved, there are sometimes
4updates or notifications that have defined rules and could be automatic.
5These might include increasing ticket priority over time so tickets don't
6get lost, resolving old tickets that haven't had any activity for a period of
7time, or sending email notifications based on some ticket criteria like
8being 3 days old and still having a status of new.
9
10The tool for automating RT tasks is L<rt-crontool>. It's designed to be
11run from the cron scheduler and accepts a set of parameters that define
12what RT objects it should operate on and what it should do. The sections
13below describe some common L<rt-crontool> tasks as examples of the
14different ways you can automate tasks.
15
16All of the options for L<rt-crontool> are documented with the tool itself:
17
18 $ perldoc bin/rt-crontool
19
20and on the Best Practical web site.
21
22=head2 Running C<rt-crontool>
23
24As you'll see in the examples below, this tool gives full access to RT.
25To manage the scope of changes that could be performed by the tool, we
26recommended creating a dedicated unix user with limited privileges for
27this purpose. Then create a user in RT with just enough access to
28perform the changes you need to automate, and set the "Unix login" field
29of the RT user to the username of the unix user you created. See the
30L<rt-crontool> documentation for more information.
31
32=head2 Testing Tips
33
34When setting up a new automated crontool job, keep in mind that you might be
35modifying a large number of tickets, especially the first time you run it.
36Changes to tickets can trigger scrips just like the same change made via
37the user interface. For example, changing the status to resolved will trigger
38the 'On Resolve' scrips, which often means sending email. Depending on the
39modification, you could end up sending a lot of email or triggering other
40actions.
41
42You can test your TicketSQL search queries in the RT web interface
43(using the Advanced tab of ticket search), and use bulk update if you
44want to prepare things for your new automated job. You can also disable
45scrips which you wish to avoid, or turn off outgoing mail with the
46L<RT_Config.pm/"$MailCommand"> option. This can be useful if you want to
47clean up older tickets without sending notifications to requestors for
48tickets that were resolved years ago.
49
50To help with debugging, the C<--verbose> option will give you more output.
51The C<--log> option accepts all of the valid log levels for RT and allows
52you to change the logging level just for the automated job. While testing,
53it's often convenient to set:
54
55 --log debug
56
57to see what's happening.
58
59=head1 A Simple Search
60
61Starting with a simple example, this command performs a search and
62displays output, but doesn't do anything to the returned tickets.
63This can be useful for safely testing search criteria.
64
65 bin/rt-crontool --search RT::Search::FromSQL \
66 --search-arg "Owner = 'root'" \
67 --action RT::Action \
68 --verbose \
69 --log debug
70
71The C<--search> argument sets the search module RT should use, in this
72case L<RT::Search::FromSQL> which processes TicketSQL. The second
73argument, C<--search-arg>, is the search query to use. These are
74the same queries you create in the RT search interface, so can use
75the RT web UI to refine your queries before setting up your job.
76
77The C<--action> argument is set to L<RT::Action> which is the base class
78for RT actions. Since this class doesn't perform any action itself, this
79command will just output the results of the TicketSQL search.
80
81=head1 Auto-resolve Aged Tickets
82
83You can auto-set status based on any criteria you can define in
84a TicketSQL statement. For example, this command will resolve all
85active tickets that haven't been acted on in a month or more:
86
87 bin/rt-crontool --search RT::Search::FromSQL \
88 --search-arg "(Status != 'resolved' AND Status != 'rejected') \
89 AND LastUpdated <= '1 month ago'" \
90 --action RT::Action::SetStatus \
91 --action-arg resolved
92
93The search is similar to the previous example with a slightly more
94complicated search argument. Note that since LastUpdated is treated as
95a timestamp (which increases over time) C<LastUpdated <= '1 month ago'>
96means "the timestamp when it was updated is before the timestamp one
97month ago" and not "updated less than a month ago."
98
99The C<--action> in this case uses the L<RT::Action::SetStatus> module
100with an C<--action-arg> of C<resolved>. For each of the tickets
101returned from the search query, the status is set to resolved. When
102setting up automated tasks, you can use actions provided as part of RT,
103actions available from extensions, or actions you create yourself.
104
105As noted previously, the normal RT rules apply when running actions
106with L<rt-crontool>, so for this example applicable 'On Resolve'
107scrips will run. If a ticket has unresolved dependencies, it will
108log an error since tickets can't be resolved until dependencies are
109resolved. Also, the status argument must be valid for the lifecycle of
110the selected tickets, and the transition must be allowed.
111
112=head1 Commenting and Corresponding on a Ticket
113
114The following command records a comment on all tickets returned from the
115query -- in this case, tickets that are new and unowned after 3 days.
116
117 bin/rt-crontool --search RT::Search::FromSQL \
118 --search-arg "Owner = 'Nobody' AND Status = 'new' \
119 AND Created < '3 days ago'" \
120 --action RT::Action::RecordComment \
121 --template 'Unowned tickets'
122
123The L<RT::Action::RecordComment> action does just that, it records a
124comment just like replying to a comment email or commenting in the
125RT UI. It uses the global RT template defined by C<--template>, so you
126could put whatever you like in that template. For example:
127
128 Subject: {$Ticket->id} new and unowned
129 RT-Send-Cc: support-backup@example.com
130
131 Ticket {$Ticket->id} is still new and unowned after 3 days!
132
133You can set up a similar command to send a reply rather than a comment
134using the L<RT::Action::RecordCorrespondence> module.
135
136=head1 Sending Notifications
137
138While the example above sends notifications as a side-effect of recording
139a comment, you can also send notifications directly.
140
141 bin/rt-crontool --search RT::Search::FromSQL \
142 --search-arg "(Status != 'resolved' AND Status != 'rejected') \
143 AND Queue = 'Project Work'" \
144 --condition RT::Condition::Overdue \
145 --action RT::Action::NotifyGroup \
146 --action-arg 'project-manager@example.com' \
147 --template 'Overdue task'
148
149This example shows the C<--condition> argument and the
150L<RT::Condition::Overdue> module, which returns true if the current
151time (the time the cron job is running) is past the Due date on the
152ticket. Like the C<--action> argument, you can use conditions
153provided with RT, added from extensions, or conditions you have
154created.
155
156L<RT::Action::NotifyGroup>, despite the "Group" in the name, can accept a
157bare email address or list of addresses as the action argument and it will
158send mail to them. A combination of email addresses and group names separated
159by commas also works. RT usernames are valid unless they conflict with group
160names.
161
162The action sends email, but unlike comment and correspond above, it
163doesn't record a transaction in the ticket history.
164
165=head1 Escalating Priority
166
167RT has a built-in ticket priority system with priority values from
1680 to 99. Depending on how you configure your queues, you can set 1 as the
169top priority with lower numbers meaning more important, or 99 can be the
170top priority with higher numbers meaning more important. You can set this
171in your queue configuration at Tools -> Configuration -> Queues. On the queue
172configuration page, set "Priority starts at" and "Over time, priority moves
173toward".
174
175Whichever scheme you choose, RT's L<RT::Action::EscalatePriority> can
176escalate the priority over time so tickets that are closer to their due
177date and are still not resolved have priority escalated automatically.
178
179This command escalates tickets in a designated queue:
180
181 bin/rt-crontool --search RT::Search::ActiveTicketsInQueue \
182 --search-arg "General" \
183 --action RT::Action::EscalatePriority
184
185The C<--search-arg> is the name of the queue in which to escalate tickets.
186As shown in previous examples, you can also set your criteria using a
187TicketSQL query as well:
188
189 bin/rt-crontool --search RT::Search::FromSQL \
190 --search-arg "(Status='new' OR Status='open') AND Due > 'Jan 1, 1970'" \
191 --action RT::Action::EscalatePriority
192
193This example will find new and open tickets in all queues, but will skip tickets
194with no explicit due dates set. Maybe you only want to bump the priority on tasks
195that have to be done by a certain date.
196
197L<RT::Action::LinearEscalate> is an alternative escalation module that
198handles the "Due date not set" condition for you. It also offers some
199configuration options to control whether a transaction is recorded on the
200ticket and whether LastUpdated is modified.
201
202=head1 Transactions
203
204Many actions and conditions are also used in RT in scrips and may require
205a transaction in addition to a ticket. For such cases, L<rt-crontool>
206provides a C<--transaction> argument to designate a transaction. Valid
207values are C<first>, C<last>, and C<all> and these are relative to the
208current ticket being processed. C<first> and C<last> are the first and
209last transaction on the ticket. Be careful with the C<all> option since
210it will run the action on all transactions for the ticket.
211
212Since actions and conditions can be used in different contexts, you
213may need to provide a transaction object even if it doesn't seem
214necessary for your automated job. If you're seeing errors about
215a missing transaction, setting C<--transaction> to C<first> or
216C<last> is usually safe and will resolve the error.
217
218You can also target specific transaction types with C<--transation-type>.
219This argument accepts one or more transaction types as a comma-separated
220list.
221
222Using these options together, you can set up a command that sets the
223appropriate transaction object for your conditions and actions. For
224example, if you had an action you wanted to perform based on the content
225of the last reply on stalled tickets, you could do something like:
226
227 bin/rt-crontool --search RT::Search::FromSQL \
228 --search-arg "Status = 'stalled' AND Queue = 'General'" \
229 --action RT::Action::CheckLastCorrespond \
230 --transaction last \
231 --transaction-type Correspond
232
233
234=cut