Una de las cosas que siempre he tenido ganas pero me ha dado mucha pereza ponerme a hacer ha sido configurar el correo para gestionarlo a través de emacs. Hace un par de días decidí dar el paso, hoy lo he estado probando y ha merecido la pena el esfuerzo
Aquí están todos los pasos que he tenido que dar para configurar una cuenta de Gmail en Emacs y en Debian.
Offlineimap
Lo primero que necesitamos es un cliente de imap. Este cliente será el que se encargue de actualizar nuestra cuenta de gmail, sincronizando los cambios entre nuestro local y el servidor de Google. Para eso he instalado offlineimap
sudo apt-get install offlineimap
Después de descargar el programa debemos configurarlo de la siguiente manera, comenzaremos creando un fichero de configuración en: ~/.offlineimaprc
El contenido del fichero es el siguiente. Esta es la configuración básica que he encontrado en los ejemplos, de aquí deberemos cambiar el usuario del email, en el ejemplo está como [email protected]. Importante fijarse que está en dos lineas.
También podremos cambiar la carpeta donde queramos que se descargue el correo. El password como podéis ver no está añadido, ese es el siguiente paso.
[general]
accounts = Gmail
maxsyncaccounts = 1
pythonfile = ~/.offlineimap.py
[Account Gmail]
localrepository = Local
remoterepository = Remote
[Repository Local]
type = Maildir
localfolders = ~/Maildir
[Repository Remote]
type = Gmail
remoteuser = [email protected]
remotepasseval = get_password_emacs("imap.gmail.com", "[email protected]", "993")
realdelete = no
folderfilter = lambda foldername: foldername not in ['[Gmail]/Spam', '[Gmail]/All Mail', '[Gmail]/Starred', '[Gmail]/Important']
holdconnectionopen = true
keepalive = 60
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
Para no tener que guardar el password en texto plano en nuestra configuración de offlineimap debemos crear un par de ficheros mas y hacer alguna cosilla. Empezaremos por crear un fichero ~/.offlineimap.py con el siguiente contenido dentro:
#!/usr/bin/python
import re, os
def get_password_emacs(machine, login, port):
s = "machine %s login %s port %s password ([^ ]*)\n" % (machine, login, port)
p = re.compile(s)
authinfo = os.popen("gpg -q --no-tty -d ~/.authinfo.gpg").read()
return p.search(authinfo).group(1)
Del fichero .py no hay que tocar nada, simplemente se encarga de leer un fichero que crearemos ahora donde se encontrará la contraseña.
El siguiente paso es crear el fichero ~/.authinfo, en este fichero deberemos introducir lo siguiente, cambiando [email protected] por nuestro usuario y aquivaelpassword por nuestra contraseña.
machine imap.gmail.com login [email protected] port 993 password aquivaelpassword
machine smtp.gmail.com login [email protected] port 587 password aquivaelpassword
Y ahora viene el encriptado del fichero, ya que si lo dejamos así estaría en texto plano.
El cifrado lo realizaremos desde emacs, ejecutando el siguiente comando y seleccionado el fichero .authinfo que acabamos de crear.
M-x epa-encrypt-file
Esto nos generará un fichero ~/.authinfo.gpg, una vez creado debemos eliminar el original.
Y con esto ya tenemos configurado nuestro imap lo siguiente sería sincronizar con el siguiente comando y tomarnos algo mientras tanto, porque tardará bastante.
$ offlineimap
¿Qué pasa si tengo doble factor de autenticación en mi correo?
Posiblemente tendréis habilitado un segundo factor de autenticación en vuestra cuenta, en ese caso no podréis usar vuestra contraseña, para solucionar eso tenemos dos opciones:
- Crear una aplicación Oauth en Google y usarla con offlineimap. Esta opción no la he probado, así que no se como se haría, si que he visto algún post comentando como se hace.
- Crear un pasword de aplicación para el correo electrónico desde vuestra cuenta de google y usarlo como password. Aquí teneis como se realiza. He visto quien desaconseja esta última opción ya que sería como quitar el doble factor de autenticación y recomiendan usar el token de Oauth. Mi impresión es que estaríamos en las mismas, ya que el password de aplicación tiene también la opción de cancelarlo y así invalidar esa aplicación.
Posible error con gpg
Al ejecutar todo el proceso en otra máquina me encontré con el siguiente error a la hora de ejecutar offlinimap: gpg: Sorry, no terminal at all requested - can't get input
La solución mas sencilla que he encontrado ha sido cambiar en el script de Python gpg por gpg2. Quizás antes tengais que instalarlo, en Debian sería con
apt-get install gnupg2
y habría que dejar el script ~/.offlineimap.py de la siguiente manera:
#!/usr/bin/python
import re, os
def get_password_emacs(machine, login, port):
s = "machine %s login %s port %s password ([^ ]*)\n" % (machine, login, port)
p = re.compile(s)
authinfo = os.popen("gpg2 -q --no-tty -d ~/.authinfo.gpg").read()
return p.search(authinfo).group(1)
Creando el indice
Una vez ya ha terminado offlineimap de sincronizar debemos indexar, para ello nos hará falta mu, como también nos hará falta mu4e lo instalamos e indexamos.
sudo apt-get install mu4e
mu index --maildir=~/Maildir
Cron
Lo siguiente que he hecho y que mas me ha costado encontrar es como hacer estas tareas cada X tiempo, no por que sea complejo si no porque no he visto nada relacionado. Yo he decidido crear un cron que lo ejecute cada 5 minutos.
crontab -e
Y como contenido:
*/5 * * * * offlineimap -u quiet && mu index --maildir=~/Maildir
Envío de correos
Para envíar los correos desde emacs hace falta instalar lo siguiente en Ubuntu/Debian
sudo apt-get install gnutls-bin
Configurando Emacs
Aún no he tocado demasiado, estoy aún aprendiendo el modo mu4e, así que esta configuración es opcional. Dejo aquí la mía como ejemplo.
Imap
(require 'mu4e)
;; default
(setq mu4e-maildir (expand-file-name "~/Maildir"))
(setq mu4e-drafts-folder "/[Gmail].Borradores")
(setq mu4e-sent-folder "/[Gmail].Enviados")
(setq mu4e-trash-folder "/[Gmail].Papelera")
;; don't save message to Sent Messages, GMail/IMAP will take care of this
(setq mu4e-sent-messages-behavior 'delete)
;; setup some handy shortcuts
(setq mu4e-maildir-shortcuts
'(("/INBOX" . ?i)
("/[Gmail].Enviados" . ?s)
("/[Gmail].Papelera" . ?t)))
;; allow for updating mail using 'U' in the main view:
(setq mu4e-get-mail-command "offlineimap")
(setq
user-mail-address "usuario@gmail"
user-full-name "Nombre Apellido"
)
SMTP (envío)
(require 'smtpmail)
(setq message-send-mail-function 'smtpmail-send-it
starttls-use-gnutls t
smtpmail-starttls-credentials
'(("smtp.gmail.com" 587 nil nil))
smtpmail-auth-credentials
(expand-file-name "~/.authinfo.gpg")
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
smtpmail-debug-info t)
Alertas
Nos pintará en nuestra barra un sobrecito con el número de correos sin leer, lo ejecutará cada minuto y además mostrará alertas del sistema.
(use-package mu4e-alert
:ensure t
:after mu4e
:init
(setq mu4e-alert-interesting-mail-query
(concat
"flag:unread AND maildir:/INBOX AND NOT flag:trashed "
))
(mu4e-alert-enable-mode-line-display)
(defun gjstein-refresh-mu4e-alert-mode-line ()
(interactive)
(mu4e~proc-kill)
(mu4e-alert-enable-mode-line-display)
)
(run-with-timer 0 60 'gjstein-refresh-mu4e-alert-mode-line)
)
Como podéis ver este código por ahora es prácticamente copiado y pegado de las fuentes, como he dicho aún no he tenido tiempo de tocarlo demasiado y quizá tampoco me haga falta.
mu4e
Pues poco puedo contar de este modo, aún tengo que aprender a manejarlo bien. Si ejecutáis en emacs
M-x mu4e
os mostrará un pequeño dashboard donde podréis comenzar a usarlo, con documentación incluida.
Conclusión
Solo llevo un día de uso y me ha resultado muy útil, sobre todo para hacer limpieza de correos. Me costó un poco configurarlo todo, pero una vez conseguido ha merecido mucho la pena.
Una recomendación que me gustaría daros es que no uséis gmail, en este caso lo hice porque es el correo del trabajo, podéis usar cualquier correo que acepte IMAP y SMTP y seguramente con algún protocolo mas también. Os dejo con un listado de servicios y herramientas que si tienen en cuenta la privacidad del usuario, ahí podréis encontrar buenos servicios de email.
Cualquier duda puedes preguntarme por gnusocial.net.