from google.oauth2 import service_account from googleapiclient.discovery import build import os import sys import json import base64 from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email import encoders global base_dir, libs_dir, SCOPES, CREDENTIALS_PATH, TOKEN_PATH, _load_json, get_drive_and_gmail_services, get_doc_name, export_doc_as_pdf, create_message_with_attachment, send_email, drive_service, gmail_service, DOC_ID, doc_name, TO_EMAIL, SUBJECT, BODY_TEXT, to_emails, pdf_filename, pdf_data, result, Request # ===== Rocketbot-compatible py_libs path ===== base_dir = os.path.dirname(sys.executable) if getattr( sys, 'frozen', False) else os.getcwd() libs_dir = os.path.join(base_dir, 'librerias', 'py_libs', 'py310') if os.path.isdir(libs_dir) and libs_dir not in sys.path: sys.path.insert(0, libs_dir) SCOPES = {scopes_api_google} CREDENTIALS_PATH = '{gdoc_sa_json2}' IMPERSONATED_USER = '{gdoc_impersonated_user}' def _load_json(path): with open(path, 'r', encoding='utf-8') as f: return json.load(f) def get_drive_and_gmail_services(credentials_json_path=CREDENTIALS_PATH, impersonated_user=IMPERSONATED_USER): info = _load_json(credentials_json_path) if not isinstance(info, dict) or info.get('type') != 'service_account': raise RuntimeError('gdoc_sa_json2 debe apuntar a un JSON de cuenta de servicio.') impersonated_user = (impersonated_user or '').strip() if not impersonated_user: raise RuntimeError('Falta la variable gdoc_impersonated_user.') creds = service_account.Credentials.from_service_account_file( credentials_json_path, scopes=SCOPES, subject=impersonated_user) drive_service = build( 'drive', 'v3', credentials=creds, cache_discovery=False) gmail_service = build( 'gmail', 'v1', credentials=creds, cache_discovery=False) return drive_service, gmail_service def get_doc_name(drive_service, doc_id): """Obtiene el nombre del documento de Google Drive""" file_metadata = drive_service.files().get( fileId=doc_id, fields='name' ).execute() return file_metadata.get('name', 'documento') def export_doc_as_pdf(drive_service, doc_id): request = drive_service.files().export_media( fileId=doc_id, mimeType='application/pdf') return request.execute() def create_message_with_attachment(to_emails, subject, body_text, attachment_bytes, attachment_filename='documento.pdf'): if isinstance(to_emails, (list, tuple)): to_header = ', '.join(to_emails) recipients = to_emails else: to_header = str(to_emails) recipients = [to_header] message = MIMEMultipart() message['to'] = to_header message['subject'] = subject message.attach(MIMEText(body_text, 'plain')) part = MIMEBase('application', 'pdf') part.set_payload(attachment_bytes) encoders.encode_base64(part) part.add_header('Content-Disposition', f'attachment; filename="{attachment_filename}"') message.attach(part) raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode() return {'raw': raw_message} def send_email(gmail_service, to_emails, subject, body_text, attachment_bytes, attachment_filename='documento.pdf'): message_body = create_message_with_attachment( to_emails, subject, body_text, attachment_bytes, attachment_filename) return gmail_service.users().messages().send(userId='me', body=message_body).execute() drive_service, gmail_service = get_drive_and_gmail_services( CREDENTIALS_PATH, IMPERSONATED_USER) # Id del documento de Google Drive a enviar por email DOC_ID = '{gdoc_id}' print(DOC_ID) # Obtener nombre del documento de Google doc_name = get_doc_name(drive_service, DOC_ID) print(doc_name) # Configuración del email TO_EMAIL = '{email_copia_envio_contrato_finalizado}' SUBJECT = doc_name # --> ZUBA 27 - 306 - ROQUE SANTACRUZ BODY_TEXT = """{email_mensaje}""" print(TO_EMAIL) print(SUBJECT) print(BODY_TEXT) # Permite múltiple destinatarios separados por coma to_emails = [email.strip() for email in TO_EMAIL.split(',') if email.strip()] if not to_emails: raise ValueError( 'Debe especificar al menos un destinatario en TO_EMAIL') if not os.path.exists(CREDENTIALS_PATH): raise FileNotFoundError( f'No existe el archivo de credenciales: {CREDENTIALS_PATH}') pdf_filename = f"{doc_name}.pdf" pdf_data = export_doc_as_pdf(drive_service, DOC_ID) result = send_email(gmail_service, to_emails, SUBJECT, BODY_TEXT, pdf_data, pdf_filename) print('Mensaje enviado. ID:', result.get('id')) SetVar('res_envio', True)