From Request Tracker Wiki
Jump to navigation Jump to search

In our organisation, we have two teams who deal with customers through RT. Sometimes, when we're doing internal work, one of those teams is the customer of the other. We wanted to be able to continue to deal with this through RT using the same workflow as with an external customer. Previously we'd tried moving tickets between queues and linking tickets but this led to mistakes.

I wrote the following perl script, and set it up aliased to an email address in the same way as you would with rt-mailgate.

 use File::Temp qw/tempdir/;
 use Getopt::Long;
 use MIME::Parser;
 my %opts;
 GetOptions( \%opts, "rtname=s", "hide=s", "find=s", "to=s", "from=s");
 my $RTNAME = $opts{'rtname'};
 my $HIDEEXT= '-'.$opts{'hide'};
 my $FINDEXT= '-'.$opts{'find'};
 for (qw/rtname hide find to from/) {
   die "$0 invoked wrongly\nNo $_ provided\n" unless $opts{$_};
 my $tmpdir = File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 );
 my $parser = new MIME::Parser;
 my $entity = $parser->parse(\*STDIN);
 my $header = $entity->head();
 #check subject:
 modify_headers( $header )
   if ( $header->get('Subject') =~ /\[\Q$opts{'rtname'}\E\s+\#(\d+)\s*\]/ );
 #change To:
 #resend email
 sub modify_headers($) {
     my $h = shift;
     chomp( my $subj = $h->get('Subject') );
   # Map out standard RTName tag using the hide extension
     if ( $subj =~ s/(\[\Q$RTNAME\E\s+\#(\d+)\s*\])//i ) {
         my $tag = $1;
         $tag =~ s/\Q$RTNAME\E/$RTNAME$HIDEEXT/i;
         $subj .= $tag unless ($subj =~ /\Q$tag\E/);
         if ( $h->get('X-RT-Loop-Prevention') =~ /\Q$opts{'rtname'}\E/ ) {
             $h->replace('X-RT-Loop-Prevention', $opts{'rtname'}.$HIDEEXT);
   # Map in hidden RTName tag using the find extension
     if ( $subj =~ s/(\[\Q$RTNAME$FINDEXT\E\s+\#(\d+)\s*\])//i ) {
         my $tag = $1;
         $tag =~ s/\Q$RTNAME$FINDEXT\E/$RTNAME/i;
         $subj .= $tag unless ($subj =~ /\Q$tag\E/);

The script changes takes an incoming email, checks it for the RT tag in the subject and modifies it by adding an extension (passed as --hide). It also checks for an RT tag with and extension (passed as --find) and removes that extension so it looks like an original RT tag. It then manipulates the to and from fields according to some other parameters. The script needs to be set up on a pair of mail aliases so that messages can pass in both directions being translated as required.

For best results, you need ExtractRTNames extension from the BestPractical site.

The result is that RT sees the mail as coming from another RT instance, but the original ticket tags are retained in a way that can be recovered.

Usage Example

Our scenario is the team organising where we run our training courses, and the team booking people into our own self-run training venue.

I set up two mail aliases as follows:

rt-train-venue: "|/path/to/rt_talk_to_self.pl --rtname MyOrg --hide TRAIN --find VENUE --from rt-venue-train@myorg.com --to venue@myorg.com"

rt-venue-train: "|/path/to/rt_talk_to_self.pl --rtname MyOrg --hide VENUE --find TRAIN --from rt-train-venue@myorg.com --to train@myorg.com"

train@myorg.com and venue@myorg.com are the normal email addresses pointing at the RT queues.

The training team use the address rt-train-venue to communicate with the venue team and the correspondance from their ticket appears in a new ticket in the training teams queues. The script changes the From field in the email so replies are filtered back through the script and appear back in the original ticket.