Prepared by Felix Jumason for the session “Building a Cloud-Native Booking System with GCP OAuth, Calendar & Meet APIs” at DevFest Nairobi 2025.
Project repository: mischief-meet on GitHub
Session Overview
- Why Google Cloud (GCP) services are central to modern scheduling workflows
- How OAuth, Google Calendar, and Meet APIs orchestrate booking automation
- Practical implementation using Next.js 14, Clerk, Prisma, and shadcn/ui
- Demo script and troubleshooting tips for live workshops
Prerequisites
- Google Cloud project with billing enabled
- Clerk application configured for your domain
- PostgreSQL instance (local or managed) for Prisma
- Environment variables in
.envfor database, Clerk, SMTP, andNEXT_PUBLIC_APP_URL - Local tooling: Node.js ≥18,
pnpm,gcloudCLI (optional for verification)
1. Prepare the Google Cloud Project
- Create/Select Project: In Google Cloud Console select a dedicated project for the booking system.
- Enable APIs: Navigate to “APIs & Services → Library” and enable the Google Calendar API (Meet conferences ride on Calendar events).
- Set Up Service Access: Confirm the project has an OAuth consent screen (required even for testing) and billing is active to avoid quota issues during the live demo.
2. Configure the OAuth Consent Screen
- User Type: Choose External so any attendee can authorize during the demo.
- App Information: Add app name, support email, and logo (optional but recommended for trust during live sessions).
-
Scopes: Add the following scopes:
openid,email,profile, andhttps://www.googleapis.com/auth/calendar.events. - Test Users: While in test mode, whitelist your demo accounts; complete verification later for production.
3. Create OAuth Client Credentials
- Go to “APIs & Services → Credentials → Create Credentials → OAuth client ID”.
- Choose Web application and add redirect URIs provided by Clerk, e.g.
https://<your-clerk-subdomain>.clerk.accounts.dev/v1/oauth_callbackfor development and your production domain callback when ready. - Store the Client ID and Client Secret securely; you will paste them into Clerk.
4. Connect GCP OAuth to Clerk
- In the Clerk dashboard open User & Authentication → Social Connections → Google.
- Paste the Google Client ID and Client Secret. Add the extra scope
calendar.eventsto ensure the returned access token authorizes Calendar operations. - Deploy the configuration and log in as a host user to connect a Google account inside the Mischief Meet UI.
5. Create Calendar Events with Meet Links
Clerk stores Google access tokens per user. Our server action retrieves the host’s token, exchanges it for a Calendar client, and issues the event insert request with Meet conferencing enabled.
const oauth2Client = new google.auth.OAuth2();
oauth2Client.setCredentials({ access_token: token });
const calendar = google.calendar({ version: "v3", auth: oauth2Client });
const meetResponse = await calendar.events.insert({
calendarId: "primary",
conferenceDataVersion: 1,
requestBody: {
summary: event.title,
description: validatedData.additionalInfo,
start: { dateTime: validatedData.startTime },
end: { dateTime: validatedData.endTime },
attendees: [
{ email: validatedData.email },
{ email: event.user.email },
],
conferenceData: {
createRequest: { requestId: `${event.id}-${Date.now()}` },
},
},
});
const meetLink = meetResponse.data.hangoutLink;
const googleEventId = meetResponse.data.id;
6. Persist the Booking and Notify Participants
- Save the booking metadata (including
googleEventIdandmeetLink) via Prisma. - Send transactional emails to both attendee and host containing the Meet URL and calendar details.
- Display the Meet link instantly in the UI for confirmation during the demo.
7. Handle Cancellations Gracefully
Use the stored googleEventId to delete the event from Google Calendar; fall back to database cleanup if the Google API call fails.
const oauth2Client = new google.auth.OAuth2();
oauth2Client.setCredentials({ access_token: token });
const calendar = google.calendar({ version: "v3", auth: oauth2Client });
try {
await calendar.events.delete({
calendarId: "primary",
eventId: meeting.googleEventId,
});
} catch (error) {
console.error("Failed to delete event from Google Calendar:", error);
}
await db.booking.delete({ where: { id: meetingId } });
8. Generate Availability Windows
Precompute upcoming slots based on host availability, duration, and existing bookings so the client component only surfaces valid times.
for (let date = startDate; date <= endDate; date = addDays(date, 1)) {
const dayOfWeek = format(date, "EEEE").toUpperCase();
const dayAvailability = availability?.days?.find(
(d) => d.day === dayOfWeek
);
if (!dayAvailability) continue;
const slots = generateAvailableTimeSlots(
dayAvailability.startTime,
dayAvailability.endTime,
event.duration,
bookings,
format(date, "yyyy-MM-dd"),
availability.timeGap || 0
);
availableDates.push({
date: format(date, "yyyy-MM-dd"),
slots,
});
}
Demo Flow Checklist
- Start with the architecture slide explaining token flow (User → Clerk → GCP APIs → Prisma).
- Walk through GCP Console steps live or via screenshots to reinforce the OAuth setup.
- Trigger a booking from the public page; highlight the Meet link returned instantly.
- Show the event in Google Calendar to prove API success.
- Cancel the booking to demonstrate lifecycle cleanup and calendar sync.
- Close with lessons on securing tokens and scaling availability logic.
Troubleshooting Tips
-
Token missing
calendar.eventsscope: Reconnect the Google account after updating Clerk scope settings. -
insufficientPermissionserrors: Confirm the Google account accepted the requested scopes during consent. - Stale access tokens: Clerk refreshes tokens automatically; if you cache them, request fresh credentials before calling the API.
- Double bookings: Always cross-check Prisma bookings before issuing a new slot to the calendar.
Resources & Credits
- Slides & repo: mischief-meet on GitHub
- Event details: DevFest Nairobi Day One
- Google Calendar API docs: developers.google.com/calendar
See you at DevFest Nairobi 2025!




Top comments (0)