feat: integrate Firebase Analytics, add Google Maps dependencies, and expose new GA4 metric API endpoints.
This commit is contained in:
@@ -169,10 +169,180 @@ app.MapGet("/api/metrics/general", async (
|
||||
Console.WriteLine($"Error: {ex}");
|
||||
return Results.Problem($"Analytics API Error: {ex.Message}");
|
||||
}
|
||||
|
||||
})
|
||||
.WithName("GetGeneralMetrics")
|
||||
.WithOpenApi();
|
||||
|
||||
// 3. Tech Overview (OS & App Version)
|
||||
// GET /api/metrics/tech?from=x&to=y
|
||||
app.MapGet("/api/metrics/tech", async (
|
||||
[FromServices] AnalyticsDataService service,
|
||||
[FromQuery] string? from,
|
||||
[FromQuery] string? to) =>
|
||||
{
|
||||
var startDate = from ?? "30daysAgo";
|
||||
var endDate = to ?? "today";
|
||||
|
||||
// Request for OS
|
||||
var requestOS = new RunReportRequest
|
||||
{
|
||||
Property = $"properties/{ga4PropertyId}",
|
||||
DateRanges = new List<DateRange> { new DateRange { StartDate = startDate, EndDate = endDate } },
|
||||
Dimensions = new List<Dimension> { new Dimension { Name = "operatingSystem" } },
|
||||
Metrics = new List<Metric> { new Metric { Name = "activeUsers" } }
|
||||
};
|
||||
|
||||
// Request for App Version
|
||||
var requestVersion = new RunReportRequest
|
||||
{
|
||||
Property = $"properties/{ga4PropertyId}",
|
||||
DateRanges = new List<DateRange> { new DateRange { StartDate = startDate, EndDate = endDate } },
|
||||
Dimensions = new List<Dimension> { new Dimension { Name = "appVersion" } },
|
||||
Metrics = new List<Metric> { new Metric { Name = "activeUsers" } } // use active users to see version adoption
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var responseOS = await service.Properties.RunReport(requestOS, $"properties/{ga4PropertyId}").ExecuteAsync();
|
||||
var responseVersion = await service.Properties.RunReport(requestVersion, $"properties/{ga4PropertyId}").ExecuteAsync();
|
||||
|
||||
var osData = responseOS.Rows?.Select(row => new {
|
||||
os = row.DimensionValues[0].Value,
|
||||
users = int.Parse(row.MetricValues[0].Value)
|
||||
}) ?? Enumerable.Empty<object>();
|
||||
|
||||
var versionData = responseVersion.Rows?.Select(row => new {
|
||||
version = row.DimensionValues[0].Value,
|
||||
users = int.Parse(row.MetricValues[0].Value)
|
||||
}) ?? Enumerable.Empty<object>();
|
||||
|
||||
return Results.Ok(new { operatingSystems = osData, appVersions = versionData });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Results.Problem($"Analytics API Error: {ex.Message}");
|
||||
}
|
||||
})
|
||||
.WithName("GetTechOverview")
|
||||
.WithOpenApi();
|
||||
|
||||
// 4. Top Events
|
||||
// GET /api/metrics/events?from=x&to=y
|
||||
app.MapGet("/api/metrics/events", async (
|
||||
[FromServices] AnalyticsDataService service,
|
||||
[FromQuery] string? from,
|
||||
[FromQuery] string? to) =>
|
||||
{
|
||||
var startDate = from ?? "30daysAgo";
|
||||
var endDate = to ?? "today";
|
||||
|
||||
var request = new RunReportRequest
|
||||
{
|
||||
Property = $"properties/{ga4PropertyId}",
|
||||
DateRanges = new List<DateRange> { new DateRange { StartDate = startDate, EndDate = endDate } },
|
||||
Dimensions = new List<Dimension> { new Dimension { Name = "eventName" } },
|
||||
Metrics = new List<Metric> { new Metric { Name = "eventCount" }, new Metric { Name = "activeUsers" } },
|
||||
OrderBys = new List<OrderBy> { new OrderBy { Desc = true, Metric = new MetricOrderBy { MetricName = "eventCount" } } },
|
||||
Limit = 20
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await service.Properties.RunReport(request, $"properties/{ga4PropertyId}").ExecuteAsync();
|
||||
var result = response.Rows?.Select(row => new {
|
||||
eventName = row.DimensionValues[0].Value,
|
||||
count = int.Parse(row.MetricValues[0].Value),
|
||||
users = int.Parse(row.MetricValues[1].Value)
|
||||
}) ?? Enumerable.Empty<object>();
|
||||
|
||||
return Results.Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Results.Problem($"Analytics API Error: {ex.Message}");
|
||||
}
|
||||
})
|
||||
.WithName("GetTopEvents")
|
||||
.WithOpenApi();
|
||||
|
||||
// 5. Top Screens
|
||||
// GET /api/metrics/screens?from=x&to=y
|
||||
app.MapGet("/api/metrics/screens", async (
|
||||
[FromServices] AnalyticsDataService service,
|
||||
[FromQuery] string? from,
|
||||
[FromQuery] string? to) =>
|
||||
{
|
||||
var startDate = from ?? "30daysAgo";
|
||||
var endDate = to ?? "today";
|
||||
|
||||
var request = new RunReportRequest
|
||||
{
|
||||
Property = $"properties/{ga4PropertyId}",
|
||||
DateRanges = new List<DateRange> { new DateRange { StartDate = startDate, EndDate = endDate } },
|
||||
// GA4 uses 'unifiedScreenName' or 'pagePath' depending on setup, usually 'unifiedScreenName' for apps
|
||||
Dimensions = new List<Dimension> { new Dimension { Name = "unifiedScreenName" } },
|
||||
Metrics = new List<Metric> { new Metric { Name = "screenPageViews" }, new Metric { Name = "activeUsers" } },
|
||||
OrderBys = new List<OrderBy> { new OrderBy { Desc = true, Metric = new MetricOrderBy { MetricName = "screenPageViews" } } },
|
||||
Limit = 20
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await service.Properties.RunReport(request, $"properties/{ga4PropertyId}").ExecuteAsync();
|
||||
var result = response.Rows?.Select(row => new {
|
||||
screenName = row.DimensionValues[0].Value,
|
||||
views = int.Parse(row.MetricValues[0].Value),
|
||||
users = int.Parse(row.MetricValues[1].Value)
|
||||
}) ?? Enumerable.Empty<object>();
|
||||
|
||||
return Results.Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Results.Problem($"Analytics API Error: {ex.Message}");
|
||||
}
|
||||
})
|
||||
.WithName("GetTopScreens")
|
||||
.WithOpenApi();
|
||||
|
||||
// 6. User Retention (New vs Returning)
|
||||
// GET /api/metrics/retention?from=x&to=y
|
||||
app.MapGet("/api/metrics/retention", async (
|
||||
[FromServices] AnalyticsDataService service,
|
||||
[FromQuery] string? from,
|
||||
[FromQuery] string? to) =>
|
||||
{
|
||||
var startDate = from ?? "30daysAgo";
|
||||
var endDate = to ?? "today";
|
||||
|
||||
var request = new RunReportRequest
|
||||
{
|
||||
Property = $"properties/{ga4PropertyId}",
|
||||
DateRanges = new List<DateRange> { new DateRange { StartDate = startDate, EndDate = endDate } },
|
||||
Dimensions = new List<Dimension> { new Dimension { Name = "newVsReturning" } },
|
||||
Metrics = new List<Metric> { new Metric { Name = "activeUsers" }, new Metric { Name = "sessions" } }
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await service.Properties.RunReport(request, $"properties/{ga4PropertyId}").ExecuteAsync();
|
||||
var result = response.Rows?.Select(row => new {
|
||||
type = row.DimensionValues[0].Value,
|
||||
users = int.Parse(row.MetricValues[0].Value),
|
||||
sessions = int.Parse(row.MetricValues[1].Value)
|
||||
}) ?? Enumerable.Empty<object>();
|
||||
|
||||
return Results.Ok(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Results.Problem($"Analytics API Error: {ex.Message}");
|
||||
}
|
||||
})
|
||||
.WithName("GetUserRetention")
|
||||
.WithOpenApi();
|
||||
|
||||
app.Run();
|
||||
|
||||
// Helper to format GA4 YYYYMMDD to YYYY-MM-DD
|
||||
|
||||
Reference in New Issue
Block a user