GMAIL desde Python, accediendo a la bandeja de entrada

¿Quieres implementar envío y recepción de emails en tus aplicaciones?

El email es una herramienta muy potente, si bien lo habitual es utilizarlo en persona, hay muchos servicios y aplicaciones que lo utilizan de forma automática para enviar y recibir notificaciones de estado.

En esta primera entrada de gmail desde Python, vamos a ver como acceder a una cuenta GMAIL, consultar la bandeja de entrada y descargar los mensajes.

Antes de nada es necesario configurar la cuenta GMAIL para permitir el acceso a otras aplicaciones. Si ya lo has hecho puedes saltarte este paso.

El código

Vamos a trabajar con los módulos email e imaplib.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Aug 14 10:38:51 2018

@author: altaruru
"""

import imaplib
import email

def get_body(tmsg):    
    body = ""
    if tmsg.is_multipart():        
        for part in tmsg.walk():
            ctype = part.get_content_type()
            cdispo = str(part.get('Content-Disposition'))    
            # skip any text/plain (txt) attachments
            if ctype == 'text/plain' and 'attachment' not in cdispo:
                body = str(part.get_payload(decode=True))  # decode
                body=body.replace("\\r\\n","\n")                
                break
    # not multipart - i.e. plain text, no attachments, keeping fingers crossed
    else:
        body = str(tmsg.get_payload(decode=True))
    return body

def get_emailinfo(id, data, bshowbody=False):
    for contenido in data:
        # comprueba que 'contenido' sea una tupla, si es así continua
        if isinstance(contenido, tuple):                    
            # recuperamos información del email:                    
            msg = email.message_from_string(contenido[1].decode())
            # mostramos resultados:   
            print ("%d - *** %s ***" % (id, msg['subject'].upper()))
            print ("enviado por %s" % msg['from'])
            print ("para %s" % msg['to'])
            if(bshowbody):
                print ("---                                                   ---")
                print(get_body(msg))
                print ("--------------------------------------------------------")
            return True
    # si no hay info
    return False

def get_emails(gmailsmtpsvr, gmailusr, gmailpwd, bshowbody):
    try:
        # Conectamos a nuestro servidor, gmail necesita un ssl socket (encriptado) por lo que utilizamos 
        # la subclase IMAP4_SSL
        # Parámetros: host='', port=IMAP4_SSL_PORT, keyfile=None, certfile=None, ssl_context=None
        # El puerto por defecto IMAP4_SSL_PORT es el 993, en el caso de gmail lo dejamos como está, el resto de 
        # parámetros tampoco son necesarios en este caso.
        # Únicamente es necesario pasar como parámetro el servidor stmp de gmail 
        mail = imaplib.IMAP4_SSL(gmailsmtpsvr)
        # logamos:
        mail.login(gmailusr, gmailpwd)
        # seleccionamos bandeja de entrada 'inbox'
        mail.select("inbox")
        # recuperamos lista de emails, es posible filtrar la consulta
        # ALL devuelve todos los emails
        # Ejemplo de filtro: '(FROM "altaruru" SUBJECT "ejemplo python")'        
        result, data = mail.search(None, 'ALL')
        strids = data[0] # coge lista de ids encontrados
        lstids = strids.split()
        # recuperamos valores para bucle
        firstid = int(lstids[0])
        lastid = int(lstids[-1])
        countid = 0
        # mostramos datos de los ids encontrados
        print("primer id: %d\nultimo id: %d\n..." % (firstid, lastid))
        # recorremos lista de mayor a menor (mas recientes primero)
        for id in range(lastid, firstid-1, -1):            
            typ, data = mail.fetch(str(id), '(RFC822)' ) # el parámetro id esperado es tipo cadena
            if (get_emailinfo(id, data, bshowbody)):
                countid+=1
        # fin, si llegamos aqui todo es correcto
        print("emails listados %d" % countid)
    except Exception as e:
        print("Error: %s" % (e))
        return ""
    except:
        print("Error desconocido")
        return ""
  • Resumen de los pasos a seguir:
    • creamos objeto «mail«
    • conectamos al servidor mail.login
    • seleccionamos bandeja de entrada mail.select(«inbox»)
    • recuperamos lista de emails: result, data = mail.search(None, ‘ALL’)
    • recorremos cada elemento obteniendo detalle del mensaje con get_emailinfo

 

Para hacer la magia, usar la función get_emails():

def test():    
    get_emails("smtp.gmail.com", "micuenta@gmail.com", "contraseña", False);

test()

La salida será similar a…

abriendo bandeja entrada de gmail...
primer id: 1
ultimo id: 5
...
5 - *** SECURITY ALERT ***
enviado por Google <no-reply@accounts.google.com>
para micuenta@gmail.com
4 - *** HELP US PROTECT YOU: SECURITY ADVICE FROM GOOGLE ***
enviado por Google <no-reply@accounts.google.com>
para micuenta@gmail.com
3 - *** SECURITY ALERT ***
enviado por Google <no-reply@accounts.google.com>
para micuenta@gmail.com
2 - *** ACCESS FOR LESS SECURE APPS HAS BEEN TURNED ON ***
enviado por Google <no-reply@accounts.google.com>
para micuenta@gmail.com
1 - *** MICUENTA, WELCOME TO YOUR NEW GOOGLE ACCOUNT  ***
enviado por Google Community Team <googlecommunityteam-noreply@google.com>
para micuenta@gmail.com
emails listados 5

Poniendo a True el último parámetro de la función get_emails recuperamos también el cuerpo del mensaje.

get_emails("smtp.gmail.com", "micuenta@gmail.com", "contraseña", True);

En este caso, la salida es…

abriendo bandeja entrada de gmail...
primer id: 1
ultimo id: 5
...
5 - *** SECURITY ALERT ***
enviado por Google <no-reply@accounts.google.com>
para micuenta@gmail.com
---                                                   ---
b"Dan Esco

New device signed in to
micuenta@gmail.com
Your Google Account was just signed in to from a new Linux device. You're
getting this email to make sure it was you.

Check activity
<https://accounts.google.com/AccountChooser?Email=micuenta@gmail.com&continue=https://myaccount.google.com/alert/nt/1537795369000?rfn%3D31%26rfnc%3D1%26eid%3D6185417258682954020%26et%3D0%26asae%3D2%26anexp%3Dgivab-fa--hsc-control_a>
<https://accounts.google.com/AccountChooser?Email=micuenta@gmail.com&continue=https://myaccount.google.com/alert/nt/1537795369000?rfn%3D31%26rfnc%3D1%26eid%3D6185417258682954020%26et%3D0%26asae%3D2%26anexp%3Dgivab-fa--hsc-control_a>

You received this email to let you know about important changes to your
Google Account and services.
\xc2\xa9 2018 Google LLC,1600 Amphitheatre Parkway, Mountain View, CA 94043, USA
1537795369000000
"
--------------------------------------------------------
4 - *** HELP US PROTECT YOU: SECURITY ADVICE FROM GOOGLE ***
enviado por Google <no-reply@accounts.google.com>
para micuenta@gmail.com
---                                                   ---
b'Dan Esco

Turn off less secure access
micuenta@gmail.com

Your personal information is vulnerable because you allow apps & devices to
access your account in a less secure way.
Turn off this type of access and see other personalized security
recommendations in the Security Ch...
...

Eso es todo, para cualquier duda dejad vuestros comentarios y responderé encantado.

¿Quieres enviar emails? aprende como en gmail desde Python, enviando emails

Altaruru!

 

 

 

2 comentarios en “GMAIL desde Python, accediendo a la bandeja de entrada

Deja un comentario

Tu dirección de correo electrónico no será publicada.