Mail.app random signatures

Posted on Mar 12, 2024

When using an emacs based mail client for many years, I collected various song lyrics that I particularly enjoyed and automatically added them to my signature on outgoing email. As a result of various life changes I’m consuming a lot less email, and have largely switched to Mail.app, which can cope fine with the reduced volume.

I missed my signatures, though, and it doesn’t seem to be possible to write a Mail.app plugin to get them back with the officially supported APIs from Apple (there are some solutions that monkey patch their way in, but they seem unreliable and regularly break).

Mail.app does support adding random signatures from a list, but maintaining that list by hand is painful. Instead, here is a small elisp script that will initialise the available signatures via Applescript.

It uses the same cookie file format as the source, which was easiest for me, but you could easily switch to something else.

No warranty, please let me know if you have trouble or enjoy it 😃

(require 'cookie1)

;;

(defvar maildotapp-signatures (expand-file-name "~/u/lib/fortune")
  "A file containing quips to use as part of a signature, in a format
understood by the `cookie-snarf' function.")

;;

(defun maildotapp-signature--delete-existing ()
  (ns-do-applescript "
tell application \"Mail\"
     set sigCount to (count of signatures)
     repeat sigCount times
          delete signature 1
     end repeat
end tell
"))

(defun maildotapp-signature--add-sig (name content)
  (ns-do-applescript (format "
tell application \"Mail\"
     make new signature at beginning of signatures with properties {name:\"%s\", content:\"%s\"}
end tell
"
			     name
			     content)))

(defun maildotapp-signature--prepare (quip)
  "Based on a QUIP, prepare a complete signature."
  (concat "dme.\n-- \n" quip))

(defun maildotapp-signature--quote (string)
  "Ensure that STRING is safely quoted."
  ;; XXX dme: This is something, but it is enough?
  (replace-regexp-in-string "\"" "\\\\\"" string))

;;

(defun maildotapp-signature-go! ()
  "Replace all of the signatures in Mail.app with those from
`maildotapp-signatures'.

After running this function, go to Mail.app and set the 'Choose
Signature:' option of relevant accounts to 'At Random'."
  (interactive)

  (maildotapp-signature--delete-existing)

  (let ((signatures (cookie-snarf maildotapp-signatures)))
    (mapcar (lambda (content)
	      (maildotapp-signature--add-sig (maildotapp-signature--quote (substring content 0 (min 30 (length content))))
					     (maildotapp-signature--prepare (maildotapp-signature--quote content))))
	    signatures)))