import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from email.mime.image import MIMEImage from email import encoders import os import pandas as pd from datetime import datetime from tqdm import tqdm def determinar_periodo(): hora_actual = datetime.now().hour if 6 <= hora_actual < 12: return "Buen día" elif 12 <= hora_actual < 18: return "Buena tarde" elif 18 <= hora_actual < 24: return "Buena noche" else: return "Madrugada" def build_message(saludo_hora, destinatarios, file_path, email_usuario, oficio_numero): msg = MIMEMultipart("related") msg["From"] = email_usuario msg["To"] = ", ".join(destinatarios) msg["Subject"] = f"Respuesta a solicitud de conectividad, oficio número: {oficio_numero}" # Abre y lee la imagen del logo with open("./img_cfe/logo.png", "rb") as fp: logo_img = MIMEImage(fp.read(), "svg+xml") # Tipo de imagen para SVG # 📌 Asigna un ID único y un nombre de archivo logo_img.add_header("Content-ID", "") logo_img.add_header("Content-Disposition", "inline", filename="logo.png") msg.attach(logo_img) # 📝 Código HTML para el cuerpo del correo cuerpo_html = f""" Respuesta a solicitud de conectividad
""" # 📌 Cambia 'plain' a 'html' para el tipo de contenido msg.attach(MIMEText(cuerpo_html, "html")) if os.path.exists(file_path): with open(file_path, "rb") as adj: parte = MIMEBase("application", "octet-stream") parte.set_payload(adj.read()) encoders.encode_base64(parte) parte.add_header("Content-Disposition", f"attachment; filename={os.path.basename(file_path)}") msg.attach(parte) else: print(f"⚠️ Archivo no encontrado: {file_path}, se envía sin adjunto.") return msg def main(): email_usuario = "david.itehua@aem.gob.mx" app_password = "lcdq hwvq wxxa pbcn" smtp_server = "smtp.gmail.com" smtp_port = 465 # Carga de Excel file_xlsx = "./Control Oficios Conectividad 2025 .xlsx" # df = pd.read_excel(file_xlsx)[["No", "FECHA DE RECEPCION", "REMITENTE", "ASUNTO", "CORREO ELECTRÓNICO", "Oficio_no", "documento"]] df = pd.read_excel(file_xlsx, dtype={'Oficio_no': str})[["No", "FECHA DE RECEPCION", "REMITENTE", "ASUNTO", "CORREO ELECTRÓNICO", "Oficio_no", "documento"]] saludo = determinar_periodo() # Abrir UNA sola conexión with smtplib.SMTP_SSL(smtp_server, smtp_port) as server: server.login(email_usuario, app_password) for _, row in tqdm(df.iterrows(), total=len(df), desc="Enviando correos"): emails_raw = str(row["CORREO ELECTRÓNICO"]) destinatarios = [e.strip() for e in emails_raw.replace(";", ",").split(",") if e.strip()] file_to_send = f'./Docs/{row["documento"]}' oficio_numero = row["Oficio_no"] msg = build_message(saludo, destinatarios, file_to_send, email_usuario, oficio_numero) try: server.send_message(msg, from_addr=email_usuario, to_addrs=destinatarios) except Exception as e: print(f"❌ Error enviando a {destinatarios}: {e}") if __name__ == "__main__": main()