Skip to content
← Public packages

@kody/google

Call Gmail, Calendar, Tasks, Drive, Docs, Sheets, People, YouTube, and Analytics through saved Google OAuth.

src/analytics.ts

85 lines · 2.7 KB · TypeScript
import type { GoogleAuthParams } from './accounts.ts'
import { requestGoogle } from './core.ts'
import type { JsonObject } from './types.ts'
import { queryReport as queryYouTubeReport } from './youtube-analytics.ts'
import type { YouTubeAnalyticsReportParams } from './youtube-analytics.ts'

export type AnalyticsRunReportParams = GoogleAuthParams & {
	propertyId: string
	dateRanges: Array<{ startDate: string; endDate: string; name?: string }>
	dimensions?: Array<{ name: string }>
	metrics: Array<{ name: string }>
	dimensionFilter?: JsonObject
	metricFilter?: JsonObject
	limit?: number
	offset?: number
	orderBys?: unknown[]
	keepEmptyRows?: boolean
	currencyCode?: string
}

/**
 * Google Analytics Data API (GA4) plus YouTube Analytics reports.
 * @returns Helper namespace or overview for this Google product.
 * @example
 * import analytics from 'kody:@kody/google/analytics'
 * const report = await analytics().runReport({
 *   propertyId: '123456789',
 *   dateRanges: [{ startDate: '7daysAgo', endDate: 'today' }],
 *   metrics: [{ name: 'activeUsers' }],
 * })
 */
export default function analytics() {
	return { runReport, getMetadata, queryYouTubeAnalytics }
}

export async function runReport(params: AnalyticsRunReportParams): Promise<JsonObject> {
	const { propertyId, dateRanges, dimensions, metrics } = params
	if (!propertyId) throw new Error('runReport requires propertyId (GA4 properties/123456).')
	if (!Array.isArray(dateRanges) || dateRanges.length === 0) {
		throw new Error('runReport requires dateRanges.')
	}
	if (!Array.isArray(metrics) || metrics.length === 0) {
		throw new Error('runReport requires metrics.')
	}
	const resource = propertyId.startsWith('properties/') ? propertyId : 'properties/' + propertyId
	return (await requestGoogle({
		...params,
		api: 'analytics',
		method: 'POST',
		path: '/v1beta/' + resource + ':runReport',
		body: {
			dateRanges,
			dimensions,
			metrics,
			dimensionFilter: params.dimensionFilter,
			metricFilter: params.metricFilter,
			limit: params.limit,
			offset: params.offset,
			orderBys: params.orderBys,
			keepEmptyRows: params.keepEmptyRows,
			currencyCode: params.currencyCode,
		},
	})) as JsonObject
}

export async function getMetadata(
	params: GoogleAuthParams & { propertyId: string },
): Promise<JsonObject> {
	if (!params.propertyId) throw new Error('getMetadata requires propertyId.')
	const resource = params.propertyId.startsWith('properties/')
		? params.propertyId
		: 'properties/' + params.propertyId
	return (await requestGoogle({
		...params,
		api: 'analytics',
		path: '/v1beta/' + resource + '/metadata',
	})) as JsonObject
}

export async function queryYouTubeAnalytics(
	params: YouTubeAnalyticsReportParams,
): Promise<JsonObject> {
	return queryYouTubeReport(params)
}