Monday, October 27, 2025

Our week in review: Integrating with Google Workspace (week 10)

Paul (Founder)
Development

The integration nobody asked for (but everyone needed)

Here's a conversation I had with an agency manager:

"So when LetAdmin sends landlord emails, do they come from LetAdmin's email or mine?"

"From LetAdmin's generic email address. Why?"

"Because landlords know my email. They don't know some random LetAdmin address. And all my correspondence with them is in Gmail. If property emails go through a different system, I've got no history, no threading, no context."

Oh.

This week I integrated LetAdmin with Google Workspace properly. Gmail for emails, Google Calendar for inspections. Not "LetAdmin has email features"—LetAdmin sends through your actual Gmail account and books into your actual Calendar.

Makes perfect sense in hindsight. But it required OAuth, which I'd been avoiding because OAuth is notoriously fiddly.

Why separate systems are terrible

Think about how letting agencies actually work. Staff use Gmail for all business email. They use Google Calendar for viewings, inspections, meetings. They use Drive for documents. That's their workflow, established over years.

Now you introduce property management software. If it uses separate email addresses, separate calendars, separate document storage? You've just doubled their workload.

They have to check two inboxes. They have to check two calendars. They lose email context because half the conversation is in Gmail and half is in "the system." Landlord asks about something they emailed last month? Good luck finding that email thread split across two systems.

It's friction nobody needs. But I'd been avoiding the integration because OAuth authentication looked complicated.

The OAuth deep end

OAuth 2.0 is how you securely access someone's Google account without storing their password. Google guides you through a permission screen, you grant access, the app gets temporary tokens. Standard stuff.

Except when you're running multi-tenant software with subdomain-based agencies.

Redirect URIs need to work for northside.let-admin.com AND southside.let-admin.com AND every other subdomain. Token storage needs proper encryption. Token refresh needs automatic handling when tokens expire. Scopes need exact permissions (Gmail sending, Calendar events) without requesting unnecessary access.

And error handling? What happens when someone revokes access? What happens when tokens expire mid-operation? What happens when someone has 2FA enabled?

I spent two days reading Google's OAuth documentation. Another day debugging why redirects worked locally but failed in production. Half a day figuring out token refresh timing. But it finally works.

Gmail integration that actually makes sense

Now when LetAdmin sends a landlord report, it sends through the agent's actual Gmail account. Not "noreply@letadmin.com"—their real address that landlords recognize.

The email appears in their Gmail Sent folder. Threading works automatically. If the landlord replies, it goes to their Gmail inbox. Email rules they've set up? Apply automatically. SPF/DKIM authentication? Already configured through their domain. Spam filtering? No issues because it's their own domain sending.

From the landlord's perspective, it's just another email from their agent. From the agent's perspective, they didn't have to manually compose it, but they have complete history in Gmail for reference.

That's the integration value: LetAdmin does the work, but the communication stays in familiar tools.

Calendar bookings that don't get lost

Inspection scheduling was another problem. I could send tenant emails saying "your inspection is Tuesday at 2pm," but where does the agent track that appointment? In a separate calendar? In LetAdmin's interface?

No—it goes straight into Google Calendar. When LetAdmin books an inspection, it creates a Calendar event with the property address, the tenant as an attendee, and a reminder 30 minutes before. The tenant gets a calendar invitation automatically. The agent sees it alongside their other appointments.

Double-booked? Google Calendar won't let you. Forgot about an inspection? The reminder fires. Need to reschedule? Update it in Calendar or LetAdmin, syncs automatically.

The technical disasters (of course there were disasters)

Getting this working was character-building.

Multi-tenant redirect URIs: Needed to register wildcard redirect URIs with Google, but they don't support wildcards. Solution: dynamic redirect URI generation that works with subdomains.

Token expiry mid-send: Tokens expire after an hour. What if someone composes an email, leaves it open for 90 minutes, then sends? Solution: automatic token refresh before every API call with fallback retry.

Timezone nightmares: Google Calendar events need timezone information. UK agencies use BST/GMT depending on season. Solution: agency-level timezone configuration with automatic DST handling.

Race conditions: Multiple staff booking inspections simultaneously could create duplicate Calendar events. Solution: unique constraint on event IDs with idempotent creation.

Each problem took hours to debug because OAuth errors are cryptically unhelpful. "Invalid token" could mean expired, revoked, wrong scope, or network timeout. Fun debugging session.

What agencies actually get

If you're running a letting agency, here's what this week means for you:

Your emails stay in Gmail. Landlord reports, tenant notifications, everything sends through your Gmail account. Complete history, proper threading, no separate inbox to check.

Your calendar stays unified. Inspection bookings appear in Google Calendar alongside your other appointments. Reminders work automatically.

No context switching. Staff don't need to remember whether they emailed someone through Gmail or "the system." It's all Gmail.

Better deliverability. Emails from your domain with proper SPF/DKIM authentication don't get spam filtered like emails from "property-system@something.com" might.

Automatic invitations. Tenants receive Calendar invitations for inspections. They can accept, decline, or request reschedule through familiar Google interface.

What I learned

This week taught me that sometimes avoiding a complicated integration just delays inevitable work.

I put off OAuth because it looked complex. But the alternative—LetAdmin using separate email and separate calendar—was worse for users. They'd tolerate it, but they'd have to work around it constantly.

Building proper integrations is hard. OAuth is fiddly. Multi-tenant OAuth with subdomain routing is extra fiddly. But the result is software that fits into existing workflows instead of forcing new workflows.

Also: Google's documentation for OAuth is comprehensive but assumes you understand OAuth already. If you don't, you'll spend a day just figuring out what "scope" means in practice.

Next week: probably something that doesn't involve parsing JWT tokens. But at least LetAdmin now plays nicely with Google Workspace.