BounceMerge

From Request Tracker Wiki
Revision as of 05:02, 17 November 2016 by Crazy4chrissi (talk | contribs) (Some bug fixes / Updates. Quotemeta added (e.g. versions from Debian backports contain + characters which caused the regex to fail) and RT-Ticket header is nowadays X-RT-Ticket.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This is a scrip which checks if a newly generated ticket was created by a mail bounce.

If yes, it tries to deduce the original ticket-id and merges this new ticket into the old one.

The scrip logic is quite conservative, only if the same TicketID is found both in a quoted Message-ID and a RT-Ticket: header, then the scrip merges the tickets.

Note that this requires an accurate Return-Path header. This should normally be added by the final MTA in the chain.

Note also that this causes the logged creation message to be inaccurate, suggesting that the ticket being merged into has just been created.

Install

Condition: On Create

Action: Userdefined

Template: Blank

Custom Condition:

return 1; # n/a

Custom Action Preparation:

return 1;

Custom Action Cleanup Code:

    #
    # Merge mail bounce into old ticket.
    #
    # Otmar Lendl <ol@bofh.priv.at>  2009/07/24
    # Minor Bugfixes/Updates by Christopher Kramer, 2016/11/17
    #
    my $ticket = $self->TicketObj;
    my $tr     = $self->TransactionObj;
    
    # possible sources of ticket-IDs:
    
    # Message-ID of the mail we sent:
    # example: Message-ID: <rt-3.8.2-1611-1247727152-952.14150-6-0@CERT.at>
    my $msgregex = '<rt-'. quotemeta($RT::VERSION) .'-\d+-\d+-\d+\.(\d+)-\d+-\d+@'. quotemeta(RT->Config->Get('Organization')) .'>';
    
    # RT-Ticket: header:
    # example: RT-Ticket: CERT.at #14150
    my $rttregex = '^X-RT-Ticket: ' .  quotemeta(RT->Config->Get('rtname')) .' #(\d+)';
    
    my $Attachments = $tr->Attachments;
    # get first attachment
    my $a = $Attachments->Next;
    return(1) unless ($a);
    
    my $rp = $a->GetHeader('Return-Path');
    my $ct = $a->ContentType;
    
    # bounce?
    return(1) unless (($rp eq '<>') or ($ct eq 'multipart/report'));
    print STDERR "BounceMerge: Looks like a bounce ($rp/$ct). Trying to find ticket-ID.\n";
    # .. which is potentially hidden in other attachments. Collect them all first.
    my $mail = "";
    do {
     my $oh = $a->Headers;
     my $oc = $a->OriginalContent;
     $mail .= "\n----------------- " . $a->id . " ---------\n" . $oh if ($oh);
     $mail .= "\n----------------- " . $a->id . " ---------\n" . $oc if ($oc);
    } while ($a = $Attachments->Next);
    
    # look for a message-ID:
    
    my $id_msg = -1;
    my $id_hdr = -2;
    
    $id_msg = $1 if ($mail =~ /$msgregex/);
    $id_hdr = $1 if ($mail =~ /$rttregex/m);
    
    if (($id_hdr == $id_msg) and ($id_hdr != $ticket->EffectiveId) ) {
     print STDERR "BounceMerge: Removing requestors and merging into $id_msg\n";
     my  @reqs = split(/[\s,]+/, $ticket->RequestorAddresses);
     foreach (@reqs) {
       $ticket->DeleteWatcher(
         Type    => "Requestor",
         Email   => $_,
         Silent  => 1) ;
     }
     $ticket->MergeInto($id_msg);
    }
    
    return(1);

It's worth bearing in mind that there are cases where the bounces may not go into the queue you intended. The branch https://github.com/jmdh/rt/tree/3.8%2Fignore_subject_ticket_for_queues may be of interest, if so.