import { getPropertyId, formatPropertyPath, executeReport } from "../../client.js";
import { periodToDateRange } from "../../utils/date.js";
import { formatDuration } from "../../utils/format.js";
import { formatPercentageFromDecimal } from "../../utils/percentage.js";
import type { GetTopPagesInput, GetTopPagesOutput, TopPage } from "../../types.js";
/**
* 人気ページランキングを取得
*/
export async function getTopPages(
input: GetTopPagesInput
): Promise<GetTopPagesOutput> {
const propertyId = getPropertyId(input.propertyId);
const property = formatPropertyPath(propertyId);
const dateRange = periodToDateRange(input.period);
const limit = input.limit || 10;
const response = await executeReport({
property,
dateRanges: [dateRange],
dimensions: [{ name: "pagePath" }, { name: "pageTitle" }],
metrics: [
{ name: "screenPageViews" },
{ name: "totalUsers" },
{ name: "averageSessionDuration" },
{ name: "bounceRate" },
],
orderBys: [{ metric: { metricName: "screenPageViews" }, desc: true }],
limit,
...(input.pathFilter && {
dimensionFilter: {
filter: {
fieldName: "pagePath",
stringFilter: {
matchType: "BEGINS_WITH",
value: input.pathFilter,
},
},
},
}),
});
const pages: TopPage[] = [];
let rank = 1;
for (const row of response.rows || []) {
const dimensionValues = row.dimensionValues || [];
const metricValues = row.metricValues || [];
const getValue = (index: number): number => {
const value = metricValues[index]?.value;
return value ? parseFloat(value) : 0;
};
pages.push({
rank: rank++,
pagePath: dimensionValues[0]?.value || "",
pageTitle: dimensionValues[1]?.value || "(タイトルなし)",
pageViews: Math.round(getValue(0)),
uniquePageViews: Math.round(getValue(1)),
avgTimeOnPage: formatDuration(getValue(2)),
bounceRate: formatPercentageFromDecimal(getValue(3)),
});
}
return { pages };
}