# email_watcher.py import os import pickle import base64 from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build from config import Config SCOPES = ['https://www.googleapis.com/auth/gmail.readonly'] def get_gmail_service(): creds = None if os.path.exists(Config.GMAIL_TOKEN_FILE): with open(Config.GMAIL_TOKEN_FILE, 'rb') as token: creds = pickle.load(token) 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( Config.GMAIL_CREDENTIALS_FILE, SCOPES) creds = flow.run_local_server(port=0) with open(Config.GMAIL_TOKEN_FILE, 'wb') as token: pickle.dump(creds, token) return build('gmail', 'v1', credentials=creds) def check_for_new_fos_email(last_checked_time=None): """ Returns a list of new emails from the FOS since last_checked_time. last_checked_time should be a datetime object. """ service = get_gmail_service() query = f'from:{Config.FOS_EMAIL}' if last_checked_time: # Gmail uses after:timestamp in seconds timestamp = int(last_checked_time.timestamp()) query += f' after:{timestamp}' result = service.users().messages().list(userId='me', q=query).execute() messages = result.get('messages', []) new_emails = [] for msg in messages: msg_data = service.users().messages().get(userId='me', id=msg['id']).execute() payload = msg_data.get('payload', {}) parts = payload.get('parts', []) if not parts: # simple email body = payload.get('body', {}).get('data', '') else: # multipart body = '' for part in parts: if part.get('mimeType') == 'text/plain': body = part.get('body', {}).get('data', '') break if body: body = base64.urlsafe_b64decode(body).decode('utf-8') headers = {h['name']: h['value'] for h in msg_data['payload']['headers']} new_emails.append({ 'id': msg['id'], 'from': headers.get('From', ''), 'subject': headers.get('Subject', ''), 'date': headers.get('Date', ''), 'body': body }) return new_emails