Files
jcoffey-dev 98413e684c
ci / build (pull_request) Skipped
ci / publish (pull_request) Skipped
ci / notices (pull_request) Successful in 49s
github/ci (branch) GitHub Actions
ci / github (pull_request) Successful in 1m3s
Debug Sieve scripts in a playground that ships with the console
The Debug button on a Sieve script sent a copy to an outside site, whose
interpreter knows only upstream's extension names: a script that requires
vnd.inbuxa.expressions or vnd.inbuxa.while failed to compile there, and
the button took admins to another project's site.

The playground now ships inside the console and runs the server's own
interpreter. sieve-playground/ is built by inbuxa-server's
tools/sieve-playground (SOURCE.md names the commit); sieve-playground.ts
copies it, with Monaco 0.52.2 from node_modules, into
sieve-playground/<content hash>/ (the server caches every file but the
console's index.html for good) and gives the console its path. The
script stays on the console's origin, so the warning dialog before
opening it is gone.

Strings (en.json): sievepad.failed reworded, sievepad.debugHint added,
the three warning-dialog strings removed.

webui.zip grows from 1.3 MB to 3.4 MB: 0.9 MB of compressed WebAssembly,
the rest Monaco's editor core.
2026-10-09 01:14:30 -07:00

106 lines
3.2 KiB
Sieve

# Welcome to the Sieve playground!
#
# Sieve (RFC 5228) is the standard language for filtering email on the
# mail server. This script runs in your browser on the same interpreter
# your inbuxa server runs.
#
# Press Run (Ctrl+Enter or Cmd+Enter) to filter the message in the middle
# column, then open the Messages tab on the right to see what changed.
# Hover over any command to read its documentation.
#
# Everything runs locally in your browser: scripts and messages are saved
# in this browser only and are never sent to or stored on a server.
require ["envelope", "fileinto", "mailbox", "special-use", "imap4flags",
"variables", "relational", "comparator-i;ascii-numeric",
"spamtest", "spamtestplus", "date", "duplicate", "extlists",
"editheader", "mime", "foreverypart", "extracttext", "replace",
"vacation"];
# Drop the message if the very same one was delivered in the last hour.
# Press "Run again" to simulate a second delivery.
if duplicate :seconds 3600 {
discard;
stop;
}
# Anything the spam filter scored 80% or higher goes to Junk.
if spamtest :percent :value "ge" :comparator "i;ascii-numeric" "80" {
fileinto :specialuse "\\Junk" :create "Junk";
stop;
}
# Mailing lists get a folder of their own, such as "Lists/rust-users".
if header :matches "List-Id" "*<*.*>*" {
set :lower "list" "${2}";
fileinto :create "Lists/${list}";
stop;
}
# Capture a few details about the message with variables and wildcard
# matches. Variables first assigned inside a block only live in that block,
# so declare the ones used later at the top level.
set "domain" "unknown";
set "subject" "";
set "sender" "there";
if address :domain :matches "from" "*" {
set :lower "domain" "${1}";
}
if header :matches "Subject" "*" {
set "subject" "${1}";
}
if header :matches "From" "* <*>" {
set "sender" "${1}";
}
# People in your address book are flagged as important.
if address :all :list "from" "addrbook:default" {
addflag "\\Flagged";
}
# Tag messages that carry a PDF anywhere in their MIME structure.
if header :mime :anychild :contenttype "Content-Type" "application/pdf" {
addflag "$HasPDF";
}
# Note when the message arrived outside office hours.
if anyof (currentdate :value "lt" :comparator "i;ascii-numeric" "hour" "08",
currentdate :value "ge" :comparator "i;ascii-numeric" "hour" "18") {
addheader "X-After-Hours" "yes";
}
# Stamp the message so you can see it went through the filter.
addheader :last "X-Sieve-Filter" "inbuxa Sieve playground";
# Append a footer to every plain text part.
foreverypart {
if header :mime :subtype "Content-Type" "plain" {
extracttext "body";
replace text:
${body}
--
Filtered on its way in by a Sieve script.
.
;
}
}
# Let the sender know you are away, at most once a week per sender.
vacation :days 7 :subject "Away: ${subject}" text:
Hi ${sender},
Thanks for your message. I am out of the office this week and will
get back to you as soon as I return.
--
This reply was sent by a Sieve script.
.
;
# Important mail stays in the inbox, the rest is sorted by domain.
if hasflag "\\Flagged" {
keep;
} else {
fileinto :create "Contacts/${domain}";
}