Enviar correo electrónico con Python usando smtplib

En este tutorial vamos a ver cómo enviar mensajes de correo electrónico usando la biblioteca smtplib. Además vamos a programar una interfaz gráfica que permita tomar el texto de una caja de entrada y enviarlo usando el smtplib.

Herramientas
Vamos a usar, en este tutorial:

  • Geany como IDE.
  • Python (por supuesto).
  • Una versión reciente de Glade (al menos 3.6).
  • Posiblemente haga falta una versión actual de pygtk también.
Uso de smtplib
Para comenzar, vamos a escribir un pequeño programa que sea capaz de enviar un mensaje de email usando una cuenta de Gmail.

Lo primero es importar la biblioteca smtplib:

import smtplib


Ahora generamos el mensaje. Primero pedimos el nombre del remitente, luego la dirección de destino y por último el mensaje en sí:

DE = raw_input("Remitente: ")
PARA = [raw_input("Destino: ")]
texto = """
%s""" % raw_input("Mensaje: ")


Analicemos cada línea: al pedir el remitente no hay nada de especial, cuando pedimos la dirección de destino hay que recordar que se debe guardar como una lista, y, por último, al pedir el texto hay que tener en cuenta que se envía desde la segunda línea para adelante.

Creamos un objeto al que llamamos "server" usando la clase smtplib.SMTP() de la biblioteca smtplib, nos autenticamos y enviamos el mensaje:

server = smtplib.SMTP("smtp.gmail.com:587")
server.starttls()
server.login("nombredeusuario", "contraseña")
server.sendmail(DE, PARA, texto)
server.quit()


Gráficamente
Vamos a crear una interfaz gráfica para el programa anterior.

Abrimos Glade y creamos una ventana con una caja horizontal de cuatro elementos. Le damos por nombre "ventanaprincipal" a nuestra ventana y le ponemos una anchura predeterminada de 400 y una altura predeterminada de 300 en sus propiedades (pestaña General):

En la parte superior de nuestra caja colocamos una vista de texto, en la segunda y en la tercera una entrada de texto, y en la cuarta una botonera de un solo elemento. Dentro de esa botonera colocamos un botón:

Le ponemos nombres a nuestros elementos: a nuestra vista de texto le ponemos "mensaje", a nuestras entradas de texto "remitente" y "destino" (además cambiamos su propiedad "Texto", en la pestaña General, por "Remitente" y "Destino", respectivamente), y a nuestro botón "botonenviar (y le ponemos en su propiedad Etiqueta la palabra "Enviar"):

Le damos el manipulador "on_botonenviar_clicked" a la señal Clicked de nuestro botón y el manipulador "on_ventanaprincipal_destroy" a la señal Destroy de nuestra ventana principal.

En la propiedad Modo de Ajuste de nuestra vista de texto (mensaje), seleccionamos "Palabra", de esta forma al encontrarse que una palabra no cabe en la vista, se baja a la siguiente línea automáticamente.

Vamos a la pestaña Empaquetado de nuestras propiedades y cambiamos la propiedad Expandir de las dos entradas de texto (remitente y destino) y de la botonera por "No". De esta forma todo el espacio de la ventana es reservado para nuestro mensaje, y los demás elementos sólo reciben el espacio necesario para ser visibles:

Guardamos el archivo como "Interfaz.xml".

Abrimos Geany (o cualquier otro IDE o editor de texto) y empezamos a escribir el programa. Primero importamos los módulos necesarios:

import smtplib
import pygtk
import gtk


Creamos la clase "enviaremail" y su constructor:

class enviaremail:
def __init__(self):

builder = gtk.Builder()
builder.add_from_file("interfaz.xml")

self.ventanaprincipal = builder.get_object("ventanaprincipal")
self.mensaje = builder.get_object("mensaje").get_buffer()
self.remitente = builder.get_object("remitente")
self.destino = builder.get_object("destino")
self.botonenviar = builder.get_object("botonenviar")

builder.connect_signals(self)

self.ventanaprincipal.show()


Lo acabamos de hacer fue simplemente crear el objeto "builder" y cargar los elementos que creamos desde el archivo "interfaz.xml". Luego autoconectar todas las señales y mostrar la ventana principal.

Ahora programamos el manipulador para la señal Clicked de nuestro botón (cuando se lo presiona):

def on_botonenviar_clicked(self, widget, data=None):
DE = self.remitente.get_text()
PARA = [self.destino.get_text()]

inicio, fin = self.mensaje.get_bounds()

texto = """
%s
""" % self.mensaje.get_text(inicio, fin)

server = smtplib.SMTP("smtp.gmail.com:587")
server.starttls()
server.login("nombredeusuario", "contraseña")
server.sendmail(DE, PARA, texto)
server.quit()


Como se puede ver, el código es el mismo del primer ejemplo, con algunas diferencias: ahora el destino y el remitente son el contenido de las entradas de texto destino y remitente, respectivamente.
Para el texto del mensaje en sí, la cosa es un poco más complicada. La forma de leer el texto de una vista de texto es estableciendo unas marcas en el inicio y el final del mismo, con la funcion get_bounds(). Éstas marcas se guardan en las variables inicio y fin, que luego se pasan a la función get_text() para conseguir el texto de la vista.

Para terminar creamos el manipulador para la señal Destroy de la ventana principal e iniciamos el programa:

def on_ventanaprincipal_destroy(self, widget, data=None):
gtk.main_quit()

enviaremail()
gtk.main()


Guardamos el archivo como "enviaremail.py" y lo ejecutamos:

8 comentarios: (+add yours?)

chuche dijo...

Muchas gracias por el tutorial, una pregunta a la hora de ejecutarlo me marca un error en def __init__(self), me dice que def no es una sintaxis correcta

ito123456789 dijo...

podes copiar aca el error completo?

chuche dijo...
Este comentario ha sido eliminado por el autor.
chuche dijo...

Ya lo pude arreglar nada mas hacia falta poner los dos puntos al final de def __init__ (sefl): y poner sus respectivas sangrías, pero no me abre la ventana a la hora de ejecutarlo, nada mas me muestra que no hay errores.

Al parecer no me ejecuta la interfaz :S

http://i35.photobucket.com/albums/d166/-jesus-rodriguez/Seleccin_001.png

ito123456789 dijo...

No veo que pudiste hacer mal.. podrias poner aca el codigo completo para ver.

chuche dijo...

Ya ve que era jeje, no puse bien unas lineas, ya todo esta bien, gracias :D

gec dijo...

buenas amig@, sera que podemos hacer un chat entre tu y yo para que me podes explicar un poco mas esto??? grax si puedes dime y vuelvo a comentar dejandote mi correo.

Anónimo dijo...

buen tema pero para complementarlo seria excelente que explicara con se adjunta archivos

Publicar un comentario