-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfetch_emails_app.py
More file actions
130 lines (106 loc) · 4.95 KB
/
fetch_emails_app.py
File metadata and controls
130 lines (106 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from flask import Flask, jsonify, request
import os
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 google.auth.exceptions import RefreshError
import logging
app = Flask(__name__)
# Set up logging
logging.basicConfig(level=logging.INFO)
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly', 'https://www.googleapis.com/auth/gmail.modify']
DEVELOPMENT = os.getenv('DEVELOPMENT', 'True').lower() == 'true'
def load_credentials_from_env():
"""Load and decode credentials from environment variables if in production."""
if not DEVELOPMENT:
credentials_base64 = os.getenv('CREDENTIALS_JSON_BASE64')
token_base64 = os.getenv('TOKEN_JSON_BASE64')
if not credentials_base64 or not token_base64:
logging.error("Environment variables for credentials are missing.")
return False
with open('credentials.json', 'wb') as f:
f.write(base64.b64decode(credentials_base64))
with open('token.json', 'wb') as f:
f.write(base64.b64decode(token_base64))
return True
def update_token_in_env(token_json):
"""Update the environment variable with the refreshed token."""
if not DEVELOPMENT:
token_base64 = base64.b64encode(token_json.encode('utf-8')).decode('utf-8')
os.system(f"heroku config:set TOKEN_JSON_BASE64={token_base64}")
def authenticate_gmail():
"""Authenticate and refresh Gmail API credentials."""
creds = None
load_credentials_from_env()
# Attempt to load credentials from token.json
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# If credentials are invalid or missing, refresh them or reauthenticate
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
try:
creds.refresh(Request())
# Save the refreshed token to token.json
with open('token.json', 'w') as token_file:
token_file.write(creds.to_json())
# Update the environment variable with the refreshed token
update_token_in_env(creds.to_json())
except RefreshError as e:
logging.error("Refresh token is invalid or revoked. Manual reauthentication required.")
else:
# Manual authentication flow (only run once if needed)
flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
flow.access_type = 'offline'
creds = flow.run_local_server(port=0)
with open('token.json', 'w') as token_file:
token_file.write(creds.to_json())
update_token_in_env(creds.to_json())
return build('gmail', 'v1', credentials=creds)
@app.route('/fetch-emails', methods=['GET'])
def fetch_emails():
"""Fetch emails based on the specified query."""
service = authenticate_gmail()
if service is None:
return jsonify({"error": "Failed to authenticate Gmail service."}), 500
if request.args.get('query'):
query = request.args.get('query')
else:
query = 'is:unread'
results = service.users().messages().list(userId='me', q=query).execute()
messages = results.get('messages', [])
email_data = []
for message in messages:
msg = service.users().messages().get(userId='me', id=message['id'], format='full').execute()
payload = msg['payload']
headers = payload.get('headers', [])
subject = next((header['value'] for header in headers if header['name'] == 'Subject'), 'No Subject')
message_id = next((header['value'] for header in headers if header['name'] == 'Message-ID'), 'No Message-ID')
sender = next((header['value'] for header in headers if header['name'] == 'From'), 'Unknown Sender')
date = next((header['value'] for header in headers if header['name'] == 'Date'), 'No Date')
body = ''
if 'parts' in payload:
for part in payload['parts']:
if part['mimeType'] == 'text/plain' and 'data' in part['body']:
body = base64.urlsafe_b64decode(part['body']['data']).decode('utf-8')
else:
if 'data' in payload['body']:
body = base64.urlsafe_b64decode(payload['body']['data']).decode('utf-8')
email_data.append({
'subject': subject,
'body': body,
'message_id': message_id,
'sender': sender,
'date': date
})
for message in messages:
service.users().messages().modify(
userId='me',
id=message['id'],
body={'removeLabelIds': ['UNREAD']}
).execute()
print(jsonify(email_data))
return jsonify(email_data)
if __name__ == '__main__':
app.run(port=5002, debug=True)