11from fastapi import APIRouter , HTTPException
22from app .utils .toolkit .notion_mcp_toolkit import NotionMCPToolkit
33from app .utils .toolkit .google_calendar_toolkit import GoogleCalendarToolkit
4+ from app .utils .toolkit .google_gmail_toolkit import GoogleGmailToolkit
45from app .utils .oauth_state_manager import oauth_state_manager
56from utils import traceroot_wrapper as traceroot
67from camel .toolkits .hybrid_browser_toolkit .hybrid_browser_toolkit_ts import (
@@ -104,10 +105,46 @@ async def install_tool(tool: str):
104105 status_code = 500 ,
105106 detail = f"Failed to install { tool } : { str (e )} "
106107 )
108+ elif tool == "google_gmail" :
109+ try :
110+ # Try to initialize toolkit - will succeed if credentials exist
111+ try :
112+ toolkit = GoogleGmailToolkit ("install_auth" )
113+ tools = [tool_func .func .__name__ for tool_func in toolkit .get_tools ()]
114+ logger .info (f"Successfully initialized Gmail toolkit with { len (tools )} tools" )
115+
116+ return {
117+ "success" : True ,
118+ "tools" : tools ,
119+ "message" : f"Successfully installed { tool } toolkit" ,
120+ "count" : len (tools ),
121+ "toolkit_name" : "GoogleGmailToolkit"
122+ }
123+ except ValueError as auth_error :
124+ # No credentials - need authorization
125+ logger .info (f"No credentials found, starting authorization: { auth_error } " )
126+
127+ # Start background authorization in a new thread
128+ logger .info ("Starting background Gmail authorization" )
129+ GoogleGmailToolkit .start_background_auth ("install_auth" )
130+
131+ return {
132+ "success" : False ,
133+ "status" : "authorizing" ,
134+ "message" : "Authorization required. Browser should open automatically. Complete authorization and try installing again." ,
135+ "toolkit_name" : "GoogleGmailToolkit" ,
136+ "requires_auth" : True
137+ }
138+ except Exception as e :
139+ logger .error (f"Failed to install { tool } toolkit: { e } " )
140+ raise HTTPException (
141+ status_code = 500 ,
142+ detail = f"Failed to install { tool } : { str (e )} "
143+ )
107144 else :
108145 raise HTTPException (
109146 status_code = 404 ,
110- detail = f"Tool '{ tool } ' not found. Available tools: ['notion', 'google_calendar']"
147+ detail = f"Tool '{ tool } ' not found. Available tools: ['notion', 'google_calendar', 'google_gmail' ]"
111148 )
112149
113150
@@ -134,6 +171,13 @@ async def list_available_tools():
134171 "description" : "Google Calendar integration for managing events and schedules" ,
135172 "toolkit_class" : "GoogleCalendarToolkit" ,
136173 "requires_auth" : True
174+ },
175+ {
176+ "name" : "google_gmail" ,
177+ "display_name" : "Gmail" ,
178+ "description" : "Gmail integration for managing emails, drafts, labels, contacts, and more" ,
179+ "toolkit_class" : "GoogleGmailToolkit" ,
180+ "requires_auth" : True
137181 }
138182 ]
139183 }
@@ -287,10 +331,40 @@ async def uninstall_tool(tool: str):
287331 status_code = 500 ,
288332 detail = f"Failed to uninstall { tool } : { str (e )} "
289333 )
334+
335+ elif tool == "google_gmail" :
336+ try :
337+ # Clean up Gmail token directory
338+ token_dir = os .path .join (os .path .expanduser ("~" ), ".eigent" , "tokens" , "gmail" )
339+ if os .path .exists (token_dir ):
340+ shutil .rmtree (token_dir )
341+ logger .info (f"Removed Gmail token directory: { token_dir } " )
342+
343+ # Clear OAuth state manager cache
344+ # This removes the cached credentials from memory
345+ state = oauth_state_manager .get_state ("google_gmail" )
346+ if state :
347+ if state .status in ["pending" , "authorizing" ]:
348+ state .cancel ()
349+ logger .info ("Cancelled ongoing Gmail authorization" )
350+ # Clear the state completely to remove cached credentials
351+ oauth_state_manager ._states .pop ("google_gmail" , None )
352+ logger .info ("Cleared Gmail OAuth state cache" )
353+
354+ return {
355+ "success" : True ,
356+ "message" : f"Successfully uninstalled { tool } and cleaned up authentication tokens"
357+ }
358+ except Exception as e :
359+ logger .error (f"Failed to uninstall { tool } : { e } " )
360+ raise HTTPException (
361+ status_code = 500 ,
362+ detail = f"Failed to uninstall { tool } : { str (e )} "
363+ )
290364 else :
291365 raise HTTPException (
292366 status_code = 404 ,
293- detail = f"Tool '{ tool } ' not found. Available tools: ['notion', 'google_calendar']"
367+ detail = f"Tool '{ tool } ' not found. Available tools: ['notion', 'google_calendar', 'google_gmail' ]"
294368 )
295369
296370
0 commit comments