PHPackages                             wonchoe/laravel-gsc-manager - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. wonchoe/laravel-gsc-manager

ActiveLibrary[API Development](/categories/api)

wonchoe/laravel-gsc-manager
===========================

Reusable Laravel package for discovering, storing, and syncing Google Search Console data via service account JSON credentials.

v0.1.3(1mo ago)014—0%MITPHP ^8.2

Since Apr 27Compare

[ Source](https://github.com/wonchoe/laravel-gsc-manager)[ Packagist](https://packagist.org/packages/wonchoe/laravel-gsc-manager)[ RSS](/packages/wonchoe-laravel-gsc-manager/feed)WikiDiscussions Synced 3w ago

READMEChangelogDependencies (6)Versions (5)Used By (0)

Laravel GSC Manager
===================

[](#laravel-gsc-manager)

Reusable Laravel package for discovering, storing, approving, and syncing Google Search Console data with Google Service Account JSON files.

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 10, 11, or 12
- `google/apiclient` `^2.0`
- One or more Google service accounts added to Search Console property permissions

This package does not use API keys. Authentication is always done with service account JSON credentials.

Installation
------------

[](#installation)

```
composer require wonchoe/laravel-gsc-manager
php artisan vendor:publish --tag=gsc-config
php artisan migrate
```

For local path development:

```
{
  "repositories": [
    {
      "type": "path",
      "url": "packages/wonchoe/laravel-gsc-manager"
    }
  ]
}
```

Service Account JSON Files
--------------------------

[](#service-account-json-files)

Put one or more JSON files in:

```
storage/app/private/gsc-keys/gsc-group-001.json
storage/app/private/gsc-keys/gsc-group-002.json

```

The file names can be anything. Each JSON file is treated as one service account and one group of accessible Search Console sites.

Add each service account `client_email` to the relevant Google Search Console property permissions. The package reads `client_email` and `project_id`, but never returns or logs `private_key`.

Discovery
---------

[](#discovery)

```
php artisan gsc:discover
php artisan gsc:discover --credential=gsc-group-001.json
```

Discovery scans `storage/app/private/gsc-keys`, upserts credentials, calls Search Console `sites.list`, and stores discovered properties. Broken JSON files are logged and skipped without stopping the batch.

Approving Sites
---------------

[](#approving-sites)

By default, discovered sites are inactive until approved:

```
POST /api/gsc/sites/{site}/approve
POST /api/gsc/sites/{site}/disable
```

You can also approve through your own admin UI or directly in the database by setting `status=approved` and `active=true`.

Sync Search Analytics
---------------------

[](#sync-search-analytics)

```
php artisan gsc:sync-analytics --days=3
php artisan gsc:sync-analytics --type=web --type=image --days=30
php artisan gsc:sync-analytics --site=sc-domain:example.com --from=2026-04-01 --to=2026-04-20
```

Supported search types:

- `web`
- `image`
- `video`
- `news`
- `discover`
- `googleNews`

Supported dimensions:

- `date`
- `hour`
- `query`
- `page`
- `country`
- `device`
- `searchAppearance`

Search Analytics uses `startRow` pagination when enabled and stores `clicks`, `impressions`, `ctr`, `position`, dynamic dimension values, a row hash, and the raw API row.

Discover Search Appearances
---------------------------

[](#discover-search-appearances)

```
php artisan gsc:discover-search-appearances --days=30
```

Search Appearance names are not hardcoded. The package discovers them by querying Search Analytics grouped by `searchAppearance`.

Sync Sitemaps
-------------

[](#sync-sitemaps)

```
php artisan gsc:sync-sitemaps
```

Sitemap sync stores sitemap path, submitted/downloaded timestamps, warnings, errors, sitemap index status, pending status, contents, submitted counts, and deprecated `indexed` counts if Google returns them.

Submitting and deleting sitemaps require full scope and are disabled by default:

```
'sitemaps' => [
    'submit_enabled' => false,
    'delete_enabled' => false,
],
```

URL Inspection
--------------

[](#url-inspection)

```
php artisan gsc:inspect-urls --site=sc-domain:example.com --url=https://example.com/page
```

The package calls:

```
POST https://searchconsole.googleapis.com/v1/urlInspection/index:inspect

```

Stored URL Inspection fields include verdict, coverage state, robots state, indexing state, page fetch state, Google/user canonicals, crawl time, crawled-as value, sitemap URLs, referring URLs, inspection result link, AMP/mobile/rich results raw payloads, and the full raw response.

Scheduler Example
-----------------

[](#scheduler-example)

```
use Illuminate\Support\Facades\Schedule;

Schedule::command('gsc:discover')->dailyAt('02:00');
Schedule::command('gsc:access-check')->dailyAt('02:30');
Schedule::command('gsc:discover-search-appearances --days=30')->dailyAt('03:00');
Schedule::command('gsc:sync-analytics --days=3')->dailyAt('03:30');
Schedule::command('gsc:sync-sitemaps')->dailyAt('04:30');
```

API Routes
----------

[](#api-routes)

Default prefix: `/api/gsc`

You can change the route URL prefix and route name prefix in `config/gsc-manager.php`:

```
'routes' => [
    'enabled' => true,
    'prefix' => 'api/gsc', // use 'gsc' if you prefer /gsc/sites
    'name_prefix' => 'gsc-manager.',
    'middleware' => ['api'],
],
```

```
GET    /credentials
GET    /credentials/{credential}
POST   /discover
POST   /access-check

GET    /sites
GET    /sites/{site}
POST   /sites/{site}/approve
POST   /sites/{site}/disable
POST   /sites/{site}/sync-analytics
POST   /sites/{site}/sync-sitemaps
POST   /sites/{site}/discover-search-appearances

GET    /sites/{site}/analytics
GET    /sites/{site}/analytics/summary
GET    /sites/{site}/search-appearances
GET    /sites/{site}/sitemaps
POST   /sites/{site}/sitemaps/submit
DELETE /sites/{site}/sitemaps

POST   /sites/{site}/inspect-url
GET    /sites/{site}/inspections

GET    /dashboard
GET    /sync-logs

```

All responses use:

```
{
  "success": true,
  "message": "OK",
  "data": {},
  "errors": []
}
```

Credential API responses expose safe fields only: `id`, `file_name`, `client_email`, `project_id`, `active`, `last_discovered_at`, and `last_synced_at`.

Supported GSC Data
------------------

[](#supported-gsc-data)

- Sites/properties from `sites.list`
- Search Analytics clicks, impressions, CTR, and position
- Search types: `web`, `image`, `video`, `news`, `discover`, `googleNews`
- Dimensions: `date`, `hour`, `query`, `page`, `country`, `device`, `searchAppearance`
- Sitemaps: submitted/downloaded timestamps, warnings, errors, contents
- URL Inspection: index status, canonicals, crawl time, robots/indexing state, AMP/mobile/rich results raw payloads
- Indexing API: optional and disabled by default

Indexing API Warning
--------------------

[](#indexing-api-warning)

Google officially limits the Indexing API to pages with `JobPosting` or `BroadcastEvent` embedded in `VideoObject`. This package never runs Indexing API automatically for normal pages. It is disabled by default and guarded by `indexing_api.allowed_content_only`.

Security Notes
--------------

[](#security-notes)

- Protect API routes with `auth:sanctum`, admin middleware, or your internal authorization layer.
- Keep `storage/app/private/gsc-keys` outside the public webroot.
- Never expose service account JSON files through web routes.
- The package redacts `private_key`, tokens, and secrets from formatted errors.
- One broken JSON or one failed site sync is logged and skipped without crashing the whole batch.

Configuration
-------------

[](#configuration)

Publish the config:

```
php artisan vendor:publish --tag=gsc-config
```

Key options:

- `credentials_path`: where JSON files are scanned
- `auto_approve_discovered_sites`: whether new sites become active immediately
- `default_scope`: usually `readonly`
- `analytics.row_limit`: capped at 25000
- `analytics.paginate`: enables `startRow` pagination
- `url_inspection.daily_limit_per_site`
- `url_inspection.qpm_limit_per_site`
- `rate_limits.max_retries`

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance89

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity39

Early-stage or recently created project

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~11 days

Total

4

Last Release

55d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/32915897?v=4)[Oleksii Semeniuk](/maintainers/wonchoe)[@wonchoe](https://github.com/wonchoe)

---

Tags

laravelanalyticsseogoogle search consolesearch consoleservice accountgsc

### Embed Badge

![Health badge](/badges/wonchoe-laravel-gsc-manager/health.svg)

```
[![Health](https://phpackages.com/badges/wonchoe-laravel-gsc-manager/health.svg)](https://phpackages.com/packages/wonchoe-laravel-gsc-manager)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.3M347](/packages/psalm-plugin-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.6k](/packages/simplestats-io-laravel-client)[api-platform/laravel

API Platform support for Laravel

58174.6k17](/packages/api-platform-laravel)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1235.9k21](/packages/fleetbase-core-api)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
