From f98338ad48639b8fe10986a518af1733d92741a1 Mon Sep 17 00:00:00 2001 From: Dulce Figueredo Date: Thu, 23 Apr 2026 10:50:12 -0300 Subject: [PATCH] agrego script que envia los contratos generados por correo a los de comercial --- envio_contrato_docs_email.py | 159 +++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 envio_contrato_docs_email.py diff --git a/envio_contrato_docs_email.py b/envio_contrato_docs_email.py new file mode 100644 index 0000000..6265cff --- /dev/null +++ b/envio_contrato_docs_email.py @@ -0,0 +1,159 @@ + +from google.auth.transport.requests import Request +from google_auth_oauthlib.flow import InstalledAppFlow +from google.oauth2.credentials import Credentials +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_json}' +TOKEN_PATH = '{gmail_token_json}' + + +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, token_json_path=TOKEN_PATH): + info = _load_json(credentials_json_path) + + # Service account + if isinstance(info, dict) and info.get('type') == 'service_account': + creds = service_account.Credentials.from_service_account_file( + credentials_json_path, scopes=SCOPES) + 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 + + # OAuth flow + creds = None + if os.path.exists(token_json_path): + creds = Credentials.from_authorized_user_file(token_json_path, SCOPES) + + if not creds or not creds.valid: + if creds and creds.expired and creds.refresh_token: + creds.refresh(Request()) + else: + flow = InstalledAppFlow.from_client_secrets_file( + credentials_json_path, SCOPES) + try: + creds = flow.run_local_server(port=0) + except Exception: + creds = flow.run_console() + + os.makedirs(os.path.dirname(token_json_path), exist_ok=True) + with open(token_json_path, 'w', encoding='utf-8') as f: + f.write(creds.to_json()) + + 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, TOKEN_PATH) + +# 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) \ No newline at end of file