Hi All
I have a spam filter in front of my queue. So all new tickets have to
pass thru the filter before they make it to the queue.
It works fine for most of the tickets. However, once in a while one or
two spams that manage to pass through the filter
as ham and hence create tickets. It is pretty embarrassing. For
regular emails I can just take those emails as it is and then
pass it through my spam learner and that works fine too. However, I am
not sure how I can do the same for a ticket. I
created a SPAM queue and I gave users’ right to drop any ticket that
is a sure spam and just drop them in that queue. So
now what I need is to find a way to take all tickets that are in SPAM
queue and run them through my spam learner. I do not
know how to do that. Any suggestion would be greatly appreciated!
Here is a script I made (for 3.6.7, needs little adjustements), it submits
tickets to spamassassin sa-learn program depending on status (I used a “spam”
status).
It runs every day through cron.
#!/usr/bin/perl -w
Submit tickets to sa-learn
The user which run this script needs to be the user who handle Anti-Spam
software and need to have proper rights in RT to access tickets
(Global rights: SeeQueue, ShowTicket)
He also needs to be able to access RT files, especially config file.
use strict;
use lib “/opt/rt/rt/local/lib”;
use lib “/opt/rt/rt/lib”;
use lib “/opt/rt/rt/etc”;
use RT;
use RT::Interface::CLI qw( CleanEnv GetCurrentUser );
use RT::Queue;
use RT::Queues;
use RT::Tickets;
use RT::Date;
use MIME::Entity;
use MIME::Body;
my $debug = 0;
my $spam_status = ‘spam’;
my $ham_status = ‘resolved’;
my $learn_ham_cmd = ‘/usr/bin/sa-learn --ham - > /dev/null’;
my $learn_spam_cmd = ‘/usr/bin/sa-learn --spam - > /dev/null’;
if ($debug) {
$learn_ham_cmd = $learn_spam_cmd = ‘/bin/cat’;
}
Set locales
$ENV{‘LANG’} = ‘POSIX’;
$ENV{‘LC_ALL’} = ‘POSIX’;
RT CLI initialization
CleanEnv();
RT::LoadConfig();
RT::Init();
Get the current user all loaded
our $CurrentUser = GetCurrentUser();
unless( $CurrentUser->Id )
{
print STDERR “No RT user found. Please consult your RT administrator.\n”;
exit 1;
}
Limit to tickets LastUpdated 2 days ago
my $datelimit = new RT::Date($RT::SystemUser);
$datelimit->SetToNow();
$datelimit->AddDays(-1);
my $spam_count = 0;
From RT 3.8
sub ContentAsMIME {
my $self = shift;
my $entity = new MIME::Entity;
$entity->head->add( split /:/, $_, 2 )
foreach SplitHeaders($self);
use MIME::Body;
$entity->bodyhandle(
MIME::Body::Scalar->new( $self->OriginalContent )
);
return $entity;
}
sub SplitHeaders {
my $self = shift;
my @headers;
for (split(/\n(?=\w|\z)/,$self->Headers)) {
push @headers, $_ if ($_ !~ /^RT-Send-Bcc/i);
}
return(@headers);
}
sub submit_message ($$) {
my $message = shift;
my $type = shift;
if ($type eq ‘ham’) {
open (CMD, "| $learn_ham_cmd ") or die “Can’t run $learn_ham_cmd: $!\n”;
print CMD $message;
close(CMD);
} elsif ($type eq ‘spam’) {
open (CMD, "| $learn_spam_cmd ") or die “Can’t run $learn_spam_cmd: $!\n”;
print CMD $message;
close(CMD);
} else {
warn “Unknown type: $type\n”;
}
}
sub get_message ($$) {
my $ticket = shift;
my $txn = shift;
my $entity = new MIME::Entity;
my $header = 0;
my $attachments = RT::Attachments->new( $txn->CurrentUser );
$attachments->Limit( FIELD => ‘TransactionId’, VALUE => $txn->id );
$attachments->OrderBy( FIELD => ‘Id’, ORDER => ‘ASC’ );
while ( my $a = $attachments->Next ) {
if (! $header) {
$entity->head->add( split /:/, $_, 2 ) foreach SplitHeaders($a);
$header = 1;
} else {
# Skip multipart declaration
next if (! $a->Content || $a->Content eq ‘’);
$entity->make_multipart unless $entity->is_multipart;
$entity->add_part(ContentAsMIME($a));
}
}
return $entity->as_string;
}
Spams
print “=================SPAM==================\n” if ($debug);
my $queues = new RT::Queues($RT::SystemUser);
$queues->LimitToEnabled();
foreach my $queue (@{$queues->ItemsArrayRef()}) {
my $tickets = new RT::Tickets($RT::SystemUser);
$tickets->LimitStatus(VALUE => $spam_status);
$tickets->LimitQueue(VALUE => $queue->Id);
$tickets->LimitLastUpdated(OPERATOR => “>”,
VALUE => $datelimit->ISO );
while (my $ticket = $tickets->Next) {
my $txn = $ticket->Transactions->First;
# Skip web created tickets
my $msgattr = $txn->Message->First;
next if (!$msgattr);
next if (!$msgattr->GetHeader(‘Received’));
$spam_count++;
my $message = get_message($ticket, $txn);
submit_message($message, 'spam');
}
}
Ham
print “==================HAM==================\n” if ($debug);
my $ham_count = 0;
foreach my $queue (@{$queues->ItemsArrayRef()}) {
# Limit to same count of ham/spam messages
last if ($ham_count >= $spam_count);
my $tickets = new RT::Tickets($RT::SystemUser);
$tickets->LimitStatus(VALUE => $ham_status);
$tickets->LimitQueue(VALUE => $queue->Id);
$tickets->LimitLastUpdated(OPERATOR => ">",
VALUE => $datelimit->ISO );
while (my $ticket = $tickets->Next) {
# Limit to same count of ham/spam messages
last if ($ham_count >= $spam_count);
my $txn = $ticket->Transactions->First;
# Skip web created tickets
my $msgattr = $txn->Message->First;
next if (!$msgattr);
next if (!$msgattr->GetHeader('Received'));
$ham_count++;
my $message = get_message($ticket, $txn);
submit_message($message, 'ham');
}
}
vim: expandtab tabstop=4