Mbox2Rt
This is a piece of code i use to import unix-style mailboxes ( mbox , or whatever you may call them ) into an RT database and keep the threaded nature of the mail in the mailbox, unfortunately it doesn't work very well in importing all email in mailboxes; sometimes (failed in investigating when and why exactly), it only imports parts of a mailbox.... :(
Prerequisites:
- Mail::Box perl-module
- an installed RT (at least the 'lib' dir from a RT distribution)
- a user that can read RT_SiteConfig.pm (otherwise RT will complain)
Caveats:
- I'm quite new to RT internals, most of this code is inspired on the Gateway-subroutine in RT::Interface::Email.pm, so your mileage may vary
- if the queue you use this on has an autoreply on create, every ticket that will be created will generate an autoreply
#!/usr/bin/perl use strict; use Getopt::Std; use Mail::Box::Manager; #TODO change this to your local RT lib use lib qw(/usr/local/rt34/lib); use RT; RT::LoadConfig(); RT::Init(); RT::ConnectToDatabase(); my %opts; getopts('m:q:fh',\%opts); if ($opts{'h'}) { print <<""; Usage: $0 -m <mailbox-file> -q <rt-queue-id> [-f] [-v] [-h] -m <mbox> : mailbox file to parse -q <rt-queue id> : numeric ID for the queue where you want to load the mailbox -f : force, get rid of the interactive notices -v : verbose -h : this message } die "can't open mailbox $opts{'m'} (option -m)" unless (-r $opts{'m'}); die "need a queue-id (option -q)" unless ($opts{'q'}); # check if this is a valid queue my $queue = RT::Queue->new( $RT::SystemUser ); $queue->Load( $opts{'q'} ); #this loads a queue by Id die "'$opts{'q'}' is not a valid queue id (option -q)" unless ($queue->Id); my $mgr = Mail::Box::Manager->new(); my $folder = $mgr->open( $opts{'m'} ); my $threads = $mgr->threads($folder); foreach my $thread ($threads->all() ) { if ($opts{'v'}) { print "**new thread**\n"; print $thread->threadToString(); } my @msgs = $thread->threadMessages; my $first = shift @msgs; my $ticket = process_first_msg($first); foreach my $rest ( @msgs ) { process_rest_msg($rest,$ticket); } } sub process_first_msg { my ($msg) = @_; if ($opts{'v'}) { print "\n**first-msg**\n". $msg->decoded ."\n****\n"; } if ($opts{'v'} || !$opts{'f'}) { print "\n**email-addrs**\n". join("\n", map {$_->format} $msg->to, $msg->cc,$msg->from,$msg->sender); print "\n"; } if (! $opts{'f'}) { print "\n**subject**\n". $msg->head->get('subject'); print "\n"; print "Are you sure to process this msg? Enter 'y' to verify, other to cancel\n"; my $yes = <STDIN>; chomp($yes); return undef unless ($yes eq 'y'); } my $Ticket = new RT::Ticket( $RT::SystemUser ); my ( $ticket_id, $Transaction, $ErrStr ) = $Ticket->Create( Queue => $queue->Id, Subject => $msg->head->get('Subject'), Requestor => [ map {$_->format} $msg->from ], Cc => [ map {$_->format} $msg->cc ], MIMEObj => mailbox_to_rt($msg), ); return $Ticket; } sub process_rest_msg { my ($msg,$ticket) = @_; if ($opts{'v'}) { print "\n**follow-up**\n". $msg->decoded ."\n****\n"; } if ($opts{'v'} || !$opts{'f'}) { print "\n**email-addrs**\n". join("\n", map {$_->format} $msg->to, $msg->cc,$msg->from,$msg->sender); print "\n"; } if (! $opts{'f'}) { print "\n**subject**\n". $msg->head->get('subject'); print "\n"; print "Are you sure to process this msg? Enter 'y' to verify, other to cancel\n"; my $yes = <STDIN>; chomp($yes); return undef unless ($yes eq 'y'); } my ($status,$retmsg) = $ticket->Correspond( CommitScrips => 0, #saw this in source code MIMEObj => mailbox_to_rt($msg), ); print "Status: $status\n"; print "Retmsg: $retmsg\n"; } sub mailbox_to_rt { my ($msg) = @_; my $parser = RT::EmailParser->new(); $parser->SmartParseMIMEEntityFromScalar( Message => $msg->string ); return $parser->Entity(); }
When used with HideGlobalScrips, I would get errors from this script (crit: Can't locate RT/QueueDeactivatedScrip.pm). The fix in my case was to add local/lib.
--- mbox2rt.pl 2005/08/15 15:15:13 1.1 +++ mbox2rt.pl 2005/08/15 15:16:05 @@ -6,7 +6,7 @@ use Mail::Box::Manager; #TODO change this to your local RT lib -use lib qw(/usr/local/rt34/lib); +use lib qw(/usr/local/rt34/lib /usr/local/rt34/local/lib); use RT; RT::LoadConfig();
When using Ubuntu, you'll have to update the path. Below is what i've used to get it to work:
use lib ("/usr/share/request-tracker3.4/lib", "/usr/local/share/request-tracker3.4/lib");
Somehow the subject of the mail is not imported properly. For example, it results in this in RT after importation : =?iso-8859-1?q?Qu=E9bec_dans_l=27intranet?= This could be solved using the MIME::WordDecoder.