[rt-users] Offering: rt-remind

Goddard Lee lee.goddard at easa.eu.int
Mon Dec 12 07:10:45 EST 2005

Today I found rt-remind on the BP FTP server, and made a few small mods, included below.

	Use Getopt::Long.
	use Pod::Usage
	Take (multiple) queue names on the command line.
	Take priority-defaults for mail-send on the command line
	&formatDate returns ISO-formatted date
	Added this POD

Lee Goddard
Internet Application Analysis/Development
European Aviation Safety Agency
Administrative Directorate

E: Lee.Goddard at EASA.EU.int 
T: +49 221 89990 3221
F: +49 221 89990 3721
W: www.easa.eu.int
:: Ottoplat 1, D-50679 Köln, Germany


#!/usr/bin/perl -w

our $DEBUG = 0;
use strict;
use warnings;

=head1 TITLE

rt-remind - reminder RT3 users of their obligations


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.
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.

You will need to manually configure this script when you install it.

=head1 USAGE

	rt-remind [-help | -q[ueue] QueueName1 ... [-q[ueue] QueueNameN] 
	[-p[riority] [new=D [open=DD] ] [ -m[ost] |-a[ll] ] ]

If run with no flags, reports on 'important' tickets. Command-line arguments and Options are:

=item -q --queue

Name of the RT queue, at least once, or many times. May also be a comma-seperated list.

=item -p --priority

Specify at what priority new or open tickets get included in the report:

	--priority new=2 open=2

=item -m --most

Optionally show all open or new tickets

=item -a --all 

Optionally show all open, new, or stalled tickets

=item -help

Show this documentation.

The intended use is to run with no flags daily, with the C<-most> flag weekly
and with the C<-all> flag monthly. Or similar.

=head1 EXAMPLE

	rt-remind -q CoffeeMachine,SandwichOrders -p new=8 open=8 -a
	rt-remind --queue CoffeeMachine



=head1 AUTHOR

Written by T.D.Bishop -in- kent.ac.uk, July 2003.
Updated by Lee.Goddard -in- easa.eu.int, Dec 2005

=head1 CHANGES

=over 4

=item 2005-12-12: lgoddard 

	Use Getopt::Long.
	Use Pod::Usage
	Take (multiple) queue names on the command line.
	Take priority-defaults for mail-send on the command line
	&formatDate returns ISO-formatted date
	Added this POD

=item 2003-07-30: TB Bishop
	Original version http://download.bestpractical.com/pub/rt/contrib/3.0/rt-remind


=head1 TODO

=over 4

=item *

Include queue names in e-mail report

=item *

Use the standard RT mail interface.



use Carp;
use Getopt::Long;
use Pod::Usage;

### Configuration

# Location of RT3's libs
use lib ("/opt/rt3/lib", "/opt/rt3/etc");

# 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' => 'lee.goddard at easaeuint',
    'root'   => 'lee.goddard at easaeuint',

# Address emails should originate from
my $FROM = 'lee.goddard at easaeuint'; die 'Read the source to configure';

# 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;

# Path to sendmail and flags
my $sendmail = "/usr/sbin/sendmail -t ";

# 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,

### Code ############

my ($showall, $showmost, $help) = (0,0,0);
my @queuenames;

my $result = GetOptions (
	'most'			=> \$showmost,
	'all'			=> \$showall,
	'help'			=> \$help,
	'queue=s'		=> \@queuenames,
	'priority=s%'	=> \$pri,
# Allow queue names as csv
@queuenames = split(/,/,join(',', at queuenames));

if ($help or not (scalar @queuenames)){
	pod2usage(-exitstatus => 0, -verbose => 2) ;

# Pull in the RT stuff
package RT;
use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
use RT::Date;
use RT::Queue;
use RT::Tickets;


foreach my $queuename (@queuenames){

	CleanEnv();						# Clean our the environment
	RT::LoadConfig();				# Load the RT configuration
	RT::Init();						# Initialise RT
	RT::DropSetGIDPermissions();	# Drop any setgid permissions we might have

	# Load in the queue
	my $queue = new RT::Queue($RT::SystemUser);

	my $now = new RT::Date($RT::SystemUser);

	# 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);

	# Sort tickets in to lists for each owner
	while (my $Ticket = $tickets->Next) {
		my $email = $map{$user->Name} || $user->EmailAddress;
		push @{$TicketStore{$email}}, $Ticket;

# Process tickets for each owner
foreach my $email (keys %TicketStore) {
	&doOwner($email, @{$TicketStore{$email}});

# Disconnect before we finish off
exit 0;

# Subroutine to generate a messages for a given owner and set of tickets.
sub doOwner() {
    my ($to, @tickets) = (@_);
    # Mail headers
    my $msg = "From: $FROM\n"."To: $to\n"."Subject: [RT] Outstanding Tickets\n\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$to\n\n";

    # Message table heaer:
    $msg .= sprintf "%5s  %-7s %3s  %-20s %-30s\n", "Id", "Status", "Pri", "Date", "Subject";
    $msg .= ('-'x($linelen-1))."\n";

    my $printmsg = 0; # Flag

    # 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  %-20s %-30s", $Ticket->Id, $Ticket->Status, $Ticket->Priority, $date, $Ticket->Subject;
            # Truncate lines if required
            $line = substr($line, 0, $linelen) if $linelen;
            $msg .= "$line\n";

    $msg .= ('-'x($linelen-1))."\n";

    # Send the message
    if ($printmsg) {
		if ($DEBUG){
			print $msg."\n" 
		} else {
        	open(SENDMAIL, "|$sendmail") || die "Error sending mail: $!";
        	print SENDMAIL $msg;

# Smaller than Data::Simple::ISO
sub formatDate() {
	my $unixtime = shift;
    return "" if $unixtime <= 0; # Return an empty string if we haven't been given a time
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($unixtime);
	$year += 1900; $mon += 1;
    return sprintf "%04d-%02d-%02d %02d:%02d:%02d", $year,$mon,$mday, $hour, $min, $sec;


More information about the rt-users mailing list