How to Integrate Google Search Console Data into OpenSEO: A Complete Technical Guide
OpenSEO integrates Google Search Console data through a layered architecture that separates OAuth authentication, service-level business logic, and server-function API endpoints, ensuring secure, client-side-free data retrieval using the user's own OAuth tokens.
The every-app/open-seo repository implements a robust Google Search Console (GSC) integration that allows projects to pull search analytics, inspect URLs, and manage property connections without persisting raw Google data beyond the essential connection records. This guide examines the exact file structure, service methods, and implementation patterns used to stream GSC data into the platform's reporting UI.
OAuth Configuration and Constants
All Google Search Console OAuth configuration resides in src/shared/gsc.ts. This file defines the provider ID (google-search-console) and required OAuth scopes that enable the application to query search analytics and site data on behalf of the user.
The low-level HTTP client wrapper, createGscClient, is exported from src/server/lib/gscClient.ts (imported throughout the service layer). This client encapsulates direct calls to the Google Search Console REST API, including listSites, querySearchAnalytics, and inspectUrl operations.
The GscService Layer
The core business logic for integrating Google Search Console data into OpenSEO lives in src/server/features/gsc/services/GscService.ts. This service orchestrates grant detection, connection management, and data retrieval while handling token-related failures gracefully.
Grant Detection
The userHasGrant method checks the account table for an existing Google Search Console grant by searching for providerId = "google-search-console". This determines whether the authenticated user has previously authorized the application to access their GSC data.
Connection Handling
getConnection, setSite, and disconnect manage the one-to-one mapping between an OpenSEO project and a GSC property:
getConnection: Retrieves the current project-to-property link fromGscConnectionRepositorysetSite: Binds a selected GSC property to a specific project, persisting the relationshipdisconnect: Removes the link between a project and its associated GSC property
Data Retrieval
The getPerformance method forwards searchAnalytics.query requests to the GSC client. It returns rows of search performance data, request metadata, and the property's URL, which powers the platform's dashboard and CSV export features.
URL Inspection
inspectUrls runs batch URL inspections against the connected property. This method handles per-URL errors individually while propagating authentication failures (token expiration or revocation) upward for UI handling.
Error Handling
The service defines GscNotConnectedError to signal when a project lacks a linked GSC property. The isExpectedGrantFailure utility identifies 401/403 responses or token-related errors that should trigger a reconnection UI rather than display as internal server errors.
Server-Function API Endpoints
The public API exposed to the frontend resides in src/serverFunctions/gsc.ts. These server functions bridge the UI and the GscService layer:
getGscGrantStatus: Returns whether the authenticated user has authorized GSC access ({ connected: true|false })getGscConnection: Provides the current project's connection status, including grant validity and site URLlistGscSites: Lists all GSC properties available to the user, marking which site is currently bound to the projectsetGscSite: ExecutesGscService.setSiteto bind a selected propertydisconnectGsc: Removes the project-to-property link viaGscService.disconnectstartSelfHostedGscLink: Generates an OAuth authorization URL for self-hosted deployments
Performance Data Integration
Search performance reports leverage src/serverFunctions/searchPerformance.ts, which calls GscService.getPerformance to assemble dashboard data, analytics tables, and CSV exports. Additionally, the MCP debugging tools in src/server/mcp/tools/search-console-tools.ts utilize the same service methods for development and diagnostics.
The data flow follows this architecture:
Frontend → Server Functions (gsc.ts) → GscService → GscConnectionRepository / GSC Client → Google Search Console API
All GSC data fetching occurs server-side only, using the user's own OAuth token without exposing credentials to the client or persisting raw Google data beyond the project-specific connection record.
Implementation Examples
Check grant status before displaying GSC features:
const { connected } = await getGscGrantStatus();
// Returns: { connected: true } or { connected: false }
List available properties for the user to select:
const { accounts } = await listGscSites({ projectId: "proj_123" });
accounts.forEach(account => {
console.log(`Account ${account.email} has ${account.sites.length} sites`);
});
Connect a project to a specific GSC property:
await setGscSite({
projectId: "proj_123",
accountId: "gsc_acc_456",
siteUrl: "https://example.com/",
});
Fetch search performance metrics for a date range:
const report = await getSearchPerformanceReport({
projectId: "proj_123",
dateRange: { start: "2024-01-01", end: "2024-01-31" },
device: "mobile",
});
console.log(report.totals);
Summary
- Authentication constants live in
src/shared/gsc.ts, defining OAuth scopes and the GSC provider ID - Core integration logic resides in
src/server/features/gsc/services/GscService.ts, handling grants, connections, queries, and errors - API endpoints in
src/serverFunctions/gsc.tsexpose grant status, site listing, and connection management to the frontend - Performance data flows through
src/serverFunctions/searchPerformance.tsand MCP tools using the same service layer - All data retrieval uses server-side OAuth tokens with
GscConnectionRepositorymanaging persistent project-to-property mappings
Frequently Asked Questions
What OAuth scopes does OpenSEO require for Google Search Console access?
OpenSEO requires standard Google Search Console API scopes defined in src/shared/gsc.ts, which typically include read-only access to search analytics data and site management permissions. The application uses these scopes solely to query searchAnalytics.query and inspectUrl endpoints, never persisting raw Google data beyond the connection metadata stored via GscConnectionRepository.
How does OpenSEO handle expired or revoked OAuth tokens?
The GscService implements isExpectedGrantFailure to detect 401 and 403 responses or token-related errors. When encountered, these errors surface to the frontend as expected grant failures rather than internal server errors, triggering the reconnection UI. Users must then re-authorize through startSelfHostedGscLink or the standard OAuth flow to restore access.
Can I connect multiple Google Search Console properties to a single OpenSEO project?
No, the architecture enforces a one-to-one mapping between a project and a GSC property. The setSite method in GscService binds one specific siteUrl to a given projectId, and getConnection retrieves only that singular relationship. To analyze multiple properties, you must create separate OpenSEO projects for each GSC site.
Where does OpenSEO store Google Search Console connection data?
Connection metadata persists in the database through GscConnectionRepository, storing only the project-to-property mapping (project ID, account ID, and site URL). Raw search analytics data is never persisted; instead, getPerformance fetches fresh data from Google's API on each request using the stored OAuth grant, ensuring reports always reflect current GSC metrics.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →