Connect Google Calendar
to Your Pipeline
Check your schedule, create events, set reminders, and build daily briefings - your Google credentials never leave your machine.
Your natural language commands flow through OpenClaw to your Expanso-managed pipeline, which reads and writes Google Calendar via the Calendar API. Credentials stay in your infrastructure.
Three steps to go live
Set Up Google Cloud OAuth Credentials
Create OAuth credentials in Google Cloud Console so Expanso can access Calendar on your behalf.
1.1 Create a Google Cloud project
Go to Google Cloud Console. Create a new project (or use an existing one). Enable the Google Calendar API under APIs & Services.
1.2 Create OAuth credentials
Under APIs & Services > Credentials, click Create Credentials > OAuth client ID. Choose "Desktop app". Download the credentials.json file.
1.3 Authenticate with gog CLI
npm install -g gog-cli
gog auth
gog calendar list Tokens are stored locally. Revoke at any time from Google Account Permissions.
1.4 Store the token path
export GOOGLE_CREDENTIALS_PATH="$HOME/.config/gog/credentials.json"
export GOOGLE_TOKEN_PATH="$HOME/.config/gog/token.json" 1.5 Alternative: ICS feed (read-only)
If you only need to query your schedule with no event creation, get your ICS URL from Google Calendar Settings > [Your Calendar] > Integrate calendar and set GOOGLE_CALENDAR_ICS_URL instead.
Deploy the Calendar Pipeline
Create Expanso pipelines for reading and creating calendar events.
2.1 Set up Expanso (if you haven't already)
Follow the Expanso setup guide to create your account and install the CLI.
2.2 Create the calendar reader pipeline
Open cloud.expanso.io, click New Pipeline, and paste:
# calendar-read.yaml
# Reads upcoming calendar events
input:
http_server:
path: /calendar-read
allowed_verbs: [ "POST" ]
pipeline:
processors:
- http:
url: "https://www.googleapis.com/calendar/v3/calendars/primary/events"
verb: GET
headers:
Authorization: "Bearer ${GOOGLE_ACCESS_TOKEN}"
- mapping: |
root.events = this.items.map_each(event -> {
"title": event.summary,
"start": event.start.dateTime.or(event.start.date),
"end": event.end.dateTime.or(event.end.date),
"location": event.location.or(""),
"attendees": event.attendees.or([]).map_each(a -> a.email)
})
output:
sync_response: {} 2.3 Create the event creator pipeline
# calendar-create.yaml
# Creates new calendar events
input:
http_server:
path: /calendar-create
allowed_verbs: [ "POST" ]
pipeline:
processors:
- mapping: |
root.summary = this.title
root.start.dateTime = this.start_time
root.start.timeZone = this.timezone.or("America/Los_Angeles")
root.end.dateTime = this.end_time
root.end.timeZone = this.timezone.or("America/Los_Angeles")
root.attendees = this.attendees.or([]).map_each(email -> {"email": email})
- http:
url: "https://www.googleapis.com/calendar/v3/calendars/primary/events"
verb: POST
headers:
Authorization: "Bearer ${GOOGLE_ACCESS_TOKEN}"
Content-Type: "application/json"
output:
sync_response: {} 2.4 Or: ICS reader for read-only access
# calendar-ics.yaml
# Reads events from ICS feed (read-only, no OAuth needed)
input:
http_server:
path: /calendar-ics
allowed_verbs: [ "POST" ]
pipeline:
processors:
- http:
url: "${GOOGLE_CALENDAR_ICS_URL}"
verb: GET
- mapping: |
root.events = this.split("BEGIN:VEVENT").slice(1).map_each(block -> {
"title": block.re_find("SUMMARY:(.+)").index(1).or(""),
"start": block.re_find("DTSTART[^:]*:(.+)").index(1).or("")
})
output:
sync_response: {} Connect to OpenClaw
Register the Expanso MCP server so OpenClaw can invoke your Calendar pipelines.
3.1 Register the MCP server
expanso-cli mcp add npx @expanso/mcp-pipelines 3.2 Test the integration
Open OpenClaw and try these commands:
"What do I have on my calendar today?"
"Am I free Thursday afternoon between 2-5pm?"
"Schedule a 30-minute call with Sarah tomorrow at 3pm"
"Check my calendar for today and post my schedule to #daily on Slack" Use cases
Every morning, OpenClaw reads your calendar and sends a formatted schedule summary to Slack or your preferred channel - with meeting details and gaps.
Ask "Schedule a call with Sarah sometime this week" - OpenClaw checks availability, finds open slots, and creates the event with the right duration and timezone.
Configure OpenClaw to send meeting reminders via Slack, WhatsApp, or Telegram at custom intervals with natural language configuration.
Ask "How much time did I spend in meetings this week?" — OpenClaw analyzes calendar events, categorizes them, and gives you a breakdown.
Combine your calendar, unread emails, and Jira sprint status into a single digest - three Expanso pipelines, three credential sets, all resolved locally.
Connect both work and personal calendars with selective access. Check availability across all, but only show work event details to team members.
Common questions
Are my Google OAuth tokens safe?
Yes. OAuth tokens are stored locally on your filesystem (managed by the gog CLI). Expanso reads them at pipeline runtime. Neither OpenClaw nor any AI model ever sees your Google credentials. You can revoke access at any time from your Google Account Permissions.
Can OpenClaw see all my calendar events?
The pipeline has access to calendars you've authorized through the OAuth consent screen. You can limit access to specific calendars during setup. OpenClaw sees event data only during the active request - nothing is stored or cached.
Can OpenClaw create events without my approval?
That depends on your configuration. By default, OpenClaw will propose an event and ask for confirmation before creating it. You can configure auto-creation for specific patterns, but the safety boundaries are always under your control.
Does this work with Google Workspace calendars?
Yes. The OAuth flow works identically for personal Gmail and Google Workspace accounts. For Workspace, your admin may need to approve the OAuth app for your organization.
What about other calendar providers (Outlook, Apple)?
Expanso supports 200+ connectors. You can create similar pipelines for Microsoft Outlook (via Microsoft Graph API) or Apple Calendar (via CalDAV). The architecture is the same - Expanso handles the API calls, credentials stay local.
Can I combine calendar with other integrations?
Absolutely. A single OpenClaw command like "Check my schedule and email, then post a morning briefing to Slack" chains three Expanso pipelines: Calendar reader, Gmail reader, and Slack poster. Each uses its own credentials, all resolved locally.
Ready to connect Google Calendar?
Get your OpenClaw wired up to Calendar in under 10 minutes.