Difference between revisions of "Mbox2Rt"

From Request Tracker Wiki
Jump to navigation Jump to search
m (2 revisions imported)
 
 
Line 12: Line 12:
* if the queue you use this on has an autoreply on create, every ticket that will be created will generate an autoreply
* if the queue you use this on has an autoreply on create, every ticket that will be created will generate an autoreply


  <nowiki>#!/usr/bin/perl
  <source lang="perl">#!/usr/bin/perl
  use strict;
  use strict;
   
   
Line 128: Line 128:
   
   
   
   
  </nowiki>
  </source>


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

Latest revision as of 09:07, 29 November 2017

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 &lt;&lt;"";
 Usage: $0 -m &lt;mailbox-file&gt; -q &lt;rt-queue-id&gt; [-f] [-v] [-h]
 -m &lt;mbox&gt; : mailbox file to parse
 -q &lt;rt-queue id&gt; : 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-&gt;new( $RT::SystemUser );
 $queue-&gt;Load( $opts{'q'} ); #this loads a queue by Id
 die "'$opts{'q'}' is not a valid queue id (option -q)" unless ($queue-&gt;Id);
 
 my $mgr = Mail::Box::Manager-&gt;new();
 
 
 my $folder = $mgr-&gt;open(
    $opts{'m'}
 );
 
 my $threads = $mgr-&gt;threads($folder);
 foreach my $thread ($threads-&gt;all() ) {
    if ($opts{'v'}) {
        print "**new thread**\n";
        print $thread-&gt;threadToString();
    }
    my @msgs = $thread-&gt;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-&gt;decoded ."\n****\n";
    }
    if ($opts{'v'} || !$opts{'f'}) {
        print "\n**email-addrs**\n". join("\n", map {$_-&gt;format} $msg-&gt;to, $msg-&gt;cc,$msg-&gt;from,$msg-&gt;sender);
        print "\n";
    }
    if (! $opts{'f'}) {
        print "\n**subject**\n". $msg-&gt;head-&gt;get('subject');
        print "\n";
        print "Are you sure to process this msg? Enter 'y' to verify, other to cancel\n";
        my $yes = &lt;STDIN&gt;;
        chomp($yes);
        return undef unless ($yes eq 'y');
    }
    my $Ticket = new RT::Ticket( $RT::SystemUser );
    my ( $ticket_id, $Transaction, $ErrStr ) = $Ticket-&gt;Create(
        Queue     =&gt; $queue-&gt;Id,
        Subject   =&gt; $msg-&gt;head-&gt;get('Subject'),
        Requestor =&gt; [ map {$_-&gt;format} $msg-&gt;from ],
        Cc        =&gt; [ map {$_-&gt;format} $msg-&gt;cc ],
        MIMEObj   =&gt; mailbox_to_rt($msg),
    );
    return $Ticket;
 }
 sub process_rest_msg {
    my ($msg,$ticket) = @_;
    if ($opts{'v'}) {
        print "\n**follow-up**\n". $msg-&gt;decoded ."\n****\n";
    }
    if ($opts{'v'} || !$opts{'f'}) {
        print "\n**email-addrs**\n". join("\n", map {$_-&gt;format} $msg-&gt;to, $msg-&gt;cc,$msg-&gt;from,$msg-&gt;sender);
        print "\n";
    }
    if (! $opts{'f'}) {
        print "\n**subject**\n". $msg-&gt;head-&gt;get('subject');
        print "\n";
        print "Are you sure to process this msg? Enter 'y' to verify, other to cancel\n";
        my $yes = &lt;STDIN&gt;;
        chomp($yes);
        return undef unless ($yes eq 'y');
    }
    my ($status,$retmsg) = $ticket-&gt;Correspond(
        CommitScrips =&gt; 0, #saw this in source code
        MIMEObj =&gt; mailbox_to_rt($msg),
    );
    print "Status: $status\n";
    print "Retmsg: $retmsg\n";
 }
 sub mailbox_to_rt {
    my ($msg) = @_;
    my $parser = RT::EmailParser-&gt;new();
    $parser-&gt;SmartParseMIMEEntityFromScalar( Message =&gt; $msg-&gt;string );
    return $parser-&gt;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.