/ src / google_services.py
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()