# How the y-gui Integration Router Connects to Gmail and Google Calendar

> Learn how the y-gui integration router manages Gmail and Google Calendar connections via OAuth. Discover its three-stage workflow for secure Third-Party service integration.

- Repository: [luohy15/y-gui](https://github.com/luohy15/y-gui)
- Tags: how-to-guide
- Published: 2026-03-06

---

**The y-gui integration router handles OAuth-based connections to Gmail and Google Calendar through a three-stage workflow: service configuration, authorization URL generation, and callback processing with token persistence to a Cloudflare D1 database.**

The **integration router** serves as the central gateway for third-party service authentication in the y-gui application. Located in [`backend/src/api/integration.ts`](https://github.com/luohy15/y-gui/blob/main/backend/src/api/integration.ts), this router manages the complete lifecycle of Google service connections, from initial authorization requests to secure credential storage.

## OAuth Configuration and Service Setup

The router defines service-specific configurations as constants for each supported integration. These configurations encapsulate the OAuth scope, redirect URIs, and service identifiers required for Google authentication.

In [`backend/src/api/integration.ts`](https://github.com/luohy15/y-gui/blob/main/backend/src/api/integration.ts), you will find the configuration objects for Google services:

- **GOOGLE_CALENDAR_CONFIG**: Defines the Calendar API scope and callback handling
- **GMAIL_CONFIG**: Specifies Gmail API permissions and redirect behavior

Each configuration includes the display name, service identifier, OAuth scope array, environment variable references for redirect URIs, and default callback paths. These constants drive the dynamic behavior of the authentication endpoints.

## Generating Authorization URLs

When a client initiates a connection, the router handles `GET /api/integration/auth/:type` requests to generate Google OAuth URLs dynamically.

The `createOAuthUrl` function constructs the authorization URL by combining the client ID, redirect URI, requested scopes, response type, and access type parameters. The `/auth/:type` handler selects the appropriate configuration based on the route parameter, then returns a JSON response containing the generated URL.

```typescript
// Client-side request to initiate Gmail authorization
const resp = await fetch('/api/integration/auth/google-gmail');
const { authUrl } = await resp.json();
window.location.href = authUrl;  // Redirects to Google's consent screen

```

This endpoint supports offline access and forces consent prompts to ensure refresh tokens are obtained for long-term API access.

## Handling OAuth Callbacks and Token Storage

After user authorization, Google redirects to `/api/integration/callback/:type` with an authorization code. The router processes this through the `handleOAuthCallback` function, which exchanges the code for access and refresh tokens.

The callback handler performs these operations:

1. Extracts the authorization code from the request body
2. Exchanges the code for tokens via Google OAuth servers
3. Constructs an `IntegrationConfig` object containing credentials and metadata
4. Persists the configuration to the database

```typescript
// Server-side callback handler (simplified)
router.post('/callback/:type', async (c) => {
  const { code } = await c.req.json();
  const integration = await handleOAuthCallback(c, code, config);
  return c.json({ success: true, integration });
});

```

The implementation stores access tokens, refresh tokens, and expiry timestamps required for subsequent API calls to Google services.

## Database Persistence with IntegrationD1Repository

Integration records are persisted using the `IntegrationD1Repository` class defined in [`backend/src/repository/d1/integration-d1-repository.ts`](https://github.com/luohy15/y-gui/blob/main/backend/src/repository/d1/integration-d1-repository.ts). This repository manages CRUD operations against the Cloudflare D1 database.

The repository uses `env.CHAT_DB` as the database connection and organizes records by `user_prefix` and integration `name`. Key methods include:

- **getIntegrations()**: Retrieves all integrations for a user
- **createIntegration()**: Inserts new OAuth credentials
- **updateIntegration()**: Refreshes existing token data

The `IntegrationConfig` interface in [`shared/types/index.ts`](https://github.com/luohy15/y-gui/blob/main/shared/types/index.ts) defines the data model, specifying fields for service name, authentication type, connection status, and encrypted credential storage.

```typescript
// Retrieving stored credentials for downstream use
import { IntegrationD1Repository } from '@/backend/repository/d1/integration-d1-repository';

async function getGmailToken(env: Env, userPrefix: string) {
  const repo = new IntegrationD1Repository(env.CHAT_DB, userPrefix);
  const integrations = await repo.getIntegrations();
  const gmail = integrations.find(i => i.name === 'google-gmail');
  return gmail?.credentials?.access_token;
}

```

## Using Stored Integrations

Once persisted, integrations are available to other services within y-gui. The repository provides lookup methods that enable email fetching, calendar event retrieval, and other API operations without requiring re-authentication.

The stored `IntegrationConfig` objects contain the active access tokens and refresh logic, allowing background services to maintain persistent connections to Google APIs.

## Summary

- **The integration router** in [`backend/src/api/integration.ts`](https://github.com/luohy15/y-gui/blob/main/backend/src/api/integration.ts) centralizes OAuth authentication for third-party services
- **Configuration constants** define service-specific OAuth parameters for Gmail and Calendar
- **Two-phase authentication** involves `/auth/:type` for URL generation and `/callback/:type` for token exchange
- **IntegrationD1Repository** handles secure persistence of credentials to Cloudflare D1
- **The IntegrationConfig type** standardizes credential storage across the application

## Frequently Asked Questions

### What happens when the authorization code is exchanged in the callback?

The `handleOAuthCallback` function receives the authorization code from Google's redirect and exchanges it for access and refresh tokens through Google's OAuth token endpoint. It then constructs an `IntegrationConfig` object containing these credentials and persists them to the D1 database via `IntegrationD1Repository`, either creating a new record or updating an existing one with fresh tokens.

### Where are the OAuth tokens stored in y-gui?

OAuth tokens are stored in a Cloudflare D1 database through the `IntegrationD1Repository` class located in [`backend/src/repository/d1/integration-d1-repository.ts`](https://github.com/luohy15/y-gui/blob/main/backend/src/repository/d1/integration-d1-repository.ts). Each integration record is keyed by `user_prefix` and service `name`, storing the access token, refresh token, expiry date, and connection status in JSON format as defined by the `IntegrationConfig` interface.

### How does the router handle different Google services like Gmail versus Calendar?

The router uses service configuration objects (`GOOGLE_CALENDAR_CONFIG` and `GMAIL_CONFIG`) that define the specific OAuth scopes, redirect URIs, and service identifiers for each API. When a request hits `/api/integration/auth/:type` or `/api/integration/callback/:type`, the router maps the `:type` parameter to the appropriate configuration and applies the correct scopes during the OAuth flow.

### Can the integration router support OAuth providers other than Google?

Yes, the architecture supports additional OAuth providers. The router uses a configuration-driven approach where new services can be added by defining new configuration objects with the required OAuth endpoints, scopes, and callback paths. The `IntegrationConfig` type in [`shared/types/index.ts`](https://github.com/luohy15/y-gui/blob/main/shared/types/index.ts) is provider-agnostic, storing generic credential fields that accommodate various authentication schemes beyond Google OAuth.