Thursday, April 16, 2020

gnus filtering html body mail

If you love emacs, you probably use gnus, which is in my opinion the
best mailer ever.
You can manage your complete filter in emacs lisp, and there are so many
ways to filter stuff.

The most complex and useful filtering method is using
"nnmail-split-fancy".

Which as I'm showing in this example, can be set as something like this:

(setq nnmail-split-fancy
      '(|
 ("subject" ".*/var/log/messages.*" "server_syslogs")
 (any "some_sender" "some_annoying_sender")
 ;; to me, not mailing lists
 (any ".*MY_NAME.*"
      (|
       (from ".*some_from_field.*" "some_company")
       (from "some_mailer_that_needs_body_filtering"
      (| 
       (: split-on-body ".*Assignee: MY_NAME.*" "your_service_me_assigned")
       (: split-on-body ".*Reporter: MY_NAME.*" "your_service_me_requested")
       "your_crappy_service")))
      "me_somewhere"
      ))
      "misc")

This would split stuff by subject first (having /var/log/messages in the subject), then see if the header contains "some_sender" and put the mail in the mail folder "some_annoying_sender". If neither of those matched, then would look for MY_NAME in the mail header, and split the logic even further, to split from the "from" header, and even on the mail body. It can be any function, but this "split-on-body" one is a common one I guess, since it comes with the documentation and all.
This is the split-on-body function:
(defun split-on-body (regexp-to-search group-to-split)
  (save-excursion
    (save-restriction
      (widen)
      (goto-char (point-min))
      (when (re-search-forward regexp-to-search nil t)
 group-to-split))))

And it works great. But you get issues when filtering HTML mail... which gnus kind of usually parses someway (when you read it on gnus, it'll depend on the value of the "mm-text-html-renderer" variable).
The thing is, when the mail is being filtered, the text apparently is all in pure text, and that text kind of differs from the actual raw mail body, or what you see parsed in the mail view.
So, in short, you'll need to get the correct regexp, which you can't see anywhere but in the filter function itself...
So, here is a filter function for that purpose. It's pretty much the same as the above, but you get the prin1 text for the complete mail text in you *Messages* buffer.
;; debug version
(defun split-on-body (regexp-to-search group-to-split)
  "debug version"
    (save-excursion
      (save-restriction
 (widen)
 (goto-char (point-min))
 (message "searching for regexp in split on body")
 (let ((search-results (re-search-forward regexp-to-search nil t))
       (complete-buffer (prin1 (buffer-substring (point-min) (point-max))))
       )
   (message (concat  "regexp to search for = " regexp-to-search))
   (message (concat "search results =" (format "%S" search-results))))
 (goto-char (point-min))
 (when (re-search-forward regexp-to-search nil t)
   group-to-split))))

For some reason I didn't think of this until like 10 years after
starting using gnus...

No comments:

Post a Comment