#!/usr/local/bin/perl -w # RT3 reminder script # # This script will remind people about tickets they have not responded to # or dealt with in a reasonable length of time. In its normal mode it will # tell ticket owners about tickets which have exceeded a given priority # (see the %pri hash below). It also has the ability to tell ticket owners # about all their open or new tickets, with or without stalled tickets. # # This is best used with another script to escalate priorities automatically. # # The intended use is to run with no flags daily, with the -a flag weekly # and with the -A flag monthly. Or similar. # # Written by T.D.Bishop@kent.ac.uk, July 2003. ### Configuration # Mappings of users to addresses # This overrides addresses in the RT database # The most useful case is setting an address for Nobody my(%map) = ( 'Nobody' => 'cs-sysadmin@kent.ac.uk', 'root' => 'cs-sysadmin@kent.ac.uk', ); # Queue to operate on my($queuename) = 'cs-syshelp'; # Each state can have a priority associated with it. # When a ticket in that state passes the given priority it is added to # the list to be sent out. my(%pri) = ( 'new' => 2, 'open' => 7, ); # The length at which lines will be truncated. 80, or thereabouts looks # best for most people. Setting to 0 will stop lines being truncated. my($linelen) = 80; # Location of RT3's libs use lib ("/usr/local/packages/rt/lib", "/usr/local/packages/rt/local/lib"); # Address emails should originate from # (don't forget to escape the @) my($from) = "cs-sysadmin\@kent.ac.uk"; # Path to sendmail and flags my($sendmail) = "/usr/lib/sendmail -t"; ### Code use strict; use Carp; my($showall) = 0; my($showmost) = 0; # Process command line arguments foreach(@ARGV) { if (/^-a$/) { $showmost = 1; } elsif (/^-A$/) { $showall = 1; } else { print STDERR "Usage: rt-remind [-a] [-A] [-h]\n"; print STDERR " -a show all open or new tickets\n"; print STDERR " -A show all open, new, or stalled tickets\n"; print STDERR " -h show this help\n"; exit 1; } } # Pull in the RT stuff package RT; use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc); # Clean our the environment CleanEnv(); # Load the RT configuration RT::LoadConfig(); # Initialise RT RT::Init(); # Drop any setgid permissions we might have RT::DropSetGIDPermissions(); use RT::Date; use RT::Queue; use RT::Tickets; # Load in the queue my $queue = new RT::Queue($RT::SystemUser); $queue->Load($queuename); my $now = new RT::Date($RT::SystemUser); $now->SetToNow(); # Get hold of the tickets we're after, sorted by priority my $tickets = new RT::Tickets($RT::SystemUser); $tickets->LimitStatus(VALUE => 'new'); $tickets->LimitStatus(VALUE => 'open'); $tickets->LimitStatus(VALUE => 'stalled') if $showall; $tickets->LimitQueue(VALUE => $queue->Id); $tickets->OrderBy(FIELD => 'Priority', ORDER => 'DESC'); my $user = RT::User->new($RT::SystemUser); my(%TicketStore); # Sort tickets in to lists for each owner while (my $Ticket = $tickets->Next) { $user->Load($Ticket->Owner); my($email) = $map{$user->Name}; $email = $user->EmailAddress if not defined $email; push @{$TicketStore{$email}}, $Ticket; } # Process tickets for each owner foreach my $email (keys %TicketStore) { my($t) = $TicketStore{$email}; &doOwner($email, @$t); } # Disconnect before we finish off $RT::Handle->Disconnect(); exit 0; # Subroutine to generate a messages for a given owner and set of tickets. sub doOwner() { my($email, @tickets) = @_; my($msg); $msg .= "From: $from\n"; $msg .= "To: $email\n"; $msg .= "Subject: cs-syshelp outstanding tickets\n"; $msg .= "\n"; if($showall) { $msg .= "This is a summary of all open, new, or stalled tickets assigned to:\n"; } elsif($showmost) { $msg .= "This is a summary of all open or new tickets assigned to:\n"; } else { $msg .= "These tickets are now considered important and are assigned to:\n"; } $msg .= "\n"; $msg .= " $email\n"; $msg .= "\n"; # Generate heading $msg .= sprintf "%5s %-7s %3s %-13s %-30s\n", "Id", "Status", "Pri", "Date", "Subject"; # We might not want to print the message if there are no tickets my($printmsg) = 0; # Look through tickets foreach my $Ticket (@tickets) { # Only add ticket if it's over the priority, or we're in -a or -A if($Ticket->Priority > $pri{$Ticket->Status} || $showmost || $showall) { $printmsg = 1; # Use our own date formatting routine my($date) = &formatDate($Ticket->CreatedObj->Unix); my($line) = sprintf "%5d %-7s %3d %-13s %-30s", $Ticket->Id, $Ticket->Status, $Ticket->Priority, $date, $Ticket->Subject; # Truncate lines if required if($linelen) { $line = substr($line, 0, $linelen); } $msg .= "$line\n"; } } # Send the message if($printmsg) { open(SENDMAIL, "|$sendmail") || die "Error sending mail: $!"; print SENDMAIL $msg; close(SENDMAIL); } } # Formats a date like: Thu 10-07-03 # Designed to be consice yet useful sub formatDate() { my($unixtime) = @_; my(@days) = ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ); # Return an empty string if we haven't been given a time return "" if $unixtime <= 0; my($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($unixtime); return sprintf "%s %02d-%02d-%02d", $days[$wday], $mday, $mon+1, $year%100; }