AI-Agent / agents /google_calendar_agent.py
walkerhsu
init
c74033b
from googleapiclient.discovery import build
from datetime import datetime, timedelta
from utils.auth import authenticate_google_services
class GoogleCalendar_Agent:
def __init__(self, creds=None, timezone="Asia/Taipei"):
if not creds:
creds = authenticate_google_services()
self.service = build("calendar", "v3", credentials=creds)
self.timezone = timezone
def list_events(self, n: int=5, queries=None) -> str:
now = datetime.utcnow().isoformat() + 'Z'
events_result = self.service.events().list(
calendarId='primary',
timeMin=now,
maxResults=n,
singleEvents=True,
orderBy='startTime'
).execute()
events = events_result.get('items', [])
if not events:
return "🔕 找不到即將到來的行事曆事件。"
output = "📅 您接下來的行事曆事件如下:\n"
for event in events:
start = event['start'].get('dateTime', event['start'].get('date'))
summary = event.get('summary', 'No title')
output += f"• {summary} at {start}\n"
return output
def create_event(self,
summary: str,
start_time: str,
end_time: str,
location: str = None,
description: str = None,
attendees: list = None,
reminder_minutes: int = None) -> str:
event = {
'summary': summary,
'start': {'dateTime': start_time, 'timeZone': self.timezone},
'end': {'dateTime': end_time, 'timeZone': self.timezone}
}
if location:
event['location'] = location
if description:
event['description'] = description
if attendees:
event['attendees'] = [{'email': email} for email in attendees]
if reminder_minutes:
event['reminders'] = {
'useDefault': False,
'overrides': [{'method': 'popup', 'minutes': reminder_minutes}]
}
try:
created_event = self.service.events().insert(
calendarId='primary',
sendUpdates='all',
body=event
).execute()
return f"""✅ 已成功建立事件:\n標題 : {summary}\n開始時間 : {start_time}\n結束時間 : {end_time}\n地點 : {location or '無'}\n說明 : {description or '無'}\n參與者 : {', '.join(attendees) if attendees else '無'}\n提醒時間 : {reminder_minutes if reminder_minutes is not None else '使用預設提醒'}\n時區 : {self.timezone}\n事件連結 : {created_event.get('htmlLink')}"""
except Exception as e:
return f"❌ 建立事件失敗,以下是錯誤訊息(英文): {e}"
def find_event(self, query: str,) -> list:
now = datetime.utcnow().isoformat() + 'Z'
events_result = self.service.events().list(
calendarId='primary',
timeMin=now,
singleEvents=True,
orderBy='startTime',
q=query
).execute()
return events_result.get('items', [])
def update_event(self, query: str,
new_summary=None,
new_location=None,
new_description=None,
new_start=None,
new_end=None,
new_attendees=None,
reminder_minutes=None):
events = self.find_event(query)
if not events:
return f"❌ 找不到包含「{query}」的事件"
if all(arg is None for arg in [
new_summary, new_location, new_description,
new_start, new_end, new_attendees, reminder_minutes
]):
return f"⚠️ 沒有指定任何要更新的欄位,未執行更新。"
for event in events:
event_id = event['id']
try:
if new_summary:
event['summary'] = new_summary
if new_location:
event['location'] = new_location
if new_description:
event['description'] = new_description
if new_attendees:
event['attendees'] = [{'email': email} for email in new_attendees]
if reminder_minutes:
event['reminders'] = {
'useDefault': False,
'overrides': [{'method': 'popup', 'minutes': reminder_minutes}]
}
if new_start or new_end:
event['start']['dateTime'] = new_start
event['end']['dateTime'] = new_end
event['start']['timeZone'] = 'Asia/Taipei'
event['end']['timeZone'] = 'Asia/Taipei'
updated_event = self.service.events().update(
calendarId='primary',
eventId=event_id,
sendUpdates='all',
body=event
).execute()
return f"✅ 已成功更新事件:{updated_event['summary']}"
except Exception as e:
return f"❌ 更新事件失敗,以下是錯誤訊息(英文): {e}"
def delete_event(self, query: str):
now = datetime.utcnow().isoformat() + 'Z'
event_results = self.find_event(query)
if len(event_results) == 0:
return f"❌ 找不到包含「{query}」的事件"
for event in event_results:
target_id = event["id"]
try:
self.service.events().delete(
calendarId='primary',
eventId=target_id,
sendUpdates='all'
).execute()
return f"🗑️ 已刪除事件:{event['summary']}(ID: {target_id})"
except Exception as e:
return f"❌ 刪除事件失敗(ID: {target_id}),以下是錯誤訊息(英文): {e}"
def get_event_details(self, query: str):
events = self.find_event(query)
if not events:
return f"❌ 找不到符合 '{query}' 的事件!"
event = events[0]
summary = event.get('summary', 'No Title')
start_time = event['start'].get('dateTime', event['start'].get('date'))
end_time = event['end'].get('dateTime', event['end'].get('date'))
formatted_string = f"事件: {summary}\n開始時間: {start_time}\n結束時間: {end_time}"
attendees = event.get('attendees', [])
emails = [attendee.get('email') for attendee in attendees if attendee.get('email')]
if emails:
formatted_string += f"\n參與者: {', '.join(emails)}"
else:
formatted_string += "\n無參與者"
return formatted_string
def get_all_tools(self):
LLM_tools = []
LLM_tools.append({
"name": "create_Calendar_event",
"description": "Create a new Google Calendar event by specifying summary, start time, and end time, and optionally location, description, attendees, and reminder.",
"parameters": {
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Title or summary of the event (e.g., 'Lunch with Alice')"
},
"start_time": {
"type": "string",
"format": "date-time",
"description": "Start time of the event in ISO format (e.g., '2025-07-01T14:00:00')"
},
"end_time": {
"type": "string",
"format": "date-time",
"description": "End time of the event in ISO format (e.g., '2025-07-01T15:00:00')"
},
"location": {
"type": "string",
"description": "Location of the event (e.g., 'Taipei 101')"
},
"description": {
"type": "string",
"description": "Detailed description of the event"
},
"attendees": {
"type": "array",
"items": {"type": "string"},
"description": "List of email addresses to invite to the event"
},
"reminder_minutes": {
"type": "integer",
"description": "Number of minutes before the event to trigger a popup reminder"
}
},
"required": ["summary", "start_time", "end_time"]
},
})
LLM_tools.append({
"name": "list_Calendar_events",
"description": "List your upcoming Google Calendar events.",
"parameters": {
"type": "object",
"properties": {
"n": {
"type": "integer",
"default": 5,
"description": "Number of upcoming events to list (default: 5)"
}
}
}
})
LLM_tools.append({
"name": "update_Calendar_event",
"description": "Update a Google Calendar event using a keyword query to find it. You can update summary, location, description, start/end time, attendees, or reminders.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Keyword to find the event to update (e.g., 'meeting with Bob')"
},
"new_summary": {
"type": "string",
"description": "New summary/title for the event"
},
"new_location": {
"type": "string",
"description": "New location for the event"
},
"new_description": {
"type": "string",
"description": "New description for the event"
},
"new_start": {
"type": "string",
"format": "date-time",
"description": "New start time in ISO format"
},
"new_end": {
"type": "string",
"format": "date-time",
"description": "New end time in ISO format"
},
"new_attendees": {
"type": "array",
"items": {"type": "string"},
"description": "New list of attendees (email addresses)"
},
"reminder_minutes": {
"type": "integer",
"description": "Updated popup reminder time in minutes"
}
},
"required": ["query"]
}
})
LLM_tools.append({
"name": "delete_Calendar_event",
"description": "Delete a Google Calendar event using a keyword query to find it.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Keyword to find the event to delete (e.g., 'meeting with Bob')"
}
},
"required": ["query"]
}
})
LLM_tools.append({
"name": "get_event_details",
"description": "Find the attendee email addresses and the summary of a specific event, based on a keyword.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Keyword to find the event and extract attendees and summary of that event."
}
},
"required": ["query"]
}
})
return LLM_tools