Multi-account Google support with user labels

This commit is contained in:
daniel
2026-05-09 11:21:37 -05:00
parent 01b258579b
commit 38d828ef74
4 changed files with 239 additions and 141 deletions

View File

@@ -94,8 +94,8 @@ def write_workspace_file(path: str, content: str) -> str:
@tool
def connect_google_account() -> str:
"""Generate a Google OAuth authorization URL for the current user to connect their Google account.
def connect_google_account(label: str = 'primary') -> str:
"""Connect a Google account with a custom label (e.g. 'work', 'personal'). Defaults to 'primary'.
Use this when the user wants to connect Google Workspace (Gmail, Calendar, Drive, etc.)
or when Google tools fail due to missing credentials."""
if not OAUTH_START_URL:
@@ -103,8 +103,18 @@ def connect_google_account() -> str:
actor_id = _current_actor_id
if not actor_id:
return 'Cannot determine actor_id for OAuth flow.'
url = f'{OAUTH_START_URL}?actor_id={actor_id}'
return f'Please open this URL to connect your Google account:\n{url}\n\nAfter authorizing, Google Workspace tools (Gmail, Calendar, Drive) will be available.'
url = f'{OAUTH_START_URL}?actor_id={actor_id}&label={label}'
return f'Please open this URL to connect your Google account as "{label}":\n{url}\n\nAfter authorizing, Google Workspace tools (Gmail, Calendar, Drive) will be available.'
@tool
def list_google_accounts() -> str:
"""List all connected Google accounts and their labels."""
accounts = _gws._current_google_accounts
if not accounts:
return 'No Google accounts connected. Use connect_google_account to add one.'
parts = [f'{label} ({email})' for label, email in accounts.items()]
return 'Connected Google accounts: ' + ', '.join(parts)
@tool
@@ -145,11 +155,9 @@ def manage_service(action: str, service: str, config: dict | None = None) -> str
return 'service name is required.'
if not config:
return 'config dict is required for enroll.'
# Validate known services
if service == 'home_assistant':
if 'url' not in config or 'token' not in config:
return 'home_assistant config requires "url" and "token" keys.'
# Update in-memory config immediately for this session
set_ha_config(config['url'], config['token'])
table.update_item(
Key={'actor_id': actor_id},
@@ -245,17 +253,21 @@ async def main(payload: dict, context):
ha_cfg = services.get('home_assistant', {})
set_ha_config(ha_cfg.get('url', ''), ha_cfg.get('token', ''))
# Sync google_accounts to google_workspace module
google_accounts = user_profile.get('google_accounts', {})
_gws._current_google_accounts = google_accounts
# Build system prompt — base cached, user context injected per-invocation
user_context = ''
if user_profile:
name = user_profile.get('display_name', '')
username = user_profile.get('telegram_username', '')
google_email = user_profile.get('google_email', '')
user_context = f'Name: {name}'
if username:
user_context += f'\nTelegram username: @{username}'
if google_email:
user_context += f'\nGoogle account: {google_email}'
if google_accounts:
acct_list = ', '.join(f'{label} ({email})' for label, email in google_accounts.items())
user_context += f'\nGoogle accounts: {acct_list}'
else:
user_context += '\nGoogle account: not connected (use connect_google_account tool to connect)'
enrolled = list(services.keys())
@@ -282,7 +294,7 @@ async def main(payload: dict, context):
)
base_tools = [web_search, web_fetch, read_workspace_file, write_workspace_file,
home_assistant, connect_google_account,
home_assistant, connect_google_account, list_google_accounts,
manage_service, schedule_reminder, list_reminders, cancel_reminder,
list_calendars, get_calendar_events, list_gmail_messages, get_gmail_message]