[Rt-devel] Need help with tickets generated by SPAM
Emmanuel Lacour
elacour at easter-eggs.com
Mon Feb 9 11:28:42 EST 2009
On Mon, Feb 09, 2009 at 11:00:36AM -0500, Asif Iqbal wrote:
> 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
More information about the Rt-devel
mailing list