mcp-ga4-analytics
v1.0.2
Published
Google Analytics Node.js library for easy integration with Google Analytics 4 API
Maintainers
Readme
Google Analytics 4 Node.js Library
A simple and powerful Node.js library for Google Analytics 4 API integration. Works just like nodemailer - easy configuration with maximum functionality.
Features
- 🔐 Multiple Authentication Methods: Service Account, OAuth2, and Auto-detection
- 📊 Complete GA4 API Coverage: Real-time data, historical reports, audience insights, conversions
- 🚀 Simple Setup: Configure once, use everywhere - just like nodemailer
- 📈 Pre-built Report Functions: Traffic sources, page performance, audience demographics, conversions
- 🛠️ Full TypeScript Support: Complete type safety and IntelliSense
- ⚡ Modern Promise-based API: Clean async/await syntax
- 🎯 Flexible Custom Reports: Build any report with GA4 metrics and dimensions
- 📱 Real-time Analytics: Live user data and active sessions
Installation
npm install mcp-ga4-analyticsQuick Start
1. Service Account (Recommended for Production)
const GoogleAnalytics = require('mcp-ga4-analytics');
const analytics = new GoogleAnalytics({
serviceAccount: {
keyFilePath: './service-account-key.json'
}
});
await analytics.initialize();
// Get all properties
const properties = await analytics.listProperties();
console.log('Properties:', properties);
// Get real-time data
const realtimeData = await analytics.getRealtimeReport({
propertyId: 'your-property-id',
metrics: ['activeUsers'],
dimensions: ['country'],
limit: 10
});
console.log('Active users by country:', realtimeData);2. OAuth2 (For Client Applications)
const analytics = new GoogleAnalytics({
oauth: {
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
},
credentialsPath: './credentials.json'
});
// First time: Get auth URL
const authUrl = await analytics.authenticate();
console.log('Visit:', authUrl);
// After user authorization, set the code
await analytics.setTokens('authorization-code-from-callback');
// Now initialize and use
await analytics.initialize();
const properties = await analytics.listProperties();3. Auto-detection (Automatic Authentication)
const analytics = new GoogleAnalytics({
keyFilePath: './gcp-keys.json', // Can be service account or OAuth2 keys
credentialsPath: './credentials.json' // Only for OAuth2
});
await analytics.initialize();
// Ready to use!Authentication Setup
Option 1: Service Account (Production Apps)
- Go to Google Cloud Console
- Create or select a project
- Enable Google Analytics Reporting API v1 and Google Analytics Admin API v1
- Create Service Account:
- Navigate to "IAM & Admin" > "Service Accounts"
- Click "Create Service Account"
- Download the JSON key file
- In Google Analytics, add the service account email as a Viewer to your GA4 property
Option 2: OAuth2 (Client Apps)
- Go to Google Cloud Console
- Create or select a project
- Enable Google Analytics Reporting API v1 and Google Analytics Admin API v1
- Create OAuth2 credentials:
- Go to "APIs & Services" > "Credentials"
- Create "OAuth client ID"
- Choose "Web application" or "Desktop application"
- Add authorized redirect URIs (e.g.,
http://localhost:3000/callback) - Download the credentials JSON file
Core API Methods
Basic Usage
import GoogleAnalytics from 'mcp-ga4-analytics';
const analytics = new GoogleAnalytics({
keyFilePath: './gcp-keys.json'
});
await analytics.initialize();
// List all available properties
const properties = await analytics.listProperties();
console.log('Properties:', properties);
// Use the first property for reports
const propertyId = properties[0].property;Real-time Analytics
// Get current active users by location and device
const realtime = await analytics.getRealtimeReport({
propertyId,
metrics: ['activeUsers', 'screenPageViews'],
dimensions: ['country', 'deviceCategory'],
limit: 10
});
// Display active users right now
if (realtime.rows) {
realtime.rows.forEach(row => {
const country = row.dimensionValues[0]?.value;
const device = row.dimensionValues[1]?.value;
const users = row.metricValues[0]?.value;
console.log(`${country} (${device}): ${users} active users`);
});
}Pre-built Report Functions
// Traffic sources for last 30 days
const traffic = await analytics.getTrafficSourcesReport(
propertyId,
'30daysAgo',
'today'
);
// Top pages performance
const pages = await analytics.getPageReport(
propertyId,
'7daysAgo',
'today'
);
// Audience demographics and behavior
const audience = await analytics.getAudienceReport(
propertyId,
'30daysAgo',
'today'
);
// Conversion events and revenue
const conversions = await analytics.getConversionReport(
propertyId,
'30daysAgo',
'today'
);Custom Reports
// Build any custom report with GA4 metrics and dimensions
const customReport = await analytics.getReport({
propertyId,
startDate: '2024-01-01',
endDate: '2024-01-31',
metrics: ['sessions', 'users', 'screenPageViews', 'bounceRate'],
dimensions: ['source', 'medium', 'campaign'],
orderBy: [{ metric: 'sessions', desc: true }],
limit: 50
});
// Process the results
if (customReport.rows) {
customReport.rows.forEach((row, index) => {
const source = row.dimensionValues[0]?.value;
const sessions = row.metricValues[0]?.value;
const users = row.metricValues[1]?.value;
console.log(`${index + 1}. ${source}: ${sessions} sessions, ${users} users`);
});
}Property Management
// List all properties you have access to
const properties = await analytics.listProperties();
properties.forEach(prop => {
console.log(`${prop.displayName} (${prop.property})`);
console.log(` Currency: ${prop.currencyCode}`);
console.log(` Timezone: ${prop.timeZone}`);
});
// Get available metrics and dimensions for a property
const metadata = await analytics.getMetadata(propertyId);
console.log(`Available: ${metadata.metrics?.length} metrics, ${metadata.dimensions?.length} dimensions`);TypeScript Support
import GoogleAnalytics, {
AnalyticsConfig,
ReportRequest,
PropertyInfo,
AnalyticsReport
} from 'mcp-ga4-analytics';
const config: AnalyticsConfig = {
keyFilePath: './gcp-keys.json'
};
const analytics = new GoogleAnalytics(config);
// Type-safe API calls
const properties: PropertyInfo[] = await analytics.listProperties();
const report: AnalyticsReport = await analytics.getReport({
propertyId: properties[0].property,
metrics: ['sessions'],
dimensions: ['source']
});Complete Configuration Options
const analytics = new GoogleAnalytics({
// Method 1: Service Account (Production)
serviceAccount: {
keyFilePath: './service-account-key.json'
},
// Method 2: OAuth2 (Client Apps)
oauth: {
clientId: 'your-google-client-id',
clientSecret: 'your-google-client-secret',
redirectUri: 'http://localhost:3000/callback' // Optional
},
credentialsPath: './oauth-credentials.json', // Where to store tokens
// Method 3: Auto-detect from key file (Easiest)
keyFilePath: './gcp-keys.json', // Service account or OAuth2 keys
credentialsPath: './credentials.json' // Only needed for OAuth2
});Available GA4 Metrics & Dimensions
Core Metrics
- User Metrics:
activeUsers,totalUsers,newUsers - Session Metrics:
sessions,engagedSessions,averageSessionDuration,bounceRate - Page Metrics:
screenPageViews,screenPageViewsPerSession - Event Metrics:
eventCount,conversions - Revenue Metrics:
totalRevenue,purchaseRevenue - Engagement:
engagementRate,userEngagementDuration
Core Dimensions
- Time:
date,year,month,week,day,hour - Geography:
country,city,continent,region - Technology:
deviceCategory,operatingSystem,browser - Traffic:
source,medium,campaign,channelGroup - Content:
pagePath,pageTitle,screenName - Events:
eventName - User:
userAgeBracket,userGender
Error Handling & Best Practices
try {
await analytics.initialize();
const properties = await analytics.listProperties();
if (properties.length === 0) {
console.log('No GA4 properties found. Check authentication and permissions.');
return;
}
const propertyId = properties[0].property;
const report = await analytics.getReport({
propertyId,
metrics: ['sessions', 'users'],
dimensions: ['source', 'medium'],
startDate: '7daysAgo',
endDate: 'today',
limit: 20
});
console.log(`Found ${report.rowCount} results`);
} catch (error) {
if (error.message.includes('authentication')) {
console.error('❌ Authentication failed. Check your key files and permissions.');
} else if (error.message.includes('property')) {
console.error('❌ Property access denied. Ensure the service account has Viewer permissions.');
} else if (error.message.includes('ENOENT')) {
console.error('❌ Key file not found. Check your file paths.');
} else {
console.error('❌ GA4 API error:', error.message);
}
}Advanced Features
Date Range Options
// Use predefined shortcuts
const report = await analytics.getReport({
propertyId,
startDate: '30daysAgo', // Supported: 'today', 'yesterday', '7daysAgo', '30daysAgo'
endDate: 'today',
metrics: ['sessions', 'users']
});
// Or use specific dates (YYYY-MM-DD format)
const customDateReport = await analytics.getReport({
propertyId,
startDate: '2024-01-01',
endDate: '2024-01-31',
metrics: ['sessions', 'users', 'conversions']
});Advanced Report Building
// Complex report with multiple metrics, dimensions, and sorting
const advancedReport = await analytics.getReport({
propertyId,
startDate: '30daysAgo',
endDate: 'today',
metrics: [
'sessions',
'users',
'newUsers',
'screenPageViews',
'averageSessionDuration',
'bounceRate',
'conversions',
'totalRevenue'
],
dimensions: [
'source',
'medium',
'campaign',
'country',
'deviceCategory'
],
orderBy: [
{ metric: 'sessions', desc: true },
{ dimension: 'source', desc: false }
],
limit: 100
});
// Process results with type safety
if (advancedReport.rows) {
advancedReport.rows.forEach(row => {
const [source, medium, campaign, country, device] = row.dimensionValues.map(d => d.value);
const [sessions, users, newUsers, pageViews, duration, bounce, conversions, revenue] = row.metricValues.map(m => m.value);
console.log({
source, medium, campaign, country, device,
sessions, users, newUsers, pageViews, duration, bounce, conversions, revenue
});
});
}Multi-Property Analytics
// Analyze multiple GA4 properties at once
const properties = await analytics.listProperties();
for (const property of properties) {
console.log(`\n📊 Analyzing: ${property.displayName}`);
// Get real-time users
const realtime = await analytics.getRealtimeReport({
propertyId: property.property,
metrics: ['activeUsers'],
limit: 1
});
// Get traffic summary
const traffic = await analytics.getTrafficSourcesReport(
property.property,
'7daysAgo',
'today'
);
const activeUsers = realtime.totals?.[0]?.metricValues?.[0]?.value || '0';
const topSource = traffic.rows?.[0]?.dimensionValues?.[0]?.value || 'N/A';
console.log(` 🔴 Active users: ${activeUsers}`);
console.log(` 🚀 Top source: ${topSource}`);
}OAuth2 Authentication Flow
// Step 1: Get authorization URL
const analytics = new GoogleAnalytics({
oauth: {
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
},
credentialsPath: './credentials.json'
});
const authUrl = await analytics.getAuthUrl();
console.log('Visit this URL:', authUrl);
// Step 2: After user grants permission, exchange code for tokens
const authCode = 'code-from-callback-url';
await analytics.setTokens(authCode);
// Step 3: Initialize and use
await analytics.initialize();
const properties = await analytics.listProperties();Testing Your Setup
# Run the example file
node example.js
# Test specific authentication methods
npm test -- --service-account # Test service account
npm test -- --oauth # Test OAuth2
npm test -- --key-file # Test auto-detection
npm test -- --comprehensive # Full test suiteReal-world Usage Examples
// Dashboard metrics for your app
async function getDashboardMetrics(propertyId) {
const analytics = new GoogleAnalytics({ /* your config */ });
await analytics.initialize();
const [realtime, traffic, pages, audience] = await Promise.all([
analytics.getRealtimeReport({ propertyId, metrics: ['activeUsers'] }),
analytics.getTrafficSourcesReport(propertyId, '30daysAgo', 'today'),
analytics.getPageReport(propertyId, '30daysAgo', 'today'),
analytics.getAudienceReport(propertyId, '30daysAgo', 'today')
]);
return {
activeUsers: realtime.totals?.[0]?.metricValues?.[0]?.value || '0',
topTrafficSource: traffic.rows?.[0]?.dimensionValues?.[0]?.value || 'Direct',
topPage: pages.rows?.[0]?.dimensionValues?.[0]?.value || '/',
totalSessions: audience.totals?.[0]?.metricValues?.[2]?.value || '0'
};
}
// Automated reporting
async function generateWeeklyReport(propertyId) {
const analytics = new GoogleAnalytics({ /* your config */ });
await analytics.initialize();
const weeklyData = await analytics.getReport({
propertyId,
startDate: '7daysAgo',
endDate: 'yesterday',
metrics: ['sessions', 'users', 'newUsers', 'screenPageViews', 'conversions'],
dimensions: ['date'],
orderBy: [{ dimension: 'date', desc: false }]
});
return weeklyData.rows?.map(row => ({
date: row.dimensionValues[0]?.value,
sessions: row.metricValues[0]?.value,
users: row.metricValues[1]?.value,
newUsers: row.metricValues[2]?.value,
pageViews: row.metricValues[3]?.value,
conversions: row.metricValues[4]?.value
}));
}License
MIT License - see LICENSE file for details.
Made in India with ❤️ by brain.webnexs.com
