The management of my current place of business wants to have high priority tickets updated on a regular basis. RT doesn't have anything built in to accomplish this, which is where the RT API comes in handy. Below is my script, which is based on Tim Bishop's rt-escalate. It will send email to a set of addresses whenever a ticket of a given priority has not been updated within a specific threshold.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | #!/usr/bin/env perl my $criticalPriority = 3; # Minimum priority to check my $criticalOffset = 2 * 60 * 60; # Time since update my $fromAddr = 'root@example.com'; # Who mail should appear to come from my $trackpath = "/tmp"; # Where to place tracking files my @toAddrs = (); # You shouldn't change this. Use command-line arguments. my @queues; # You shouldn't change this. Use command-line arguments. my $is_test = 0; my $show_help = 0; # Location of RT3's libs use lib ("/opt/rt3/lib", "/opt/rt3/local/lib"); use strict; use warnings; use Getopt::Long; GetOptions( 'queue=s' => \@queues, 'to=s' => \@toAddrs, 'threshold=i' => \$criticalOffset, 'priority=i' => \$criticalPriority, 'test' => \$is_test, 'help' => \$show_help, ); if ($show_help){ print "\n$0 --threshold seconds --priority number [options]... --threshold # Number of seconds before next update --priority # Priority to check --to # Who should get mailed, you can specify multiple --queue queuename # Searches all by default, you can specify multiple --test # Don't send mail, just print message --help # Show this screen \n"; exit 1; } # Pull in the RT stuff package RT; use RT::Interface::CLI qw(CleanEnv); use Mail::Mailer; use POSIX qw(floor); use Time::Piece; # Clean our the environment CleanEnv(); # Load the RT configuration RT::LoadConfig(); # Initialise RT RT::Init(); # If no queues given, get all enabled queues if(!@queues) { my $queues = new RT::Queues($RT::SystemUser); $queues->LimitToEnabled(); foreach my $queue (@{$queues->ItemsArrayRef()}) { push @queues, $queue->Name; } } #Load tracking hash for repeat notification avoidance my %th; # tracking hash my @idlist; # used to strip tickets that are closed my $trackfile = "$trackpath/NotifyTimed.$criticalPriority"; open(FH, "<$trackfile"); while(<FH>){ my @parts = split; $th{$parts[0]} = $parts[1]; } close(FH); foreach my $queuename (@queues) { my $queue = new RT::Queue($RT::SystemUser); $queue->Load($queuename); # Get hold of new, open, and stalled tickets only my $tickets = new RT::Tickets($RT::SystemUser); $tickets->LimitStatus(VALUE => 'open'); $tickets->LimitStatus(VALUE => 'new'); $tickets->LimitStatus(VALUE => 'stalled'); $tickets->LimitPriority(OPERATOR => '=', VALUE => $criticalPriority); $tickets->LimitQueue(VALUE => $queue->Id); while (my $ticket = $tickets->Next) { my $ticketdt = Time::Piece->strptime($ticket->LastUpdated, "%Y-%m-%d %H:%M:%S"); my $now = localtime; my $dt = $now - $criticalOffset; my $will_notify = 0; if ($dt->epoch > $ticketdt->epoch){ my $minutes = floor(($now->epoch - $ticketdt->epoch) / 60); my $owner = $ticket->OwnerObj; # Keep track of ids to strip old ones push(@idlist, $ticket->Id); # Only notify once if (exists $th{$ticket->Id}){ if ($th{$ticket->Id} < $ticketdt->epoch){ $th{$ticket->Id} = $ticketdt->epoch; $will_notify = 1; } } else { $th{$ticket->Id} = $ticketdt->epoch; $will_notify = 1; } # Prepare report my $mailmsg = '<html> <body> <p>Ticket <a href="https://rt.wbsconnect.com/Ticket/Display.html?id=' .$ticket->Id.'">'.$ticket->Id.'</a> needs to be updated.</p> <p>Subject: '.$ticket->Subject.'</p> <p>Owner: '.$owner->RealName.'</p> <p>Status: '.$ticket->Status.'</p> <p>Priority: '.$ticket->Priority.'</p> <p>Minutes since last update: '.$minutes.'</p> </body> </html>'; # Send email, if this isn't a repeat or test next if not $will_notify; if ($is_test){ print $mailmsg; } else { foreach (@toAddrs){ my $mailer = Mail::Mailer->new; $mailer->open({ 'From' => $fromAddr, 'To' => $_, 'Subject' => "Update Required: Priority " .$ticket->Priority." ticket " .$ticket->Id." needs to be updated", 'MIME-Version' => "1.0", 'Content-Type' => "text/html", }); print $mailer $mailmsg; $mailer->close(); } } } } } # Strip old ids from tracking hash my %nth; # New tracking hash foreach(@idlist){ $nth{$_} = $th{$_}; } # Write tracking hash to file for future use open(FH, ">$trackfile"); while((my $key, my $value) = each(%nth)){ print FH $key, " ", $value, "\n"; } close(FH); # Disconnect before we finish off $RT::Handle->Disconnect(); exit 0; |
Usage is as such, assuming the script is named NotifyTimed.pl.
NotifyTimed.pl --threshold seconds --priority number [options]...
--threshold # Number of seconds before next update
--priority # Priority to check
--to # Who should get mailed, you can specify multiple
--queue queuename # Searches all by default, you can specify multiple
--test # Don't send mail, just print message
--help # Show this screen
To have this be useful, you'll want to set up a cron job. This was developed and tested on RT 3.8.1. It should work fine on many older and newer RT versions.
Posted by
on December 30, 2008
at 12:06
