Skip to content

Instantly share code, notes, and snippets.

@xenodium
Last active June 9, 2023 16:19
Show Gist options
  • Save xenodium/f26882453d054e76d3f8517556a9ac43 to your computer and use it in GitHub Desktop.
Save xenodium/f26882453d054e76d3f8517556a9ac43 to your computer and use it in GitHub Desktop.
[Experiment] Mark mu4e messages as spam/junk using ChatGPT NOTE: sender email, name, subject, and docid sent to ChatGPT
;; Needs make-mu4e-context :vars mu4e-spam-folder set.
;; Generates `mu4e-headers-mark-for-spam'.
(mu4e~headers-defun-mark-for spam)
(defun ar/mu4e-mark-junk-candidates-using-chatgpt ()
"Mark potential messages as junk by asking ChatGPT."
(interactive)
(save-restriction
(narrow-to-region (window-start)
(window-end-visible))
(let* ((prompt (concat
"for each of the following emails in an org table, evaluate if the message has a chance of being spam. return a list of \"Message ID\" that are likely spam. only reply with a list of IDs and nothing else. one ID per line."
(ar/mu4e-junk-candidates-to-org-table (ar/mu4e-header-view-messages))))
(response (chatgpt-shell-post-prompt prompt "gpt-3.5-turbo"))
(spam-candidates (split-string (string-trim response) "\n")))
(mapc (lambda (candidate)
(ar/mu4e-header-jump-to-docid candidate)
(mu4e-headers-mark-for-spam))
spam-candidates))))
(defun ar/mu4e-header-view-messages ()
(unless (eq major-mode 'mu4e-headers-mode)
(user-error "Not in *mu4e-headers*"))
(let ((items))
(save-excursion
(goto-char (point-min))
(while (not (eobp))
(when-let* ((msg (mu4e-message-at-point t))
(from (car-safe (mu4e-message-field msg :from)))
(item `((:docid . ,(mu4e-message-field msg :docid))
(:subject . ,(mu4e-message-field msg :subject))
(:email . ,(plist-get from :email))
(:name . ,(plist-get from :email)))))
(add-to-list 'items item))
(mu4e-headers-next)))
items))
(defun ar/mu4e-header-jump-to-docid (docid)
"Move point mu4e message with DOCID."
(let ((pos))
(save-excursion
(goto-char (point-min))
(setq pos (search-forward docid)))
(goto-char pos)))
(defun ar/mu4e-junk-candidates-to-org-table (candidates)
"Convert CANDIDATES to org table.
CANDIDATES are of the form:
((:docid . 1234)
(:subject . \"Hello friend\")
(:email . \"someone@somewhere.com\")
(:name . \"John Doe\"))"
(orgtbl-to-orgtbl
(append
(list (list "Message ID" "Sender name" "Sender email" "Subject"))
(mapcar (lambda (msg)
(list (number-to-string (map-elt msg :docid))
(map-elt msg :subject)
(map-elt msg :email)
(or (map-elt msg :name) "")))
candidates))
nil))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment