import { getPropertyId, formatPropertyPath, executeReport } from "../../client.js";
import { periodToDateRange } from "../../utils/date.js";
import { calculatePercentage } from "../../utils/percentage.js";
import type {
GetExitPagesInput,
GetExitPagesOutput,
ExitPage,
} from "../../types.js";
/**
* 離脱ページ分析
*/
export async function getExitPages(
input: GetExitPagesInput
): Promise<GetExitPagesOutput> {
const propertyId = getPropertyId(input.propertyId);
const property = formatPropertyPath(propertyId);
const dateRange = periodToDateRange(input.period);
const limit = input.limit || 10;
// GA4では直接exitPageディメンションがないため、
// pagePath と screenPageViews を使って近似する
const response = await executeReport({
property,
dateRanges: [dateRange],
dimensions: [{ name: "pagePath" }],
metrics: [{ name: "screenPageViews" }, { name: "sessions" }],
orderBys: [{ metric: { metricName: "screenPageViews" }, desc: true }],
limit,
});
// 合計セッション数を取得
const totalSessions =
response.totals?.[0]?.metricValues?.[1]?.value
? parseFloat(response.totals[0].metricValues[1].value)
: 0;
const exitPages: ExitPage[] = [];
for (const row of response.rows || []) {
const dimensionValues = row.dimensionValues || [];
const metricValues = row.metricValues || [];
const pageViews = metricValues[0]?.value
? Math.round(parseFloat(metricValues[0].value))
: 0;
const sessions = metricValues[1]?.value
? Math.round(parseFloat(metricValues[1].value))
: 0;
// 離脱数をセッション数で近似(実際の離脱数とは異なる可能性あり)
const exits = sessions;
exitPages.push({
pagePath: dimensionValues[0]?.value || "",
exits,
exitRate: calculatePercentage(exits, totalSessions),
});
}
return { exitPages };
}