Skip to content

Commit

Permalink
add temporary metrics to looker studio schema
Browse files Browse the repository at this point in the history
  • Loading branch information
diosmosis committed Jun 28, 2024
1 parent 2153b35 commit 60ec074
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 31 deletions.
3 changes: 3 additions & 0 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export interface ReportMetadata {
parameters?: Record<string, string>;
metricAggregationTypes?: Record<string, string>;
metricAggregationTypesGoal?: Record<string, string>;
processedMetricFormulas?: Record<string, string>;
temporaryMetricAggregationTypes?: Record<string, string>;
temporaryMetricSemanticTypes?: Record<string, string>;
}

export interface Goal {
Expand Down
79 changes: 48 additions & 31 deletions src/schema/report-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function addMetric(
matomoType: string,
siteCurrency: string,
reaggregation?: string,
formula?: string,
lookerFormula?: string,
) {
let type = mapMatomoSemanticTypeToLooker(matomoType, siteCurrency);
let aggregationType = mapMatomoAggregationTypeToLooker(reaggregation);
Expand All @@ -108,9 +108,7 @@ function addMetric(
.setName(name)
.setType(type);

if (formula) {
let { lookerFormula } = mapMatomoFormulaToLooker(formula);

if (lookerFormula) {
field
.setFormula(lookerFormula)
.setAggregation(AggregationType.AUTO);
Expand Down Expand Up @@ -146,6 +144,26 @@ function addDateDimensions(
});
}

function addTemporaryMetric(
fields: GoogleAppsScript.Data_Studio.Fields,
metricId: string,
matomoType: string,
siteCurrency: string,
aggregationType?: string,
) {
const field = fields
.newMetric()
.setId(metricId)
.setName(metricId)
.setIsHidden(true)
.setType(mapMatomoSemanticTypeToLooker(matomoType, siteCurrency));

const tempFieldAggregation = mapMatomoAggregationTypeToLooker(aggregationType);
if (tempFieldAggregation) {
field.setAggregation(tempFieldAggregation);
}
}

export function getFieldsFromReportMetadata(
reportMetadata: Api.ReportMetadata,
goals: Record<string, Api.Goal>,
Expand All @@ -154,41 +172,22 @@ export function getFieldsFromReportMetadata(
) {
const fields = cc.getFields();

// TODO: add temporary metrics first? how do we handle metadata that is only present in getData()?
/*
for (const tempMetric of temporaryMetrics) {
const tempField = fields
.newMetric()
.setId(tempMetric.id)
.setName(tempMetric.id)
.setIsHidden(true)
.setType(mapMatomoSemanticTypeToLooker(tempMetric.type, siteCurrency));
const tempFieldAggregation = mapMatomoAggregationTypeToLooker(tempMetric.aggregationType);
if (tempFieldAggregation) {
tempField.setAggregation(tempFieldAggregation);
}
}
*/

let allMetrics = {
...reportMetadata.metrics,
...reportMetadata.processedMetrics,
};
let allMetrics = { ...reportMetadata.metrics };
let allProcessedMetrics = { ...reportMetadata.processedMetrics };

if (reportMetadata.metricsGoal) {
allMetrics = { ...allMetrics, ...metricsForEachGoal(reportMetadata.metricsGoal, goals) };
}

if (reportMetadata.processedMetricsGoal) {
allMetrics = { ...allMetrics, ...metricsForEachGoal(reportMetadata.processedMetricsGoal, goals) };
allProcessedMetrics = { ...allProcessedMetrics, ...metricsForEachGoal(reportMetadata.processedMetricsGoal, goals) };
}

if (reportMetadata.metricsGoal || reportMetadata.processedMetricsGoal) {
// add goal specific conversion_rate if not present in metadata, but other goal metrics are
// (in 4.x-dev, this is removed in the API despite the data being available)
if (!reportMetadata.metricsGoal?.conversion_rate && !reportMetadata.processedMetricsGoal?.conversion_rate) {
allMetrics = { ...allMetrics, ...metricsForEachGoal({ 'conversion_rate': 'Conversion Rate' }, goals) };
allProcessedMetrics = { ...allProcessedMetrics, ...metricsForEachGoal({ 'conversion_rate': 'Conversion Rate' }, goals) };
}

// pre 5.1.0, the overall conversions and revenue sum metrics were not present in metadata output,
Expand All @@ -215,7 +214,7 @@ export function getFieldsFromReportMetadata(
}
}

const allFieldsSorted = Object.keys(allMetrics);
const allFieldsSorted = Object.keys({ ...allMetrics, ...allProcessedMetrics });

// make sure nb_visits is before unique visitors if it's present so when adding directly to a report, unique visitors
// won't be the column that gets added (since won't have data for ranges)
Expand All @@ -226,6 +225,7 @@ export function getFieldsFromReportMetadata(
allFieldsSorted.unshift('nb_visits');
}

const allTemporaryMetrics = new Set<string>();
(requestedFields || allFieldsSorted).forEach((metricId) => {
if (fields.getFieldById(metricId)) {
return;
Expand All @@ -240,28 +240,34 @@ export function getFieldsFromReportMetadata(

if (DATE_DIMENSIONS[metricId]) {
addDateDimensions(fields, [metricId]);
return;
}

if (reportMetadata.dimensions?.[metricId]) {
addDimension(fields, metricId, reportMetadata.dimensions[metricId]);
return;
}

if (allMetrics[metricId]) {
if (allMetrics[metricId] || allProcessedMetrics[metricId]) {
let matomoType: string;
let aggregationType: string;

const m = metricId.match(/^goal_\d+_(.*)/)
if (m) {
matomoType = reportMetadata.metricTypesGoal?.[m[1]];
aggregationType = reportMetadata.metricAggregationTypesGoal?.[m[1]]; // TODO: handle in core
aggregationType = reportMetadata.metricAggregationTypesGoal?.[m[1]]; // TODO: handle in core (in Goals plugin)
} else {
matomoType = reportMetadata.metricTypes?.[metricId];
aggregationType = reportMetadata.metricAggregationTypes?.[metricId];
}
matomoType = matomoType || 'text';

addMetric(fields, metricId, allMetrics[metricId], matomoType, siteCurrency, aggregationType);
const formula = reportMetadata.processedMetricFormulas?.[metricId];
let { lookerFormula, temporaryMetrics } = mapMatomoFormulaToLooker(formula);

temporaryMetrics.forEach(m => allTemporaryMetrics.add(m));

addMetric(fields, metricId, allMetrics[metricId] || allProcessedMetrics[metricId], matomoType, siteCurrency, aggregationType, lookerFormula);
} else if (metricId === 'nb_uniq_visitors') {
// to support showing nb_uniq_visitors for day periods, but not others, we need to make sure
// the metric appears in the schema no matter what date range is required. which means adding
Expand All @@ -270,6 +276,17 @@ export function getFieldsFromReportMetadata(
}
});

allTemporaryMetrics.forEach((metricId) => {
const aggregationType = reportMetadata.temporaryMetricAggregationTypes[metricId];
const matomoType = reportMetadata.temporaryMetricSemanticTypes[metricId];

if (!matomoType) {
return;
}

addTemporaryMetric(fields, metricId, matomoType, siteCurrency, aggregationType);
});

return fields;
}

Expand Down

0 comments on commit 60ec074

Please sign in to comment.