Compare commits
10 commits
94cdfd39ff
...
9831a87844
Author | SHA1 | Date | |
---|---|---|---|
|
9831a87844 | ||
|
cf3c2dff79 | ||
|
9c36813918 | ||
|
615cac871f | ||
|
cacbc9182c | ||
|
4ff8e0133c | ||
|
52a1213a1c | ||
|
877bca0ca4 | ||
|
3e682d05e0 | ||
|
e1d580141b |
4 changed files with 124 additions and 23 deletions
14
.gitignore
vendored
14
.gitignore
vendored
|
@ -1 +1,15 @@
|
||||||
|
blib*
|
||||||
|
Makefile
|
||||||
|
Makefile.old
|
||||||
|
pm_to_blib*
|
||||||
|
*.tar.gz
|
||||||
|
.lwpcookies
|
||||||
|
cover_db
|
||||||
|
pod2htm*.tmp
|
||||||
|
/RT-Extension-References*
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
/MYMETA.*
|
||||||
|
/t/tmp
|
||||||
|
/xt/tmp
|
||||||
*~
|
*~
|
11
Makefile.PL
Normal file
11
Makefile.PL
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
use inc::Module::Install;
|
||||||
|
|
||||||
|
RTx 'RT-Extension-ThreadByReference';
|
||||||
|
license 'perl';
|
||||||
|
repository 'https://github.com/akamai/rt-extension-threadbyreference';
|
||||||
|
|
||||||
|
requires_rt '4.0.0';
|
||||||
|
rt_too_new '4.4.0';
|
||||||
|
|
||||||
|
sign;
|
||||||
|
WriteAll;
|
80
lib/RT/Extension/ThreadByReference.pm
Normal file
80
lib/RT/Extension/ThreadByReference.pm
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
package RT::Extension::ThreadByReference;
|
||||||
|
|
||||||
|
our $VERSION = '0.01';
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
RT-Extension-ThreadByReference - Use the MIME Reference header to try and thread messages to tickets
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
When an RT ticketing queue is CCed on a message thread, it can be very
|
||||||
|
difficult to get the subject lines correct in all parts of the
|
||||||
|
message. This can cause a single thread to spawn off tens of
|
||||||
|
different tickets that need manual merging.
|
||||||
|
|
||||||
|
This extension uses the MIME Reference header to search for threads
|
||||||
|
to associate a message with.
|
||||||
|
|
||||||
|
=head1 RT VERSION
|
||||||
|
|
||||||
|
Works with RT 4.0 and greater.
|
||||||
|
|
||||||
|
=head1 INSTALLATION
|
||||||
|
|
||||||
|
=over
|
||||||
|
|
||||||
|
=item C<perl Makefile.PL>
|
||||||
|
|
||||||
|
=item C<make>
|
||||||
|
|
||||||
|
=item C<make install>
|
||||||
|
|
||||||
|
May need root permissions
|
||||||
|
|
||||||
|
=item Edit your F</opt/rt4/etc/RT_SiteConfig.pm>
|
||||||
|
|
||||||
|
If you are using RT 4.2 or greater, add this line:
|
||||||
|
|
||||||
|
Plugin('RT::Extension::ThreadByReference');
|
||||||
|
|
||||||
|
For RT 4.0, add this line:
|
||||||
|
|
||||||
|
Set(@Plugins, qw(RT::Extension::ThreadByReference));
|
||||||
|
|
||||||
|
or add C<RT::Extension::ThreadByReference> to your existing C<@Plugins> line.
|
||||||
|
|
||||||
|
=item Clear your mason cache
|
||||||
|
|
||||||
|
rm -rf /opt/rt4/var/mason_data/obj
|
||||||
|
|
||||||
|
=item Restart your webserver
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Harlan Lieberman-Berg C<< <hlieberm@akamai.com> >>
|
||||||
|
|
||||||
|
=head1 BUGS
|
||||||
|
|
||||||
|
All bugs should be reported via email to
|
||||||
|
|
||||||
|
L<bug-RT-Extension-ThreadByReference@rt.cpan.org|mailto:bug-RT-Extension-ThreadByReference@rt.cpan.org>
|
||||||
|
|
||||||
|
or via the web at
|
||||||
|
|
||||||
|
L<rt.cpan.org|http://rt.cpan.org/Public/Dist/Display.html?Name=RT-Extension-ThreadByReference>.
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
Copyright (c) 2015-2016 by Akamai Technologies, Inc.
|
||||||
|
|
||||||
|
This software is free software; you can redistribute and/or modify it
|
||||||
|
under the same terms as Perl itself.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
1;
|
|
@ -1,18 +1,12 @@
|
||||||
package RT::Interface::Email::TryThreading;
|
package RT::Interface::Email::ThreadByReference;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
use RT::Interface::Email ();
|
use RT::Interface::Email ();
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
RT::Interface::Email::TryThreading - Use In-Reply-To and other headers to try and find a ticket
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
sub GetCurrentUser {
|
sub GetCurrentUser {
|
||||||
$RT::Logger->debug("Entering TryThreading");
|
$RT::Logger->debug("Entering ThreadByReference");
|
||||||
|
|
||||||
my %args = (
|
my %args = (
|
||||||
Message => undef,
|
Message => undef,
|
||||||
|
@ -25,13 +19,13 @@ sub GetCurrentUser {
|
||||||
@_
|
@_
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($args{'Ticket'}) {
|
if ($args{'Ticket'}->id) {
|
||||||
$RT::Logger->debug("Ticket %s already assigned. You don't need my help!",
|
$RT::Logger->debug(sprintf("Ticket %s already assigned. You don't need my help!",
|
||||||
$args{'Ticket'});
|
$args{'Ticket'}->id));
|
||||||
return ($args{'CurrentUser'}, $args{'AuthLevel'});
|
return ($args{'CurrentUser'}, $args{'AuthLevel'});
|
||||||
}
|
}
|
||||||
|
|
||||||
$RT::Logger->debug("Operating on queue %s", $args{'Queue'});
|
$RT::Logger->debug(sprintf("Operating on queue %s", $args{'Queue'}));
|
||||||
|
|
||||||
my @messageids = FetchPossibleHeaders($args{'Message'});
|
my @messageids = FetchPossibleHeaders($args{'Message'});
|
||||||
|
|
||||||
|
@ -41,9 +35,9 @@ sub GetCurrentUser {
|
||||||
}
|
}
|
||||||
|
|
||||||
my %tickets = ();
|
my %tickets = ();
|
||||||
foreach $messageid (@messageids) {
|
foreach my $messageid (@messageids) {
|
||||||
if (MessageIdToTicket($messageid)) {
|
if (my $ids = MessageIdToTicket($messageid)) {
|
||||||
foreach $ticket ($_) {
|
foreach my $ticket ($ids) {
|
||||||
$tickets{$ticket} = undef;
|
$tickets{$ticket} = undef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,11 +51,11 @@ sub GetCurrentUser {
|
||||||
}
|
}
|
||||||
elsif (scalar(@tickets) > 1) {
|
elsif (scalar(@tickets) > 1) {
|
||||||
$RT::Logger->warning("Email maps to more than one ticket.");
|
$RT::Logger->warning("Email maps to more than one ticket.");
|
||||||
$RT::Logger->warning("Tickets: %s", @tickets);
|
$RT::Logger->warning(sprintf("Tickets: %s", @tickets));
|
||||||
}
|
}
|
||||||
|
|
||||||
# We have the ticket. Set it.
|
# We have the ticket. Set it.
|
||||||
$RT::Logger->debug("Threading email in ticket %s", $tickets[0]);
|
$RT::Logger->debug(sprintf("Threading email in ticket %s", $tickets[0]));
|
||||||
$args{'Ticket'}->Load($tickets[0]);
|
$args{'Ticket'}->Load($tickets[0]);
|
||||||
|
|
||||||
return ($args{'CurrentUser'}, $args{'AuthLevel'});
|
return ($args{'CurrentUser'}, $args{'AuthLevel'});
|
||||||
|
@ -78,21 +72,22 @@ sub FetchPossibleHeaders {
|
||||||
# There may be multiple references
|
# There may be multiple references
|
||||||
# In practice, In-Reply-To seems to no longer be worth parsing, as
|
# In practice, In-Reply-To seems to no longer be worth parsing, as
|
||||||
# it seems to usually just be a repeat of the References.
|
# it seems to usually just be a repeat of the References.
|
||||||
if ($head->get('References')) {
|
if (my $refs = $head->get('References')) {
|
||||||
chomp();
|
chomp();
|
||||||
|
|
||||||
foreach my $ref (split(/\s+/, $_)) {
|
foreach my $ref (split(/\s+/, $refs)) {
|
||||||
$ref =~ /,?<([^>]+)>/;
|
$ref =~ /,?<([^>]+)>/;
|
||||||
if ($1) {
|
if ($1) {
|
||||||
push(@msgids, $1);
|
push(@msgids, $1);
|
||||||
$RT::Logger->debug("Found reference: %s", $1);
|
$RT::Logger->debug(sprintf("Found reference: %s", $1));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$RT::Logger->debug("Reference with borked syntax: %s", $ref);
|
$RT::Logger->debug(sprintf("Reference with borked syntax: %s", $ref));
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return @msgids;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub MessageIdToTicket {
|
sub MessageIdToTicket {
|
||||||
|
@ -136,10 +131,11 @@ sub MessageIdToTicket {
|
||||||
);
|
);
|
||||||
|
|
||||||
my %tickets;
|
my %tickets;
|
||||||
while (my $attach => $attachments->Next) {
|
while (my $attach = $attachments->Next) {
|
||||||
$tickets{$attach->TransactionObj()->Ticket} = undef;
|
$tickets{$attach->TransactionObj()->Ticket} = undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
return keys(%tickets);
|
return keys(%tickets);
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
Loading…
Reference in a new issue