Calendar & SchedulingDocumentedScanned

google-calendar

Interact with Google Calendar via the Google Calendar API – list upcoming events, create new events, update or delete.

Share:

Installation

npx clawhub@latest install google-calendar

View the full skill documentation and source below.

Documentation

Google Calendar API

Manage calendar events via Google Calendar API.

Setup (OAuth2)

  • Create project:

  • Enable Calendar API: APIs & Services → Enable APIs → Google Calendar API

  • Create OAuth credentials: APIs & Services → Credentials → Create OAuth Client ID

  • Download JSON → save as ~/.config/google/credentials.json

  • Get refresh token using oauth2 flow (see below)
  • Quick Auth (using gcalcli)

    Easiest setup using gcalcli:

    pip install gcalcli
    gcalcli init  # Opens browser for OAuth

    Or use gcloud:

    gcloud auth application-default login --scopes=

    API Basics

    ACCESS_TOKEN=$(gcloud auth application-default print-access-token)
    
    curl -s "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.items[] | {id, summary}'

    List Calendars

    curl -s "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.items[] | {id, summary}'

    Primary calendar ID is usually your email or primary.

    List Events

    CALENDAR_ID="primary"
    TIME_MIN=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    TIME_MAX=$(date -u -d "+7 days" +"%Y-%m-%dT%H:%M:%SZ")
    
    curl -s "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.items[] | {summary, start: .start.dateTime, end: .end.dateTime}'

    Get Today's Events

    TODAY=$(date -u +"%Y-%m-%dT00:00:00Z")
    TOMORROW=$(date -u -d "+1 day" +"%Y-%m-%dT00:00:00Z")
    
    curl -s "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq '.items[] | {summary, start: .start.dateTime}'

    Create Event

    curl -s -X POST "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "summary": "Meeting Title",
        "description": "Meeting description",
        "start": {
          "dateTime": "2024-01-15T10:00:00",
          "timeZone": "Europe/Paris"
        },
        "end": {
          "dateTime": "2024-01-15T11:00:00",
          "timeZone": "Europe/Paris"
        }
      }' | jq '{id, summary, htmlLink}'

    Create Event with Attendees

    curl -s -X POST "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "summary": "Team Meeting",
        "start": {"dateTime": "2024-01-15T14:00:00", "timeZone": "Europe/Paris"},
        "end": {"dateTime": "2024-01-15T15:00:00", "timeZone": "Europe/Paris"},
        "attendees": [
          {"email": "person1@example.com"},
          {"email": "person2@example.com"}
        ],
        "conferenceData": {
          "createRequest": {"requestId": "meet-'$(date +%s)'"}
        }
      }' | jq

    Add sendUpdates=all to send email invites.

    Create All-Day Event

    curl -s -X POST "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "summary": "Holiday",
        "start": {"date": "2024-01-15"},
        "end": {"date": "2024-01-16"}
      }'

    Use date (not dateTime) for all-day events.

    Update Event

    EVENT_ID="event_id_here"
    
    curl -s -X PATCH "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "summary": "Updated Title",
        "description": "Updated description"
      }'

    Delete Event

    curl -s -X DELETE "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}"

    Add Google Meet

    curl -s -X POST "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "summary": "Video Call",
        "start": {"dateTime": "2024-01-15T10:00:00", "timeZone": "Europe/Paris"},
        "end": {"dateTime": "2024-01-15T11:00:00", "timeZone": "Europe/Paris"},
        "conferenceData": {
          "createRequest": {
            "requestId": "'$(uuidgen)'",
            "conferenceSolutionKey": {"type": "hangoutsMeet"}
          }
        }
      }' | jq '.conferenceData.entryPoints[0].uri'

    Free/Busy Query

    curl -s -X POST "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "timeMin": "2024-01-15T00:00:00Z",
        "timeMax": "2024-01-15T23:59:59Z",
        "items": [{"id": "primary"}]
      }' | jq '.calendars.primary.busy'

    Quick Add (Natural Language)

    curl -s -X POST "" \
      -H "Authorization: Bearer ${ACCESS_TOKEN}" | jq

    Rate Limits

    • 1,000,000 queries/day (default)
    • 100 requests/100 seconds/user