Add custom goal props to breakdown endpoint (#1578)

This commit is contained in:
Ralf Zimmermann 2022-02-01 17:09:45 +01:00 committed by GitHub
parent 78dbdfc092
commit 408d95fe09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 1 deletions

View File

@ -17,6 +17,7 @@ All notable changes to this project will be documented in this file.
- New UTM Tags `utm_content` and `utm_term` plausible/analytics#515
- If a session was started without a screen_size it is updated if an event with screen_size occurs
- Added `LISTEN_IP` configuration parameter plausible/analytics#1189
- The breakdown endpoint with the property query `property=event:goal` returns custom goal properties (within `props`)
### Fixed
- UI fix where multi-line text in pills would not be underlined properly on small screens.

View File

@ -2,7 +2,7 @@ defmodule PlausibleWeb.Api.ExternalStatsController do
use PlausibleWeb, :controller
use Plausible.Repo
use Plug.ErrorHandler
alias Plausible.Stats.Query
alias Plausible.Stats.{Query, Props}
def realtime_visitors(conn, _params) do
site = conn.assigns[:site]
@ -66,6 +66,18 @@ defmodule PlausibleWeb.Api.ExternalStatsController do
limit = String.to_integer(Map.get(params, "limit", "100"))
page = String.to_integer(Map.get(params, "page", "1"))
results = Plausible.Stats.breakdown(site, query, property, metrics, {limit, page})
results =
if property == "event:goal" do
prop_names = Props.props(site, query)
Enum.map(results, fn row ->
Map.put(row, "props", prop_names[row["goal"]] || [])
end)
else
results
end
json(conn, %{"results" => results})
else
{:error, msg} ->

View File

@ -1076,6 +1076,88 @@ defmodule PlausibleWeb.Api.ExternalStatsController.BreakdownTest do
end
end
describe "breakdown by event:goal" do
test "custom properties from custom events are returned", %{conn: conn, site: site} do
insert(:goal, %{domain: site.domain, event_name: "404"})
insert(:goal, %{domain: site.domain, event_name: "Purchase"})
insert(:goal, %{domain: site.domain, page_path: "/test"})
populate_stats([
build(:pageview,
domain: site.domain,
timestamp: ~N[2021-01-01 00:00:00],
pathname: "/test"
),
build(:pageview,
domain: site.domain,
timestamp: ~N[2021-01-01 00:00:01],
pathname: "/test",
"meta.key": ["method"],
"meta.value": ["HTTP"]
),
build(:event,
name: "404",
domain: site.domain,
timestamp: ~N[2021-01-01 00:00:02],
"meta.key": ["method"],
"meta.value": ["HTTP"]
),
build(:event,
name: "Purchase",
domain: site.domain,
timestamp: ~N[2021-01-01 00:00:02],
"meta.key": ["method"],
"meta.value": ["HTTPS"]
),
build(:event,
name: "404",
timestamp: ~N[2021-01-01 00:00:03],
domain: site.domain,
"meta.key": ["OS", "method"],
"meta.value": ["Linux", "HTTP"]
),
build(:event,
name: "404",
timestamp: ~N[2021-01-01 00:00:04],
domain: site.domain,
"meta.key": ["version"],
"meta.value": ["1"]
)
])
conn =
get(conn, "/api/v1/stats/breakdown", %{
"site_id" => site.domain,
"period" => "day",
"date" => "2021-01-01",
"property" => "event:goal"
})
res =
Enum.map(json_response(conn, 200)["results"], fn item ->
Map.update(item, "props", [], fn x -> Enum.sort(x) end)
end)
assert res == [
%{
"goal" => "404",
"props" => ["OS", "method", "version"],
"visitors" => 3
},
%{
"goal" => "Visit /test",
"props" => [],
"visitors" => 2
},
%{
"goal" => "Purchase",
"props" => ["method"],
"visitors" => 1
}
]
end
end
describe "filtering" do
test "event:page filter for breakdown by session props", %{conn: conn, site: site} do
populate_stats([