How do I check for spam using the async SpamAssassin and Rspamd interfaces?
Two async spam-checking variants are available, both used in filter_end:
md_async_spamc_check- sends the message to spamd using the raw SPAMC wire protocol over an async socket. Does not requireMail::SpamAssassin::Client.md_async_rspamd_check- POSTs the message to the Rspamd HTTP API over an async TCP socket. Does not requireLWP::UserAgent.md_async_spam_assassin_check- runs SpamAssassin in-process (no spamd), reading./INPUTMSG. Use when spamd is not available.
Each returns the same values as its synchronous counterpart.
use Mail::MIMEDefang::Async;
sub filter_end {
my($entity) = @_;
# --- Option A: async spamc (needs a running spamd) ---
my ($score, $threshold, $report, $isspam) = md_async_spamc_check(
host => '127.0.0.1',
port => 783,
user => 'defang',
timeout => 30,
);
if (defined $score) {
action_change_header('X-Spam-Flag', $isspam ? 'YES' : 'NO');
action_change_header('X-Spam-Score', "$score / $threshold");
if ($isspam && $score >= 10) {
return action_bounce("Message rejected as spam (score $score)");
}
}
# --- Option B: async Rspamd ---
my ($hits, $req, $tests, $rpt, $action, $is_spam) =
md_async_rspamd_check('http://127.0.0.1:11333');
md_syslog('Info',
"Rspamd: score=$hits/$req action=$action spam=$is_spam tests=$tests");
if ($action eq 'reject') {
return action_bounce("Message rejected by Rspamd (score $hits)");
}
if ($action eq 'add header' || $is_spam eq 'true') {
action_change_header('X-Spam-Score', "$hits/$req $tests");
}
# --- Option C: in-process SpamAssassin (no spamd required) ---
# my ($hits, $required, $names, $full_report) =
# md_async_spam_assassin_check();
}