smart refiling to variable maildir

14 views
Skip to first unread message

Christopher Causer

unread,
Jul 20, 2021, 9:03:38 AM7/20/21
to mu-discuss
Hi there,

I posted this on StackExchange but I haven't had a response, and the low number of views is making me think that SE isn't where mu4e people hang out, so apologies for cross-posting but I hope you understand. What I'm asking seems reasonably sane to me but my elisp isn't good enough to see this through to the end. What follows is taken from the original question:

Mu4e documentation has an example of smart refiling, whereby you can choose which maildir to refile an email based on the properties of that email. I'd like to do that, except the destination maildir's name is a property of the email (specifically the :to property).

Probably easiest to explain in an example. In the documentation:

(setq mu4e-refile-folder
  (lambda (msg)
    (cond
      ;; messages to the mu mailing list go to the /mu folder
      ((mu4e-message-contact-field-matches msg :to
     "mu-di...@googlegroups.com")
    "/mu")
    ;; ........[ SNIP ]
 )))

In this example all emails to a google groups mu-di...@googlegroups.com end up in the /mu maildir. I'd like to go one further. I'd like %anything%@googlegroups.com to go to the maildir /googlegroups/%anything%, for any value of %anything%.

Does anyone have any pointers on how to do this?


Yuri D'Elia

unread,
Jul 23, 2021, 4:18:37 PM7/23/21
to mu-di...@googlegroups.com, Christopher Causer
On Tue, Jul 20 2021, Christopher Causer wrote:
> (setq mu4e-refile-folder
> (lambda (msg)
> (cond
> ;; messages to the mu mailing list go to the /mu folder
> ((mu4e-message-contact-field-matches msg :to
> "mu-di...@googlegroups.com")
> "/mu")
> ;; ........[ SNIP ]
> )))

What about this untested snippet to get you started:

(setq mu4e-refile-folder
(lambda (msg)
(let* ((to (split-string (cdar (mu4e-message-field msg :to)) "@"))
(user (car to))
(domain (cadr to)))
(when (eq domain "googlegroups.com")
(concat "/groups/" user)))))

The important bit is to extract the :to field and act on it instead of
using "contact-field-matches", which does just the test.

The problem with the snippet above is that it's not robust, so you need
to work on it.

We're taking the first "to" address only (there might be none!, or more
than one where "googlegroups" is not the first), and simply splitting
the address with "@" (not sure how deeply the address we get here is
sanitized). There might be better functions to operate on email adresses
looking in the gnus-message code.

Then we take the user part, and simply concatenate the results to get a
folder name. I wouldn't do that: either this needs to be furthermore
sanitized for a path name, or I would pass that to a whitelist.

Christopher Causer

unread,
Aug 5, 2021, 10:57:41 AM8/5/21
to mu-discuss
On Friday, 23 July 2021 at 21:18:37 UTC+1 wav...@thregr.org wrote:
(setq mu4e-refile-folder
(lambda (msg)
(let* ((to (split-string (cdar (mu4e-message-field msg :to)) "@"))
(user (car to))
(domain (cadr to)))
(when (eq domain "googlegroups.com")
(concat "/groups/" user)))))

Thanks for this. Some useful ideas in here for a beginner. I'd never seen cadr and cdar before.

Just for the record, I wrote my currently working solution to the SE page:

(defun personal/refile-maildir (msg)
  "Refile based on a message's characteristics"
  (let*
      ((to-addresses (mu4e-message-field msg :to))
       (maillist-addr  (cl-find-if
                        (lambda (to) (s-suffix? "@googlegroups.com" (cdr to)))
                        to-addresses)))
    (cond
     (maillist-addr
        (concat "/googlegroups." (s-chop-suffix "@googlegroups.com" (s-downcase (cdr maillist-addr)))))
       (t "/Archive"))))

This seems to have the benefit of refiling when there's a @googlegroups.com anywhere in any of the "to" fields, not just the first one. Obviously it cannot do BCC, but I don't think it's possible.
Reply all
Reply to author
Forward
0 new messages