Google Calendar
Manage calendars and events with Google Calendar API.
Authentication
| Type | Default | Details |
|---|---|---|
oauth_2 | ✅ | Google OAuth 2.0 with offline access |
Scopes:
https://www.googleapis.com/auth/calendar.readonlyhttps://www.googleapis.com/auth/calendar.events
Uses access_type: "offline" and prompt: "consent" for refresh tokens.
Endpoints
| Path | Risk | Description |
|---|---|---|
calendars.list | read | List the user's accessible calendars. |
calendars.get | read | Get a calendar by id. |
events.list | read | List events on a calendar (use syncToken for deltas). |
events.get | read | Get an event by id. |
events.insert | write | Create an event. |
events.update | write | Patch an existing event. |
events.delete | destructive | Delete an event. |
freebusy.query | read | Query free/busy intervals for one or more calendars. |
calendars.list
List calendars accessible to the user.
Input:
| Field | Type | Description |
|---|---|---|
maxResults | number | Max results per page |
pageToken | string | Pagination token |
Output: { items?: GoogleCalendar[]; nextPageToken?: string }
calendars.get
Get a calendar's metadata.
Input:
| Field | Type | Required | Description |
|---|---|---|---|
calendarId | string | ✅ | Calendar ID (primary or UUID) |
Output: GoogleCalendar
events.list
List events on a calendar.
Input:
| Field | Type | Description |
|---|---|---|
calendarId | string | ✅ Calendar ID |
timeMin | string | ISO datetime lower bound |
timeMax | string | ISO datetime upper bound |
singleEvents | boolean | Expand recurring events |
orderBy | enum | startTime or updated |
pageToken | string | Pagination token |
maxResults | number | Max results |
syncToken | string | Delta sync token |
Output: { items?: GoogleCalendarEvent[]; nextPageToken?: string; nextSyncToken?: string }
events.get
Get a single event.
Input:
| Field | Type | Required | Description |
|---|---|---|---|
calendarId | string | ✅ | Calendar ID |
eventId | string | ✅ | Event ID |
Output: GoogleCalendarEvent
events.insert
Create a new event.
Input:
| Field | Type | Required | Description |
|---|---|---|---|
calendarId | string | ✅ | Calendar ID |
summary | string | Event title | |
description | string | Event description | |
start | object | ✅ | { date?: string; dateTime?: string; timeZone?: string } |
end | object | ✅ | Same shape as start |
attendees | array | Array of { email: string } | |
sendUpdates | enum | all, externalOnly, none |
Output: GoogleCalendarEvent
events.update
Update an existing event.
Input: Same as events.insert plus:
| Field | Type | Required | Description |
|---|---|---|---|
eventId | string | ✅ | Event ID |
Output: GoogleCalendarEvent
events.delete
Delete an event.
Input:
| Field | Type | Required | Description |
|---|---|---|---|
calendarId | string | ✅ | Calendar ID |
eventId | string | ✅ | Event ID |
sendUpdates | enum | all, externalOnly, none |
Output: { ok: boolean }
freebusy.query
Query free/busy intervals.
Input:
| Field | Type | Required | Description |
|---|---|---|---|
timeMin | string | ✅ | ISO datetime start |
timeMax | string | ✅ | ISO datetime end |
items | array | ✅ | Array of { id: string } (calendar IDs) |
timeZone | string | Time zone ID |
Output: { calendars: Record<string, { busy: Array<{ start: string; end: string }>; errors?: unknown }> }
Usage
import { createFabric } from "@fabricorg/integrations";
import { googleCalendar } from "@fabricorg/integrations/plugins";
const fabric = createFabric({
plugins: [googleCalendar({ accessToken: process.env.GOOGLE_ACCESS_TOKEN })],
});
// Create an event
const event = await fabric.googleCalendar.api.events.insert({
calendarId: "primary",
summary: "Team Standup",
start: { dateTime: "2026-05-14T10:00:00-07:00" },
end: { dateTime: "2026-05-14T10:30:00-07:00" },
attendees: [{ email: "alice@example.com" }],
sendUpdates: "all",
});
// Check availability
const busy = await fabric.googleCalendar.api.freebusy.query({
timeMin: "2026-05-14T09:00:00-07:00",
timeMax: "2026-05-14T17:00:00-07:00",
items: [{ id: "primary" }, { id: "room@example.com" }],
});Webhooks
Google Calendar uses Pub/Sub push channels for change notifications rather than direct webhooks. The portal's Pub/Sub bridge invokes events.list with syncToken after each push to fetch deltas.
Types
interface GoogleCalendar {
id: string;
summary: string;
timeZone?: string;
primary?: boolean;
accessRole?: "owner" | "reader" | "writer" | "freeBusyReader";
}
interface GoogleCalendarEvent {
id: string;
status?: "confirmed" | "tentative" | "cancelled";
summary?: string;
description?: string;
start: { date?: string; dateTime?: string; timeZone?: string };
end: { date?: string; dateTime?: string; timeZone?: string };
attendees?: Array<{
email: string;
displayName?: string;
responseStatus?: "needsAction" | "declined" | "tentative" | "accepted";
organizer?: boolean;
}>;
hangoutLink?: string;
htmlLink?: string;
}