A TypeScript toolkit for Google Analytics 4, Google Search Console, and Indexing API - designed for use with AI assistants like Claude Code.
- GA4 Analytics - Traffic, pages, events, conversions, real-time data
- Search Console SEO - Search queries, page performance, device/country breakdown
- Indexing API - Request re-indexing, check URL index status
- Auto-save Results - All API responses automatically saved with timestamps
- Type-safe - Full TypeScript support with interfaces for all responses
- Flexible Date Ranges - Support for shorthand (
"30d") and explicit date ranges - Test Coverage - Built with TDD, 78 tests included
- Node.js 18+
- A Google Analytics 4 property
- A Google Search Console property (for SEO features)
- A Google Cloud Platform project with APIs enabled:
- Google Analytics Data API
- Google Search Console API
- Indexing API
- Service account credentials
git clone https://github.com/yourusername/ga4-toolkit.git
cd ga4-toolkit
npm install- Go to Google Cloud Console
- Create a new project (or select existing)
- Enable the following APIs:
- Google Analytics Data API
- Google Search Console API
- Indexing API
- Go to IAM & Admin > Service Accounts
- Click "Create Service Account"
- Give it a name like "ga4-toolkit"
- Click "Create and Continue"
- Skip the optional steps and click "Done"
- Click on the service account you just created
- Go to "Keys" tab > "Add Key" > "Create new key"
- Select JSON and click "Create"
- Save the downloaded JSON file securely
For GA4:
- Open your GA4 property
- Go to Admin > Property Access Management
- Click the "+" button to add a user
- Enter the service account email (from the JSON key)
- Select "Viewer" role
- Click "Add"
For Search Console:
- Open Google Search Console
- Select your property
- Go to Settings > Users and permissions
- Click "Add user"
- Enter the service account email
- Select "Full" permission
- Click "Add"
Copy the example environment file:
cp .env.example .envEdit .env with your credentials:
GA4_PROPERTY_ID=123456789
GA4_CLIENT_EMAIL=your-service-account@your-project.iam.gserviceaccount.com
GA4_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nYOUR_KEY_HERE\n-----END PRIVATE KEY-----\n"
SEARCH_CONSOLE_SITE_URL=https://your-domain.com- Find your GA4 Property ID in GA4 Admin > Property Settings
- Use your exact Search Console property URL (e.g.,
https://casso.app/)
Just ask Claude what you want to analyze:
GA4 Analytics:
"Give me a site overview for the last 30 days"
"Analyze my traffic sources this week"
"What are my top pages?"
"Compare this month to last month"
Search Console SEO:
"What are my top search queries?"
"Show me SEO performance by page"
"Get my Search Console overview"
Indexing:
"Request re-indexing for https://casso.app/blog/new-post"
"Check if these URLs are indexed"
import {
siteOverview,
getPageViews,
searchConsoleOverview,
getTopQueries,
reindexUrls,
checkIndexStatus,
} from './src/index.js';
// GA4 Analytics
const overview = await siteOverview('30d');
const pages = await getPageViews('7d');
// Search Console SEO
const seoOverview = await searchConsoleOverview('30d');
const queries = await getTopQueries('7d');
// Indexing API
const reindexResult = await reindexUrls(['https://casso.app/blog/new-post']);
const indexStatus = await checkIndexStatus(['https://casso.app/']);| Function | Description |
|---|---|
siteOverview(dateRange?) |
Comprehensive site snapshot |
trafficAnalysis(dateRange?) |
Deep dive on traffic sources |
contentPerformance(dateRange?) |
Top pages analysis |
userBehavior(dateRange?) |
User engagement patterns |
compareDateRanges(range1, range2) |
Period comparison |
liveSnapshot() |
Real-time data snapshot |
| Function | Description |
|---|---|
searchConsoleOverview(dateRange?) |
Combined SEO snapshot |
keywordAnalysis(dateRange?) |
Query/keyword deep dive |
seoPagePerformance(dateRange?) |
Page-level SEO metrics |
| Function | Description |
|---|---|
reindexUrls(urls) |
Request re-indexing for multiple URLs |
checkIndexStatus(urls) |
Check if URLs are indexed |
| Function | Description |
|---|---|
runReport(options) |
Run custom report with any dimensions/metrics |
getPageViews(dateRange?) |
Page performance data |
getTrafficSources(dateRange?) |
Traffic source breakdown |
getUserDemographics(dateRange?) |
User demographics (country, device) |
getEventCounts(dateRange?) |
Event tracking data |
getConversions(dateRange?) |
Conversion metrics |
getEcommerceRevenue(dateRange?) |
E-commerce metrics |
| Function | Description |
|---|---|
getActiveUsers() |
Current active users |
getRealtimeEvents() |
Live event stream |
getRealtimePages() |
Currently viewed pages |
| Function | Description |
|---|---|
getAvailableDimensions() |
List all available dimensions |
getAvailableMetrics() |
List all available metrics |
getPropertyMetadata() |
Full property metadata |
| Function | Description |
|---|---|
querySearchAnalytics(options) |
Raw search analytics query |
getTopQueries(dateRange?) |
Top search queries by clicks |
getTopPages(dateRange?) |
Top pages by impressions |
getDevicePerformance(dateRange?) |
Mobile vs desktop breakdown |
getCountryPerformance(dateRange?) |
Traffic by country |
getSearchAppearance(dateRange?) |
Rich results, AMP data |
| Function | Description |
|---|---|
requestIndexing(url) |
Request single URL re-crawl |
requestIndexingBatch(urls) |
Batch request for multiple URLs |
removeFromIndex(url) |
Request URL removal from index |
inspectUrl(url) |
Check URL's index status |
Three formats are supported:
// Shorthand (days ago to today)
await getPageViews('7d');
await getPageViews('30d');
await getPageViews('90d');
// Explicit dates
await getPageViews({ startDate: '2024-01-01', endDate: '2024-01-31' });
// GA4 relative format
await getPageViews({ startDate: '30daysAgo', endDate: 'today' });All results are automatically saved to the results/ directory:
results/
├── reports/
│ └── 20240105_093715__site_overview__30d.json
├── realtime/
│ └── 20240105_094500__snapshot.json
├── searchconsole/
│ └── 20240105_100000__overview__30d.json
├── indexing/
│ └── 20240105_101500__request_indexing.json
└── summaries/
└── january-report.md
Each result includes metadata:
{
"metadata": {
"savedAt": "2024-01-05T09:37:15.123Z",
"category": "reports",
"operation": "site_overview",
"propertyId": "123456789"
},
"data": { ... }
}npm testnpm run test:watchnpm run builddate,dateHour,week,monthcountry,city,regiondeviceCategory,browser,operatingSystempagePath,pageTitle,landingPagesessionSource,sessionMedium,sessionCampaignNameeventName,newVsReturning
activeUsers,newUsers,totalUserssessions,engagedSessions,engagementRatescreenPageViews,averageSessionDurationbounceRate,exitseventCount,conversionstotalRevenue,ecommercePurchases
MIT License - see LICENSE file.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Implement your changes
- Run tests (
npm test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Built with the Google Analytics Data API
- Inspired by the DataForSEO API toolkit pattern