🤖AI Agents Guide
TutorialsComparisonsReviewsExamplesIntegrationsUse CasesTemplatesGlossary
Get Started
🤖AI Agents Guide

Your comprehensive resource for understanding, building, and implementing AI Agents.

Learn

  • Tutorials
  • Glossary
  • Use Cases
  • Examples

Compare

  • Tool Comparisons
  • Reviews
  • Integrations
  • Templates

Company

  • About
  • Contact
  • Privacy Policy

© 2026 AI Agents Guide. All rights reserved.

Home/Integrations/AI Agents + Google Calendar: Setup Guide
IntegrationGoogle Calendarbeginner9 min readSetup: 15-25 minutes

AI Agents + Google Calendar: Setup Guide

Step-by-step guide to connecting AI agents with Google Calendar. Learn how to automate meeting scheduling, availability checking, event creation, and calendar management using LangChain, n8n, and the Google Calendar API.

photo of computer cables
Photo by Kvistholt Photography on Unsplash
By AI Agents Guide Team•February 28, 2026

Table of Contents

  1. What AI Agents Can Do With Google Calendar Access
  2. Setting Up Google Calendar API Access
  3. Option 1: No-Code with n8n
  4. Meeting Request Automation Workflow
  5. Option 2: LangChain with Python
  6. Build Google Calendar Tools
  7. Personal Scheduling Agent
  8. Rate Limits and Best Practices
  9. Next Steps
Team scheduling meeting representing AI-powered calendar management workflow
Photo by Plush Design Studio on Unsplash

Scheduling is a tax on time — every back-and-forth email chain and manual calendar block is time not spent on actual work. AI agents connected to Google Calendar eliminate this overhead by finding availability, creating events with all the right details, and managing calendar hygiene automatically.

For teams with heavy meeting loads, executives with complex calendars, and anyone who handles scheduling for multiple people, Google Calendar AI integration delivers immediate and measurable productivity gains.

What AI Agents Can Do With Google Calendar Access#

Intelligent Scheduling

  • Parse natural language scheduling requests: "set up a 30-minute call with Alex next Tuesday afternoon"
  • Check availability for all attendees before proposing a time
  • Find optimal meeting times that minimize context-switching
  • Create events with video conference links, meeting agendas, and prep materials

Calendar Management

  • Block focus time automatically based on productivity patterns
  • Reschedule conflicting events with minimal disruption
  • Send pre-meeting reminders with relevant documents and context
  • Detect and clean up duplicate or expired calendar events

Schedule Intelligence

  • Generate daily briefings: what's on the agenda, who you're meeting, what to prepare
  • Identify meeting-heavy days and suggest protection for deep work blocks
  • Summarize recurring meeting attendance and suggest which to cancel
  • Alert when back-to-back meetings leave no buffer time

Setting Up Google Calendar API Access#

The Calendar API uses the same Google Cloud project and OAuth setup as Gmail:

pip install google-api-python-client google-auth google-auth-oauthlib python-dotenv langchain langchain-openai
import os
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
from datetime import datetime, timedelta, timezone

# Include both scopes if using Gmail + Calendar together
SCOPES = ['https://www.googleapis.com/auth/calendar']

def get_calendar_service():
    creds = None
    if os.path.exists('token_calendar.json'):
        creds = Credentials.from_authorized_user_file('token_calendar.json', SCOPES)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        with open('token_calendar.json', 'w') as token:
            token.write(creds.to_json())
    return build('calendar', 'v3', credentials=creds)

service = get_calendar_service()

Option 1: No-Code with n8n#

Meeting Request Automation Workflow#

  1. Gmail Trigger: Detect emails with scheduling keywords ("schedule a call", "available for a meeting")
  2. OpenAI: "Extract meeting details: proposed date/time, duration, attendees, purpose"
  3. Google Calendar node: Check availability for the proposed time
  4. Switch: If available → create event; if not → find next available slot
  5. Google Calendar: Create event with attendees and Meet link
  6. Gmail: Reply to the original email confirming the meeting with calendar link

Option 2: LangChain with Python#

Build Google Calendar Tools#

from langchain.tools import tool

service = get_calendar_service()
TIMEZONE = "America/New_York"  # Set to your timezone
CALENDAR_ID = "primary"


@tool
def check_availability(date: str, duration_minutes: int = 30,
                       attendee_emails: list = None) -> str:
    """
    Check availability for a given date. date format: 'YYYY-MM-DD'.
    Returns available time slots for scheduling meetings.
    """
    # Build freebusy query
    day_start = datetime.fromisoformat(f"{date}T09:00:00").astimezone(timezone.utc)
    day_end = datetime.fromisoformat(f"{date}T18:00:00").astimezone(timezone.utc)

    calendars = [{"id": CALENDAR_ID}]
    if attendee_emails:
        calendars.extend([{"id": email} for email in attendee_emails])

    freebusy = service.freebusy().query(body={
        "timeMin": day_start.isoformat(),
        "timeMax": day_end.isoformat(),
        "timeZone": TIMEZONE,
        "items": calendars
    }).execute()

    # Collect all busy periods
    busy_periods = []
    for cal_data in freebusy.get("calendars", {}).values():
        for period in cal_data.get("busy", []):
            start = datetime.fromisoformat(period["start"].replace("Z", "+00:00"))
            end = datetime.fromisoformat(period["end"].replace("Z", "+00:00"))
            busy_periods.append((start, end))

    busy_periods.sort(key=lambda x: x[0])

    # Find available slots
    available = []
    current = day_start
    for busy_start, busy_end in busy_periods:
        if current + timedelta(minutes=duration_minutes) <= busy_start:
            slot_end = min(busy_start, current + timedelta(hours=2))
            available.append(f"{current.strftime('%I:%M %p')} – {slot_end.strftime('%I:%M %p')}")
        current = max(current, busy_end)

    if current + timedelta(minutes=duration_minutes) <= day_end:
        available.append(f"{current.strftime('%I:%M %p')} – {day_end.strftime('%I:%M %p')}")

    if not available:
        return f"No available {duration_minutes}-minute slots on {date}"
    return f"Available slots on {date}:\n" + "\n".join(f"  • {slot}" for slot in available[:5])


@tool
def create_event(title: str, start_datetime: str, duration_minutes: int = 30,
                 attendee_emails: list = None, description: str = "",
                 add_meet_link: bool = True) -> str:
    """
    Create a Google Calendar event. start_datetime format: 'YYYY-MM-DDTHH:MM:SS'.
    attendee_emails: list of email strings.
    """
    start = datetime.fromisoformat(start_datetime)
    end = start + timedelta(minutes=duration_minutes)

    event_body = {
        "summary": title,
        "description": description,
        "start": {"dateTime": start.isoformat(), "timeZone": TIMEZONE},
        "end": {"dateTime": end.isoformat(), "timeZone": TIMEZONE},
    }

    if attendee_emails:
        event_body["attendees"] = [{"email": email} for email in attendee_emails]

    if add_meet_link:
        event_body["conferenceData"] = {"createRequest": {"requestId": f"meet-{int(start.timestamp())}"}}

    params = {"calendarId": CALENDAR_ID, "sendUpdates": "all", "body": event_body}
    if add_meet_link:
        params["conferenceDataVersion"] = 1

    event = service.events().insert(**params).execute()
    meet_link = event.get("conferenceData", {}).get("entryPoints", [{}])[0].get("uri", "No Meet link")
    return f"Event created: '{title}'\nTime: {start.strftime('%B %d, %Y at %I:%M %p')}\nMeet: {meet_link}\nLink: {event.get('htmlLink')}"


@tool
def get_todays_schedule() -> str:
    """Get all calendar events for today."""
    today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
    tomorrow = today + timedelta(days=1)

    events = service.events().list(
        calendarId=CALENDAR_ID,
        timeMin=today.astimezone(timezone.utc).isoformat(),
        timeMax=tomorrow.astimezone(timezone.utc).isoformat(),
        singleEvents=True,
        orderBy="startTime"
    ).execute().get("items", [])

    if not events:
        return "No events scheduled for today"

    lines = [f"Today's schedule ({today.strftime('%A, %B %d')}):"]
    for event in events:
        start = event.get("start", {}).get("dateTime", event.get("start", {}).get("date", ""))
        if "T" in start:
            start_time = datetime.fromisoformat(start.replace("Z", "+00:00")).strftime("%I:%M %p")
        else:
            start_time = "All day"
        attendees = [a.get("email", "") for a in event.get("attendees", []) if not a.get("self")]
        attendee_str = f" | With: {', '.join(attendees[:3])}" if attendees else ""
        lines.append(f"  {start_time}: {event.get('summary', 'No title')}{attendee_str}")
    return "\n".join(lines)


@tool
def block_focus_time(date: str, start_hour: int = 10, duration_hours: int = 2,
                     title: str = "Focus Time — No Meetings") -> str:
    """Block focus time on the calendar to protect deep work periods."""
    start_dt = f"{date}T{start_hour:02d}:00:00"
    result = create_event.run({
        "title": title,
        "start_datetime": start_dt,
        "duration_minutes": duration_hours * 60,
        "add_meet_link": False,
        "description": "Protected focus time — scheduled by AI assistant"
    })
    return result

Personal Scheduling Agent#

from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate

llm = ChatOpenAI(model="gpt-4o", temperature=0)
tools = [check_availability, create_event, get_todays_schedule, block_focus_time]

prompt = ChatPromptTemplate.from_messages([
    ("system", """You are a scheduling assistant with access to Google Calendar.

When handling scheduling requests:
1. Always check availability before creating events
2. Default to 30-minute meetings unless specified
3. Add Google Meet links for remote meetings
4. Confirm the event details before creating (title, time, attendees)
5. Block focus time when requested to protect deep work

Today's date context: use the check_availability and get_todays_schedule tools to understand the calendar state before making decisions.

Timezone: America/New_York — convert user's natural language times to this timezone."""),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# Natural language scheduling
result = executor.invoke({
    "input": "Schedule a 45-minute product review with alice@company.com and bob@company.com tomorrow afternoon. Add a Google Meet link."
})
print(result["output"])

Rate Limits and Best Practices#

Google Calendar API limitValue
Requests per day1,000,000
Requests per 100 seconds100
Events per calendarNo limit

Best practices:

  • Batch freebusy checks: Use the freebusy API for multiple attendees in one call rather than checking calendars individually
  • Use incremental sync: For agents that monitor calendar changes, use the sync token pattern to only fetch changed events
  • Handle all-day events separately: All-day events use date format instead of dateTime in the API response
  • Confirm before creating: For externally visible events with attendees, have the agent confirm details before calling the API

Next Steps#

  • AI Agents Gmail Integration — Parse scheduling emails and auto-create calendar events
  • AI Agents Slack Integration — Post daily calendar briefs to Slack
  • Build an AI Agent with LangChain — Complete framework tutorial
  • Human-in-the-Loop Agents — When to confirm before taking calendar actions

Related Integrations

How to Integrate AI Agents with Airtable

Step-by-step guide to connecting AI agents with Airtable. Learn how to automate record creation, data enrichment, workflow triggers, and database management using LangChain, n8n, and the Airtable REST API.

How to Integrate AI Agents with Asana

Step-by-step guide to connecting AI agents with Asana. Learn how to automate task creation, project updates, workload analysis, and deadline tracking using LangChain, n8n, and the Asana REST API.

AI Agents + Google BigQuery: Setup Guide

Step-by-step guide to connecting AI agents with Google BigQuery. Learn how to automate SQL queries, build analytics pipelines, detect anomalies, and generate business reports using LangChain, n8n, and the BigQuery Python SDK.

← Back to All Integrations