Patch to add References and In-Reply-To parsing and handling to OTRS. Created 2004-01-09 by Petter Reinholdtsen --- Kernel/Config/Defaults.pm.orig 2003-07-13 21:23:21.000000000 +0200 +++ Kernel/Config/Defaults.pm 2004-01-09 15:21:43.000000000 +0100 @@ -714,6 +714,8 @@ 'Mailing-List', 'X-Loop', 'X-No-Loop', + 'References', + 'In-Reply-To', 'X-OTRS-Loop', 'X-OTRS-Info', 'X-OTRS-Priority', --- Kernel/System/PostMaster.pm.orig 2003-06-22 20:37:36.000000000 +0200 +++ Kernel/System/PostMaster.pm 2004-01-09 16:57:48.000000000 +0100 @@ -221,23 +221,91 @@ my $Self = shift; my %Param = @_; my $Subject = $Param{Subject} || ''; - if (my $Tn = $Self->{TicketObject}->GetTNByString($Subject)) { - my $TicketID = $Self->{TicketObject}->CheckTicketNr(Tn => $Tn); + my $Tn; + my $TicketID; + if ($Tn = $Self->{TicketObject}->GetTNByString($Subject)) { + $TicketID = $Self->{TicketObject}->CheckTicketNr(Tn => $Tn); if ($Self->{Debug} > 1) { $Self->{LogObject}->Log( Priority => 'debug', Message => "CheckFollowUp: Tn: $Tn found or forward!", ); } - if ($TicketID) { - if ($Self->{Debug} > 1) { - $Self->{LogObject}->Log( + } else { + # Based on info from + my @msgids = (); + + # Extract Message-id(s) from References and In-Reply-to + my $references = $Param{References}; + my $inreplyto = $Param{'In-Reply-To'}; # XXX Check capitalisation + + push(@msgids, split(/\s+/, $references)) if ($references); + + if ($inreplyto) { + if ($inreplyto =~ m/(<[^>]+>)/) { + push(@msgids, $1); + } else { + $Self->{LogObject}->Log( + Priority => 'debug', + Message => "CheckFollowUp: Unhandled In-Reply-To: '$inreplyto'", + ); + } + } + + # Look up Message-id(s) using Article::ArticleMsgIdLookup + my @ids = (); + my %checked; + my $msgid; + for $msgid (@msgids) { + next if $checked{$msgid}; + my @ArticleIDs = + $Self->{TicketObject}->ArticleMsgIdLookup(MessageID => $msgid); + my @TicketIDs; + my $aid; + for $aid (@ArticleIDs) { + my %data = + $Self->{TicketObject}->GetArticle(ArticleID => $aid); + my $tn = $Self->{TicketObject}->GetTNOfId(ID => $data{TicketID}); + push(@TicketIDs, $tn); + } + 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) { + if ($Self->{Debug} > 1) { + $Self->{LogObject}->Log( + Priority => 'debug', + Message => "CheckFollowUp: Several possible ticket ids", + ); + } + } + + # Just pick the first. Not sure how we should handle several + # ticket ids + if (@ids) { + $Tn = $ids[0]; + $TicketID = $Self->{TicketObject}->CheckTicketNr(Tn => $Tn); + } + } + if ($TicketID) { + if ($Self->{Debug} > 1) { + $Self->{LogObject}->Log( Priority => 'debug', - Message => "CheckFollowUp: ja, it's a follow up ($Tn/$TicketID)", + Message => "CheckFollowUp: yes, it's a follow up ($Tn/$TicketID)", ); - } - return ($Tn, $TicketID); - } + } + return ($Tn, $TicketID); } return; } --- Kernel/System/Ticket/Article.pm.orig 2003-06-19 00:40:35.000000000 +0200 +++ Kernel/System/Ticket/Article.pm 2004-01-09 15:21:15.000000000 +0100 @@ -621,5 +621,35 @@ return %Data; } # -- +sub ArticleMsgIdLookup { + my $Self = shift; + my %Param = @_; + my @Index = (); + # -- + # check needed stuff + # -- + if (!$Param{MessageID}) { + $Self->{LogObject}->Log(Priority => 'error', Message => "Need MessageID!"); + return; + } + # -- + # sql query + # -- + my $SQL = "SELECT id" . + " FROM " . + " article " . + " WHERE " . + " a_message_id = '$Param{MessageID}' " . + " ORDER BY incoming_time"; + $Self->{DBObject}->Prepare(SQL => $SQL); + while (my @Row = $Self->{DBObject}->FetchrowArray()) { + push (@Index, $Row[0]); + } + # -- + # return data + # -- + return @Index; +} +# -- 1;