I am a newbie at handling MIME lists in emacs. I want to edit the mu4e-action-view-in-browser
function so that before an email is displayed on a web browser all of its Microsoft Safelinks urls are filtered. I have developed an elisp function called unsafelinks to do this operation (both functions written below).
Find here an edited raw email with a link for testing purposes. Here is another example of a message which cannot be decoded by a simple hook of the unsafelinks
function to the gnus-article-decode-hook
(as suggested by @db48x). I am currently reading the documentation on how to bypass the "=" linebreak format of this last message.
(defun mu4e-action-view-in-browser (msg)
"Show current MSG in browser if it includes an HTML-part.
The variables `browse-url-browser-function',
`browse-url-handlers', and `browse-url-default-handlers'
determine which browser function to use."
(with-temp-buffer
(insert-file-contents-literally
(mu4e-message-field msg :path) nil nil nil t)
(run-hooks 'gnus-article-decode-hook)
(let ((header (cl-loop for field in '("from" "to" "cc" "date" "subject")
when (message-fetch-field field)
concat (format "%s: %s\n" (capitalize field) it)))
(parts (mm-dissect-buffer t t)))
;; If singlepart, enforce a list.
(when (and (bufferp (car parts))
(stringp (car (mm-handle-type parts))))
(setq parts (list parts)))
;; Process the list
(unless (gnus-article-browse-html-parts parts header)
(mu4e-warn "Message does not contain a \"text/html\" part"))
(mm-destroy-parts parts))))
(defun unsafelinks ()
"This function filters MS safelinks from a message buffer"
(interactive)
(beginning-of-buffer)
(let ((simple-url-regexp "https?://") urls)
(save-excursion
;; edit text URLs
(while (search-forward-regexp simple-url-regexp nil t)
(when-let ((url (thing-at-point 'url))
(bounds (thing-at-point-bounds-of-url-at-point)))
(delete-region (car bounds) (cdr bounds))
(insert (my-decode-safelink url)))))))
(require 'url-parse)
(defun my-decode-safelink (url)
;; (print url)
"Given a url string this function returns the corresponding decoded url"
(if (string-match-p (regexp-quote "safelinks.protection") url)
(let* ((query (url-filename (url-generic-parse-url url)))
(url (cadr (assoc ".*/?url" (url-parse-query-string query) (lambda (pat x) (string-match-p x pat)))))
(path (replace-regexp-in-string "3Dhttps" "https" (url-unhex-string url))))
(url-encode-url (replace-regexp-in-string (rx "/" (>= 20 (any "#$%&*^@"))) "" path)))
url))