Enviar correo a través de Gmail con Python

Python

Buenas... pues para aquellos que necesiten hacer un programita que mande notificaciones a alguien, puede usar alguno de los cientos de programas que existen por ahí... o puede hacer su propio notificador vía e-mail. En python es ultra sencillo y hay varios métodos, que yo conozca: conectar a un servidor SMTP, autenticarse y mandar el mensaje; o ser uno mismo el servidor y conectarse con un relay que te autorice (también soportado en python). En esta receta explicamos la primera, que es más simple (aunque también requiere tener la contraseña por algún lado, en el ejemplo la pediremos al usuario y listo...).

A cerca de Gmail

Bueno, este servidor, al igual que otros muchos por ahí, utiliza conexiones cifradas, por lo que mandar un correo nos obligará a establecer una conexión segura antes de autenticarnos (lo cual está muy requetebién y es muy sencillo).

Supongo que esta receta funcionará igual para todos aquellos servidores que requieran TLS puesto que cumple con la RFC 821 y la RFC 1869 (que alguien ponga los enlaces si quiere, yo voy con prisas Sticking out tongue).

Componer el mensaje

En python un mail es básicamente un diccionario cuyas keys son los nombres de los campos: Subject, Reply-To, etc... pero que además nos ofrece un par de métodos interesantes que nos permiten attach-ear imágenes y codificar todo el mensaje como mensaje MIME:

Mensaje de texto corriente y moliente

from email.MIMEText import MIMEText
msg = MIMEText("Hello World,\no algo parecido...")
msg['Subject'] = 'Esto es una prueba'
msg['From'] = "Juancar I"
msg['Reply-to'] = "La casa ficticia"
msg['To'] = "La Sofi"

Como dijimos antes, los campos se tratan igual que en un diccionario. Hay que tener en cuenta que no son obligatorios y que podemos falsear el origen y el destino del mismo, aunque para enviar el correo SI es necesario origen y destino reales, pero los datos que aparecerán en el correo al destinatario serán los que pongamos aquí. Tened cuidado con poner cosas demasiado "raras" o no rellenar suficientes campos porque entonces vuestro mail será considerado Spam casi con toda seguridad...

Mensaje con texto y fotos

Esto está sacado de la documentación de python y no lo he probado, pero en teoría funciona, si alguien me lo confirma pues mejor que mejor. Como dije antes, voy con prisa! Sticking out tongue

from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
 
msg = MIMEMultipart()
msg['Subject'] = 'Tu maridito achantando!'
msg['From'] = 'Juancar I'
msg['To'] = 'La Sofi'
msg.preamble = 'Nuestro viajecito pagado'
imagen = open('/home/juancar/vacaciones/visita_usa/callate01.png', 'rb')
attachment = MIMEImage(imagen.read())
imagen.close()
msg.attach(attachment)

Aquí tenéis cómo enviar un mensaje con imágenes, podéis attachear cuantas imágenes queráis de la misma manera. Si queréis envíar sonidos o algún otro tipo de fichero, consultad la documentación de python porque se pueden componer cosas bastante chulas de forma similar (básicamente cambiar la clase MIMEImage por una más adecuada).

Conectar con el servidor SMTP

Asumimos aquí que tienes un objeto msg construído como anteriormente explicamos, pues bien, la cosa queda más o menos tal que así:

import getpass
import smtplib
sender = smtplib.SMTP('smtp.gmail.com')
sender.ehlo()
sender.starttls()
usuario_gmail = 'ssmm_juancar'
sender.login(usuario_gmail, getpass.getpass())
origen = usuario_gmail + '@gmail.com'
destino = 'ssmm_sofi@yahoo.es'
sender.sendmail(origen, destino, msg.as_string())
sender.close()

Y así de fácil es!
En este punto sabed que el origen y el destino deben ser auténticos, en caso contrario, el servidor de gmail nos dirá que hasta luego (y en el error nos da un bonito enlace con ayuda sobre su SMTP). Otra cosa más, si nuestro servidor utiliza algún tipo de certificado especial, se puede especificar en la función starttls().

Enlaces