Integrating Google Calendar API with Website
Google Calendar API is used to display event schedules on the website, synchronize bookings and meetings, and create events on behalf of users. Covers tasks from simple event widgets to full-featured scheduling systems.
Public Calendar Without Authorization
To display public events, an API Key is sufficient without OAuth:
async function getPublicEvents(calendarId: string): Promise<CalendarEvent[]> {
const resp = await fetch(
`https://www.googleapis.com/calendar/v3/calendars/${encodeURIComponent(calendarId)}/events` +
`?key=${process.env.GOOGLE_API_KEY}` +
`&timeMin=${new Date().toISOString()}` +
`&orderBy=startTime&singleEvents=true&maxResults=20`
);
const data = await resp.json();
return data.items.map((item: any) => ({
id: item.id,
title: item.summary,
start: item.start.dateTime ?? item.start.date,
end: item.end.dateTime ?? item.end.date,
location: item.location,
url: item.htmlLink,
}));
}
OAuth2 for Personal Calendars
// Create event in user's calendar after authorization
$client = new Google\Client();
$client->setAccessToken($userAccessToken);
$calendar = new Google\Service\Calendar($client);
$eventData = new Google\Service\Calendar\Event([
'summary' => $booking->service->name,
'location' => $booking->location,
'start' => ['dateTime' => $booking->starts_at->toRfc3339String(), 'timeZone' => 'Europe/Moscow'],
'end' => ['dateTime' => $booking->ends_at->toRfc3339String(), 'timeZone' => 'Europe/Moscow'],
'reminders' => [
'useDefault' => false,
'overrides' => [['method' => 'popup', 'minutes' => 60]],
],
]);
$event = $calendar->events->insert('primary', $eventData);
"Add to Google Calendar" Button
Without API — simplest option for events:
function getGoogleCalendarUrl(event: Event): string {
const params = new URLSearchParams({
action: 'TEMPLATE',
text: event.title,
dates: `${formatDate(event.start)}/${formatDate(event.end)}`,
details: event.description,
location: event.location ?? '',
});
return `https://calendar.google.com/calendar/render?${params}`;
}
function formatDate(date: Date): string {
return date.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z';
}
Timeline
Public events widget: 1 day. OAuth2 with personal calendar write: 2–3 days.







