[rt-devel] Draft patch to add references and in-reply-to parsing

Petter Reinholdtsen pere at hungry.com
Tue Jan 27 09:16:30 EST 2004


We are testing RT here at work, and one of the problems we would like
to solve is making sure emails are grouped together in the correct
ticket, even if the subject is missing the ticket ID marker.  We want
the follwing messages to end up in the same ticket when recieved in
order:

  To: otrs at some.domain
  Subject: Foo is not working, everything is bad
  From: user at some.domain
  Message-ID: <1 at some.domain>

  Please, please help us.



  To: otrs at some.domain
  Subject: Re: Foo is not working, everything is bad
  From: user at some.domain
  References: <1 at some.domain>
  In-Reply-To: <1 at some.domain>
  Message-ID: <2 at some.domain>

  Oh, and bar is giving strange noises as well.



  To: otrs at some.domain
  Subject: Re: Foo is not working, everything is bad
  From: user at some.domain
  References: <1 at some.domain> <2 at some.domain>
  In-Reply-To: <2 at some.domain>
  Message-ID: <3 at some.domain>

  I got my local admin to help me.  Everything is OK now.


As you can see, the messages contain references to each other, and it
should be possible to make sure these emails are grouped together in
one ticket.

I've started on a patch, but do not quite know how to look up ticket
IDs based on message-ids.  Anyone got a clue to spare?

Here is the current draft, which of course do not work because the
part marked XXX is broken.


--- src-3-0-8/lib/RT/Interface/Email.pm 2004-01-02 22:23:39.000000000 +0100
+++ src-3-0-8-local/lib/RT/Interface/Email.pm  2004-01-27 14:23:13.000000000 +0100
@@ -475,6 +475,61 @@

     $args{'ticket'} ||= $parser->ParseTicketId($Subject);

+    unless ( $args{'ticket'} ) {
+        # Based on info from <URL:http://www.jwz.org/doc/threading.html>
+       my @msgids = ();
+
+       my $references = $head->get('References') || '';
+       my $inreplyto  = $head->get('In-Reply-To') || '';
+
+       push(@msgids, split(/\s+/, $references)) if ($references);
+
+       if ($inreplyto) {
+           if ($inreplyto =~ m/(<[^>]+>)/) {
+               push(@msgids, $1);
+           } else {
+               $RT::Logger->log(level => 'debug',
+                                message => "Gateway: Unhandled In-Reply-To format: '$inreplyto'"
+                                );
+           }
+       }
+
+        # Map Message-id(s) to ticket id
+       my @ids = ();
+       my %checked;
+       my $msgid;
+       for $msgid (@msgids) {
+           next if $checked{$msgid}; # Already looked up this message-id
+
+           # XXX Find proper API
+           my $TicketID = $RT::Attachment::TicketIDofMessageId($msgid);
+           push(@ids, @TicketIDs) if (@TicketIDs);
+
+           $checked{$msgid} = 1;
+       }
+
+       # Reduce list of IDs to unique IDs only
+       my $id;
+       my %idhash;
+       for $id (sort @ids) {
+           $idhash{$id} = 1;
+       }
+       @ids = sort keys %idhash;
+
+       # If the Message-id(s) are already in the database, use their
+       # ticked-id
+       if (1 < @ids) {
+           $RT::Logger->log(level => 'debug',
+                            message => "Gateway: Several possible tickets: " .
+                                join(",", @ids)
+                            );
+       }
+
+       # Just pick the first.  Not sure how we should handle several
+       # ticket ids
+       $args{'ticket'} = $ids[0] if (@ids);
+    }
+
     my $SystemTicket;
     if ( $args{'ticket'} ) {
         $SystemTicket = RT::Ticket->new($RT::SystemUser);



More information about the Rt-devel mailing list