google_services.py
1 # ============================================================================ 2 # GOOGLE SERVICES 3 # ============================================================================ 4 5 from google.oauth2.service_account import Credentials 6 from googleapiclient.discovery import build 7 from googleapiclient.http import MediaIoBaseDownload, MediaFileUpload 8 import io 9 from googleapiclient.http import MediaIoBaseUpload 10 import base64 11 from email.mime.multipart import MIMEMultipart 12 from email.mime.text import MIMEText 13 from src.config import Config 14 15 def create_message(to: str, subject: str, html_content: str): 16 message = MIMEMultipart("alternative") 17 18 # IMPORTANT: From must match impersonated account 19 message["From"] = "hr@yourcompany.com" 20 message["To"] = to 21 message["Subject"] = subject 22 23 message.attach(MIMEText(html_content, "html")) 24 25 raw_message = base64.urlsafe_b64encode( 26 message.as_bytes() 27 ).decode("utf-8") 28 29 return { 30 "raw": raw_message 31 } 32 33 34 class GoogleServices: 35 """Handle Google Drive and Sheets operations""" 36 37 ## Google Service Account Required 38 def __init__(self): 39 scopes = [ 40 "https://www.googleapis.com/auth/drive", 41 "https://www.googleapis.com/auth/spreadsheets" 42 "https://www.googleapis.com/auth/gmail.send" 43 ] 44 45 self.creds = Credentials.from_service_account_file( 46 Config.GOOGLE_CREDENTIALS_PATH, 47 scopes=scopes 48 ) 49 50 self.drive_service = build("drive", "v3", credentials=self.creds) 51 self.sheets_service = build("sheets", "v4", credentials=self.creds) 52 self.gmail_service = build("gmail", "v1", credentials=self.creds) 53 54 def download_file(self, file_url: str) -> bytes: 55 """Download file from Google Drive""" 56 # Extract file ID from URL 57 file_id = file_url.split('/d/')[1].split('/')[0] if '/d/' in file_url else file_url 58 59 request = self.drive_service.files().get_media(fileId=file_id) 60 file_buffer = io.BytesIO() 61 downloader = MediaIoBaseDownload(file_buffer, request) 62 63 done = False 64 while not done: 65 status, done = downloader.next_chunk() 66 67 return file_buffer.getvalue() 68 69 70 def upload_file(self, file_content: bytes, filename: str, folder_id: str) -> dict: 71 """Upload file to Google Drive""" 72 file_metadata = { 73 'name': filename, 74 'parents': [folder_id] 75 } 76 77 file_bytes = io.BytesIO(file_content) 78 file_bytes.seek(0) 79 media = MediaIoBaseUpload( 80 file_bytes, 81 mimetype='application/pdf', 82 resumable=True 83 ) 84 85 file = self.drive_service.files().create( 86 body=file_metadata, 87 media_body=media, 88 fields='id,webViewLink' 89 ).execute() 90 91 return file 92 93 def append_to_sheet(self, sheet_id: str, sheet_name: str, values: list): 94 """Append row to Google Sheets""" 95 body = {'values': [values]} 96 97 self.sheets_service.spreadsheets().values().append( 98 spreadsheetId=sheet_id, 99 range=f'{sheet_name}!A:M', 100 valueInputOption='RAW', 101 body=body 102 ).execute() 103 104 105 def send_email(self, subject: str, body_html: str): 106 """Send email""" 107 self.gmail_service.users().messages().send( 108 userId="me", 109 body=create_message( 110 to="hiring.manager@yourcompany.com", 111 subject=subject, 112 html_content="<p>Candidate details here...</p>" 113 ) 114 ).execute()