Mail workflows
Integrations
Connect sc to Dovecot, Rspamd, or another mail workflow that can submit full message content.
sc is designed to fit into existing mail operations. It can return a report for review, generate abuse-report evidence,
or ask a configured server to send abuse reports when the request explicitly includes abuse_report.send.
The examples below are starting points. Adjust timing, user selection, logging, redaction, rate limits, and failure handling for your environment before running them unattended.
Dovecot Junk purge job
A Dovecot job can periodically inspect a user’s Junk mailbox, report messages that have been there long enough for user review, and mark each message so it does not get reported again.
This example reports messages in Junk that are between 24 and 48 hours old and do not already have the
$AbuseReported keyword. When sc accepts the report, the script adds that keyword to the message.
#!/usr/bin/env sh
set -euo pipefail
USER="you@example.com"
FLAG='$AbuseReported'
SC_URL="https://sc.example.com"
doveadm search -u "$USER" mailbox Junk before 24h since 48h not keyword "$FLAG" |
while read -r guid uid; do
tmp="$(mktemp)"
doveadm fetch -u "$USER" text mailbox-guid "$guid" uid "$uid" | sed 1d > "$tmp"
if jq -n --rawfile message "$tmp" \
'{message: $message, abuse_report: {send: true}}' |
curl -fsS \
-H 'Content-Type: application/json' \
--data-binary @- \
"$SC_URL"
then
doveadm flags add -u "$USER" "$FLAG" mailbox-guid "$guid" uid "$uid"
else
echo "Failed guid=$guid uid=$uid" >&2
fi
rm -f "$tmp"
done
Use this pattern when users or filters already move unwanted mail into Junk and you want a delayed, repeat-safe reporting workflow.
Rspamd Lua postfilter
Rspamd can report messages it rejects by posting the rejected message content to sc from a postfilter callback.
Put a script like this in /etc/rspamd/rspamd.local.lua, set SC_URL in the Rspamd environment, and make sure your
sc server has abuse_report SMTP settings configured if you request sending.
local rspamd_logger = require "rspamd_logger"
local rspamd_http = require "rspamd_http"
local ucl = require "ucl"
rspamd_logger.infox(rspamd_config, "loading sc_report.lua")
local SC_URL = os.getenv("SC_URL")
local TIMEOUT = 15.0
local function sc_report(task)
if task:get_metric_action() ~= "reject" then
return
end
local content = task:get_content()
if not content then
rspamd_logger.errx(task, "no message content available")
return
end
local body = ucl.to_json({
message = tostring(content),
abuse_report = {
send = true,
},
})
local ok = rspamd_http.request({
task = task,
url = SC_URL,
method = "POST",
body = body,
headers = {
["Content-Type"] = "application/json",
},
timeout = TIMEOUT,
callback = function(err, code, response)
if err or not code or code < 200 or code >= 300 then
rspamd_logger.errx(task, "SC report failed: err=%s code=%s response=%s",
err or "none", tostring(code), response or "")
return
end
local parser = ucl.parser()
local parsed_ok, parse_err = parser:parse_string(response or "")
if not parsed_ok then
rspamd_logger.errx(task, "SC report returned invalid JSON: %s response=%s",
parse_err or "unknown parse error", response or "")
return
end
local result = parser:get_object()
local report = result and result.abuse_report
if report and report.sent == false then
rspamd_logger.errx(task, "SC report completed with send failures: %s",
response or "")
else
rspamd_logger.infox(task, "SC report succeeded")
end
end,
})
if not ok then
rspamd_logger.errx(task, "SC report could not be scheduled")
end
end
rspamd_config:register_symbol{
name = "SC_REPORT",
type = "postfilter,callback",
flags = "nostat,ignore_passthrough",
callback = sc_report,
}
Use this pattern when you want rejected mail to generate reports immediately, without waiting for a user-visible Junk folder workflow.
Integration checklist
- Send the full RFC-822 message in the JSON
messagefield. - Use
abuse_report.send: trueonly when thescserver is configured to send mail and you want synchronous delivery. - Keep retry behavior conservative so a temporary
scoutage does not create duplicate reports. - Preserve a local marker, such as a Dovecot keyword, when reporting stored messages.
- Review privacy tradeoffs before forwarding evidence that may identify real recipients.
Source wiki pages: Integrations, Dovecot_Purge, and Rspamd-Lua.