gavinzli commited on
Commit
1cd6322
·
1 Parent(s): 216bd87

Implement email retrieval functionality and enhance authentication flow in the API

Browse files
Files changed (3) hide show
  1. app/controllers/mail.py +73 -6
  2. app/router/auth.py +13 -19
  3. app/router/mail.py +29 -13
app/controllers/mail.py CHANGED
@@ -1,20 +1,19 @@
1
  """Module to search and list emails from Gmail."""
2
- import os
3
- import re
4
  import base64
5
  import hashlib
 
 
6
  from datetime import datetime, timedelta
7
  from venv import logger
8
- from ics import Calendar
9
 
10
- from langchain_core.documents import Document
11
  from langchain_community.document_loaders import (
 
12
  PyPDFLoader,
13
  UnstructuredExcelLoader,
14
- CSVLoader,
15
  UnstructuredImageLoader,
16
  )
17
-
18
  from models.db import vectorstore
19
 
20
  SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]
@@ -230,3 +229,71 @@ def collect(service, query=(datetime.today() - timedelta(days=10)).strftime("aft
230
  return f"{len(emails)} emails added to the collection."
231
  else:
232
  logger.info("No emails found after two weeks ago.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  """Module to search and list emails from Gmail."""
 
 
2
  import base64
3
  import hashlib
4
+ import os
5
+ import re
6
  from datetime import datetime, timedelta
7
  from venv import logger
 
8
 
9
+ from ics import Calendar
10
  from langchain_community.document_loaders import (
11
+ CSVLoader,
12
  PyPDFLoader,
13
  UnstructuredExcelLoader,
 
14
  UnstructuredImageLoader,
15
  )
16
+ from langchain_core.documents import Document
17
  from models.db import vectorstore
18
 
19
  SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]
 
229
  return f"{len(emails)} emails added to the collection."
230
  else:
231
  logger.info("No emails found after two weeks ago.")
232
+
233
+
234
+ def get_emails(service, query=(datetime.today() - timedelta(days=10)).strftime("after:%Y/%m/%d"), max_results=10):
235
+ """
236
+ Retrieve a list of emails with subject, to, from, cc, and content.
237
+
238
+ Args:
239
+ mailservice: Authenticated Gmail API service instance
240
+ max_results: Maximum number of emails to retrieve
241
+
242
+ Returns:
243
+ List of dictionaries containing email details
244
+ """
245
+ try:
246
+ # List messages
247
+ response = service.users().messages().list(userId='me', q=query, maxResults=max_results).execute()
248
+ messages = response.get('messages', [])
249
+ email_list = []
250
+
251
+ if not messages:
252
+ return email_list
253
+
254
+ for message in messages:
255
+ # Get detailed message data
256
+ msg = service.users().messages().get(userId='me', id=message['id'], format='full').execute()
257
+ headers = msg['payload']['headers']
258
+
259
+ # Initialize email details
260
+ email_data = {
261
+ 'subject': '',
262
+ 'from': '',
263
+ 'to': '',
264
+ 'cc': '',
265
+ 'content': '',
266
+ 'snippet': msg['snippet'] if 'snippet' in msg else '',
267
+ }
268
+
269
+ # Extract headers
270
+ for header in headers:
271
+ name = header['name'].lower()
272
+ if name == 'subject':
273
+ email_data['subject'] = header['value']
274
+ elif name == 'from':
275
+ email_data['from'] = header['value']
276
+ elif name == 'to':
277
+ email_data['to'] = header['value']
278
+ elif name == 'cc':
279
+ email_data['cc'] = header['value']
280
+
281
+ # Extract content
282
+ if 'parts' in msg['payload']:
283
+ for part in msg['payload']['parts']:
284
+ if part['mimeType'] == 'text/plain':
285
+ email_data['content'] = base64.urlsafe_b64decode(part['body']['data']).decode('utf-8')
286
+ break
287
+ elif part['mimeType'] == 'text/html':
288
+ email_data['content'] = base64.urlsafe_b64decode(part['body']['data']).decode('utf-8')
289
+ break
290
+ elif 'data' in msg['payload']['body']:
291
+ email_data['content'] = base64.urlsafe_b64decode(msg['payload']['body']['data']).decode('utf-8')
292
+
293
+ email_list.append(email_data)
294
+
295
+ return email_list
296
+
297
+ except Exception as e:
298
+ print(f"An error occurred: {e}")
299
+ return []
app/router/auth.py CHANGED
@@ -2,10 +2,10 @@
2
  import os
3
  import json
4
  import pickle
5
- from cv2 import log
6
  from fastapi import APIRouter, Request
7
  from fastapi.responses import JSONResponse
8
  from google_auth_oauthlib.flow import InstalledAppFlow
 
9
  from googleapiclient.discovery import build
10
 
11
  router = APIRouter(tags=["auth"])
@@ -74,25 +74,19 @@ async def google_callback(state: str, code: str, scope: str, request: Request):
74
  flow.redirect_uri = REDIRECT_URI
75
  flow.fetch_token(code=code)
76
  credentials = flow.credentials
 
77
  request.state.session["credential"] = json.loads(credentials.to_json())
78
- # cred_dict = (request.state.session.get("credential"))
79
- # cred = Credentials(
80
- # token=cred_dict["token"],
81
- # refresh_token=cred_dict["refresh_token"],
82
- # token_uri=cred_dict["token_uri"],
83
- # client_id=cred_dict["client_id"],
84
- # client_secret=cred_dict["client_secret"],
85
- # scopes=cred_dict["scopes"],
86
- # )
87
- # service = build("gmail", "v1", credentials=Credentials(
88
- # token=cred_dict["token"],
89
- # refresh_token=cred_dict["refresh_token"],
90
- # token_uri=cred_dict["token_uri"],
91
- # client_id=cred_dict["client_id"],
92
- # client_secret=cred_dict["client_secret"],
93
- # scopes=cred_dict["scopes"],
94
- # ))
95
- service = build("gmail", "v1", credentials=credentials)
96
  profile = service.users().getProfile(userId="me").execute()
97
  with open(f"cache/{profile['emailAddress']}.pickle", "wb") as token:
98
  pickle.dump(credentials, token)
 
2
  import os
3
  import json
4
  import pickle
 
5
  from fastapi import APIRouter, Request
6
  from fastapi.responses import JSONResponse
7
  from google_auth_oauthlib.flow import InstalledAppFlow
8
+ from google.oauth2.credentials import Credentials
9
  from googleapiclient.discovery import build
10
 
11
  router = APIRouter(tags=["auth"])
 
74
  flow.redirect_uri = REDIRECT_URI
75
  flow.fetch_token(code=code)
76
  credentials = flow.credentials
77
+ print(credentials.to_json())
78
  request.state.session["credential"] = json.loads(credentials.to_json())
79
+ cred_dict = (request.state.session.get("credential"))
80
+ service = build("gmail", "v1", credentials=Credentials(
81
+ token=cred_dict["token"],
82
+ # refresh_token=cred_dict["refresh_token"],
83
+ # token_uri=cred_dict["token_uri"],
84
+ # client_id=cred_dict["client_id"],
85
+ # client_secret=cred_dict["client_secret"],
86
+ # scopes=cred_dict["scopes"],
87
+ ))
88
+ print(service)
89
+ # service = build("gmail", "v1", credentials=credentials)
 
 
 
 
 
 
 
90
  profile = service.users().getProfile(userId="me").execute()
91
  with open(f"cache/{profile['emailAddress']}.pickle", "wb") as token:
92
  pickle.dump(credentials, token)
app/router/mail.py CHANGED
@@ -46,16 +46,32 @@ def collect(query: MailReqData, request: Request):
46
  logger.error("Error collecting mail: %s", e)
47
  return JSONResponse(content={"error": str(e)}, status_code=500)
48
 
49
- # @router.get("")
50
- # def get():
51
- # """
52
- # Handles the chat POST request.
53
-
54
- # Args:
55
- # query (ReqData): The request data containing the query parameters.
56
-
57
- # Returns:
58
- # str: The generated response from the chat function.
59
- # """
60
- # # result = mail.get()
61
- # return JSONResponse(content= result)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  logger.error("Error collecting mail: %s", e)
47
  return JSONResponse(content={"error": str(e)}, status_code=500)
48
 
49
+ @router.get("")
50
+ def get(query: MailReqData, request: Request):
51
+ """
52
+ Handles the chat POST request.
53
+
54
+ Args:
55
+ query (ReqData): The request data containing the query parameters.
56
+
57
+ Returns:
58
+ str: The generated response from the chat function.
59
+ """
60
+ if os.path.exists(f"cache/{query.email}.pickle"):
61
+ with open(f"cache/{query.email}.pickle", "rb") as token:
62
+ credentials = pickle.load(token)
63
+ else:
64
+ cred_dict = request.state.session.get("credential")
65
+ credentials = Credentials(
66
+ token=cred_dict["token"],
67
+ refresh_token=cred_dict["refresh_token"],
68
+ token_uri=cred_dict["token_uri"],
69
+ client_id=cred_dict["client_id"],
70
+ client_secret=cred_dict["client_secret"],
71
+ scopes=cred_dict["scopes"],
72
+ )
73
+ mailservice = build("gmail", "v1", credentials=credentials)
74
+ print("query: ", query.query)
75
+ result = mail.get_emails(mailservice, query.query)
76
+ print(result)
77
+ return JSONResponse(content= result)