foxcpp / maddy

✉️ Composable all-in-one mail server.
https://maddy.email
GNU General Public License v3.0
5.01k stars 241 forks source link

Deliver-To Address Support in IMAP Filtering #495

Closed FIGBERT closed 2 years ago

FIGBERT commented 2 years ago

Use case

I'm working on moving my self-hosted git repositories from Gitea to a combination of stagit and crabmail. To do so, I've created a new email, lists@figbert.com, and plan on utilizing subaddressing (i.e. lists+general@figbert.com, lists+dockerfiles@figbert.com, etc.) to organize the various lists.

To get emails to deliver properly with subaddressing, I run the following regex (ripped from the default config):

table.chain local_rewrites {
    optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3"
    optional_step file /data/aliases
}

To sort these subaddressed emails into their respective folders (eventually exported as maildirs with mbsync), I've turned to IMAP filters, and run the following script:

#!/bin/sh
echo ${1} | sed -rn -e 's/lists\+(general|dockerfiles)@figbert\.com/\1/p'

I call this script using the following snippet:

command /data/sieve.sh {account_name}

The {account_name} variable, however, doesn't contain the subaddress and instead just holds the "effective IMAP account name": lists@figbert.com. So the filter doesn't work, and the emails get delivered to the inbox.

None of the available variables for imap.filter.command give actual address.

Your idea for a solution

imap.filter.command should have access to the address in the To: field.

ptrcnull commented 2 years ago

when it comes to the To: field in the message, you get the whole message body on standard input, so you can parse it in the script, with something like this:

while read line; do
    case "$line" in
    Subject:*)
        subject="$(echo $line | cut -c10- | tr -d '\r')" ;;
    To:*)
        to_address="$(echo $line | cut -c5- | tr -d '\r')" ;;
    esac
done

(actually you should probably do proper imf parsing, but it's a really simple example that mostly works)

though it would be useful to have SMTP RCPT TO address exposed as a variable, because i don't think it actually is

FIGBERT commented 2 years ago

That is incredibly helpful! I've whipped up a quick script in Go and have email filtering working.

Not certain about the future of this issue. I think the most important thing is to document that the message is passed via stdin – that basically exposes any variables that one might need. It still may be useful to have more variables exposed directly, however. I'm open to thoughts and feedback.

foxcpp commented 2 years ago

There is https://github.com/foxcpp/maddy/pull/449 which adds a bunch of new fields, including {address}. It was merged into dev for 0.6 but it was never released since I had little time lately. :(

ptrcnull commented 2 years ago

Thanks for the mention - I've been looking at the docs at https://maddy.email and missed that it's already a thing on the dev branch, gonna test it out soon :heart:

foxcpp commented 2 years ago

P.S. Take a backup of your DB first since dev branch introduces significant changes to data structure.