Permalink
Find file
7b7a124 Oct 1, 2016
297 lines (219 sloc) 9.63 KB

Reading and Sending Email in Emacs

To goals of Email in Emacs. First, to be able to easily send org-mode files to colleagues, and second, to be able to quickly read the newest email messages that arrive on my GMail account.

OfflineIMAP

Followed these instructions to get offlineimap working. First:

sudo apt-get install offlineimap

Then:

  • Created ~/.offlineimaprc, and changed the following:
    • folderfilter = lambda folder: folder.startswith('INBOX')
    • maxage = 7
  • Created .offlineimap.py shell script to return the password.
  • Set up both smtp and imap in .authinfo file.

The first time I ran it, it takes a while to download the latest email messages. After this point, I can put it in a cronjob.

MU4E

Using mu4e, which required cloning the Github repo, and building it from source. First, install the dependencies:

sudo apt-get install libgmime-2.6 libxapian-dev

And build it and install it in /usr/local (which includes installing mu4e in the [[file:/usr/local/share/emacs/site-lisp/mu4e/][site-lisp]]:

autoreconf -i && ./configure && make && sudo make install

Finally, combine these into a single cronjob:

offlineimap && mu index --maildir=~/Maildir

Now, we just have to require it:

(require 'mu4e nil t)

Point it to the full binary of the mu:

(setq mu4e-mu-binary "/usr/local/bin/mu")

And connect it to the drop-off location for offlineimap:

(setq mu4e-maildir (expand-file-name "~/Maildir"))

I’m only download the INBOX, but otherwise, I would set these:

(setq mu4e-drafts-folder "/[Gmail].Drafts")
(setq mu4e-sent-folder   "/[Gmail].Sent Mail")
(setq mu4e-trash-folder  "/[Gmail].Trash")

Don’t save message to Sent Messages, as GMail/IMAP will take care of this:

(setq mu4e-sent-messages-behavior 'delete)

Wonder if these would be handy shortcuts:

(setq mu4e-maildir-shortcuts
      '(("/INBOX"             . ?i)
        ("/[Gmail].Sent Mail" . ?s)
        ("/[Gmail].Trash"     . ?t)))

Allow for updating mail using ‘U’ in the main view:

(setq mu4e-get-mail-command "offlineimap")

However, I’m not sure if using that command will automatically index it or not.

Finally, we need to make sure that we can have org-mode link to mail messages through mu4e:

(require 'org-mu4e nil t)

Sending Email

To send to GMail, we need to install TLS:

sudo apt-get install gnutls-bin

Require and set to use the TLS:

(require 'starttls)
(setq starttls-use-gnutls t)

Now, configure the SMTP subsystem:

(require 'smtpmail)

(setq send-mail-function            'smtpmail-send-it
      message-send-mail-function    'smtpmail-send-it
      smtpmail-auth-credentials     (expand-file-name "~/.authinfo.gpg")
      smtpmail-stream-type          'tls
      smtpmail-smtp-server          "smtp.gmail.com"
      smtpmail-smtp-service         465)

To send email to an Exchange server, change the port:

(setq send-mail-function  'smtpmail-send-it
      message-send-mail-function    'smtpmail-send-it
      smtpmail-auth-credentials     (expand-file-name "~/.authinfo.gpg")
      smtpmail-smtp-server  "smtp.office365.com"
      smtpmail-stream-type  'starttls
      smtpmail-smtp-service 587)

To send a normal text message, type C-x m and fill out the fields. Hit C-c C-c to send it. Problems, you might want to turn on debugging:

(setq starttls-use-gnutls t)
(setq smtpmail-debug-info t)
(setq smtpmail-debug-verb t)

Org-Mime

To send formatted =org-mode= files, like this, first, install the org-plus-contrib package from ELPA (but do not install the org-mime package, as that is old and broken, see this discussion for details.

Require this [[http://orgmode.org/worg/org-contrib/org-mime.html][org-mime]] system (that is part of org-plus-contrib):

(use-package org-plus-contrib
  :ensure t
  :init   (require 'org-mime))

This gives us a new function, org-mime-org-buffer-htmlize which allows us to send the entire buffer (or region) as email.

If your org-mode file contains BEGIN_SRC blocks (like what is the literate point, otherwise), then you’ll need to install and use this the htmlize project:

(use-package htmlize
   :ensure t)

We just need to touch up a bit of the CSS that is sent:

(add-hook 'org-mime-html-hook
        (lambda ()
          (org-mime-change-element-style
           "pre" "margin-left: 2em;")))

According to this example, all block-quotes are trimmed down:

(add-hook 'org-mime-html-hook
        (lambda ()
          (org-mime-change-element-style
           "blockquote" "border-left: 2px solid gray; padding-left: 4px;")))

The final trick is to give it a nicer keystroke. Since C-x m sends a blank email, how about Shift-M?

(global-set-key (kbd "C-x M") 'org-mime-org-buffer-htmlize)

Address Book

Using the Insidious Big Brother Database (BBDB) for the basics of easily sending email to co-workers, teams and whatnot.

(when (require 'bbdb nil t)
  (bbdb-initialize)
  (setq bbdb-offer-save 1                        ;; 1 means save-without-asking

        bbdb-use-pop-up t                        ;; allow popups for addresses
        bbdb-electric-p t                        ;; be disposable with SPC
        bbdb-popup-target-lines  1               ;; very small

        bbdb-dwim-net-address-allow-redundancy t ;; always use full name
        bbdb-quiet-about-name-mismatches 2       ;; show name-mismatches 2 secs

        bbdb-always-add-address t                ;; add new addresses to existing...
                                                 ;; ...contacts automatically
        bbdb-canonicalize-redundant-nets-p t     ;; x@foo.bar.cx => x@bar.cx

        bbdb-completion-type nil                 ;; complete on anything

        bbdb-complete-name-allow-cycling t       ;; cycle through matches
                                                 ;; this only works partially

        bbbd-message-caching-enabled t           ;; be fast
        bbdb-use-alternate-names t               ;; use AKA

        bbdb-elided-display t                    ;; single-line addresses

        ;; auto-create addresses from mail
        bbdb/mail-auto-create-p 'bbdb-ignore-some-messages-hook
        bbdb-ignore-some-messages-alist ;; don't ask about fake addresses

        ;; NOTE: there can be only one entry per header (such as To, From)
        ;; http://flex.ee.uec.ac.jp/texi/bbdb/bbdb_11.html
        '(( "From" . "no.?reply\\|DAEMON\\|daemon\\|facebookmail\\|twitter"))))

Along with some other useful mu4e settings, I found this function to add the sender to the bbdb database:

(defun mu4e-add-bbdb (field)
  (interactive "sField (f)rom / (t)o / (c)c: ")
  (let* ((fieldsym (cond
                    ((string-prefix-p "f" field t) :from)
                    ((string-prefix-p "t" field t) :to)
                    ((string-prefix-p "c" field t) :cc)))
         (tuple (mu4e-field-at-point fieldsym))
         (name (car (car tuple)))
         (addr (cdr (car tuple))))
    (bbdb-create-internal name nil nil nil addr)))

(defun mu4e-add-bbdb-sender ()
  (interactive)
  (mu4e-add-bbdb "f"))

(defun mu4e-add-bbdb-from ()
  (interactive)
  (mu4e-add-bbdb "f"))

(defun mu4e-add-bbdb-to ()
  (interactive)
  (mu4e-add-bbdb "t"))

Technical Artifacts

Make sure that we can simply require this library.

(provide 'init-mail)

Before you can build this on a new system, make sure that you put the cursor over any of these properties, and hit: C-c C-c