Files
scripts_zubabot/envio_contrato_docs_email.py

159 lines
5.5 KiB
Python

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)