112 lines
3.5 KiB
Perl
112 lines
3.5 KiB
Perl
package RT::Interface::Email::OneTicketPerRequestor;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Role::Basic 'with';
|
|
with 'RT::Interface::Email::Role';
|
|
|
|
use Email::Address;
|
|
use Encode;
|
|
use RT::Interface::Email ();
|
|
use RT::Plugin;
|
|
use RT::Tickets;
|
|
use YAML::Tiny;
|
|
|
|
my %QUEUES = ();
|
|
my $plugin_self = RT::Plugin->new(name => "RT-Extension-Conservancy");
|
|
foreach my $confdir ($plugin_self->Path("etc"), $RT::LocalEtcPath, $RT::EtcPath) {
|
|
next unless (defined($confdir) && $confdir);
|
|
my $conf_path = "$confdir/OneTicketPerRequestor.yml";
|
|
if (-r $conf_path) {
|
|
%QUEUES = %{YAML::Tiny->read($conf_path)->[0]};
|
|
last if (%QUEUES);
|
|
}
|
|
}
|
|
|
|
# Compile the user's configuration into arguments for RT::Tickets->OrderBy.
|
|
while (my ($key, $sort_orders) = each %QUEUES) {
|
|
if (!ref($sort_orders)) {
|
|
$sort_orders = [($sort_orders ? $sort_orders : ())];
|
|
}
|
|
if (!@$sort_orders) {
|
|
push(@$sort_orders, "Created DESC");
|
|
}
|
|
$QUEUES{$key} = [map {
|
|
my ($field, $order) = split;
|
|
$order = uc($order || "ASC");
|
|
[FIELD => $field, ORDER => $order];
|
|
} @$sort_orders];
|
|
}
|
|
|
|
sub ReadHeader {
|
|
my $headers = shift;
|
|
my $header_name = shift;
|
|
return Encode::decode("UTF-8", $headers->get($header_name) || "");
|
|
}
|
|
|
|
sub BeforeDecrypt {
|
|
$RT::Logger->debug("Entered OneTicketPerRequestor BeforeDecrypt");
|
|
my %args = (
|
|
Message => undef,
|
|
RawMessage => undef,
|
|
Actions => undef,
|
|
Queue => undef,
|
|
@_
|
|
);
|
|
|
|
my $queue_name = $args{Queue}->Name;
|
|
my $sort_orders = $QUEUES{$queue_name};
|
|
if (!defined($sort_orders)) {
|
|
$RT::Logger->debug("OTPR stopping: Not configured for $queue_name");
|
|
return;
|
|
}
|
|
elsif (RT::Interface::Email::ExtractTicketId($args{Message})) {
|
|
$RT::Logger->debug("OTPR stopping: Message already has ticket ID");
|
|
return;
|
|
}
|
|
my $headers = $args{Message}->head();
|
|
my @from_addrs = Email::Address->parse(ReadHeader($headers, "From"));
|
|
my $from_address;
|
|
foreach my $address (@from_addrs) {
|
|
$from_address = $address->address;
|
|
last if $from_address;
|
|
}
|
|
unless (defined($from_address) && $from_address) {
|
|
$RT::Logger->debug("OTPR stopping: Message has no From address (?!)");
|
|
return;
|
|
}
|
|
|
|
my $dest_ticket = eval {
|
|
my $ticket_search = RT::Tickets->new($RT::SystemUser);
|
|
$ticket_search->LimitQueue(
|
|
OPERATOR => "=",
|
|
VALUE => $queue_name,
|
|
);
|
|
$ticket_search->LimitWatcher(
|
|
TYPE => "Requestor",
|
|
OPERATOR => "=",
|
|
VALUE => $from_address,
|
|
);
|
|
foreach my $sort_args (@$sort_orders) {
|
|
$ticket_search->OrderBy(@$sort_args);
|
|
}
|
|
$RT::Logger->debug("OTPR search: " . $ticket_search->BuildSelectQuery());
|
|
$ticket_search->First;
|
|
};
|
|
if ($@) {
|
|
$RT::Logger->debug("OTPR stopping: Ticket search died: $@");
|
|
return;
|
|
}
|
|
elsif (!defined($dest_ticket)) {
|
|
$RT::Logger->debug(sprintf("OTPR stopping: No ticket found from <%s> in queue %s",
|
|
$from_address, $queue_name));
|
|
return;
|
|
}
|
|
$RT::Logger->info(sprintf("OTPR: Redirecting email from <%s> to ticket #%s",
|
|
$from_address, $dest_ticket->id));
|
|
my $subject = ReadHeader($headers, "Subject");
|
|
$headers->replace("Subject", RT::Interface::Email::AddSubjectTag($subject, $dest_ticket->id));
|
|
}
|
|
|
|
1;
|