Skip to content

Commit

Permalink
feat(web-analytics): Support screen events in web analytics queries (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
robbie-c authored Jan 6, 2025
1 parent 942c647 commit da23d14
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 159 deletions.
1 change: 1 addition & 0 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export const FEATURE_FLAGS = {
CDP_ACTIVITY_LOG_NOTIFICATIONS: 'cdp-activity-log-notifications', // owner: #team-cdp
COOKIELESS_SERVER_HASH_MODE_SETTING: 'cookieless-server-hash-mode-setting', // owner: @robbie-c #team-web-analytics
INSIGHT_COLORS: 'insight-colors', // owner @thmsobrmlr #team-product-analytics
WEB_ANALYTICS_FOR_MOBILE: 'web-analytics-for-mobile', // owner @robbie-c #team-web-analytics
} as const
export type FeatureFlagKey = (typeof FEATURE_FLAGS)[keyof typeof FEATURE_FLAGS]

Expand Down
1 change: 1 addition & 0 deletions frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -13402,6 +13402,7 @@
"InitialPage",
"ExitPage",
"ExitClick",
"ScreenName",
"InitialChannelType",
"InitialReferringDomain",
"InitialUTMSource",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/queries/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1850,6 +1850,7 @@ export enum WebStatsBreakdown {
InitialPage = 'InitialPage',
ExitPage = 'ExitPage', // not supported in the legacy version
ExitClick = 'ExitClick',
ScreenName = 'ScreenName',
InitialChannelType = 'InitialChannelType',
InitialReferringDomain = 'InitialReferringDomain',
InitialUTMSource = 'InitialUTMSource',
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/scenes/web-analytics/tiles/WebAnalyticsTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ const BreakdownValueTitle: QueryContextColumnTitleComponent = (props) => {
return <>End Path</>
case WebStatsBreakdown.ExitClick:
return <>Exit Click</>
case WebStatsBreakdown.ScreenName:
return <>Screen Name</>
case WebStatsBreakdown.InitialChannelType:
return <>Initial Channel Type</>
case WebStatsBreakdown.InitialReferringDomain:
Expand Down Expand Up @@ -258,6 +260,8 @@ export const webStatsBreakdownToPropertyName = (
return { key: '$end_pathname', type: PropertyFilterType.Session }
case WebStatsBreakdown.ExitClick:
return { key: '$last_external_click_url', type: PropertyFilterType.Session }
case WebStatsBreakdown.ScreenName:
return { key: '$screen_name', type: PropertyFilterType.Event }
case WebStatsBreakdown.InitialChannelType:
return { key: '$channel_type', type: PropertyFilterType.Session }
case WebStatsBreakdown.InitialReferringDomain:
Expand Down
302 changes: 157 additions & 145 deletions frontend/src/scenes/web-analytics/webAnalyticsLogic.tsx

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions posthog/hogql_queries/web_analytics/stats_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def to_path_scroll_bounce_query(self) -> ast.SelectQuery:
min(session.$start_timestamp ) AS start_timestamp
FROM events
WHERE and(
events.event == '$pageview',
or(events.event == '$pageview', events.event == '$screen'),
breakdown_value IS NOT NULL,
{inside_periods},
{event_properties},
Expand All @@ -172,7 +172,7 @@ def to_path_scroll_bounce_query(self) -> ast.SelectQuery:
min(session.$start_timestamp) as start_timestamp
FROM events
WHERE and(
events.event == '$pageview',
or(events.event == '$pageview', events.event == '$screen'),
breakdown_value IS NOT NULL,
{inside_periods},
{event_properties},
Expand Down Expand Up @@ -204,7 +204,7 @@ def to_path_scroll_bounce_query(self) -> ast.SelectQuery:
min(session.$start_timestamp) AS start_timestamp
FROM events
WHERE and(
or(events.event == '$pageview', events.event == '$pageleave'),
or(events.event == '$pageview', events.event == '$pageleave', events.event == '$screen'),
breakdown_value IS NOT NULL,
{inside_periods},
{event_properties_for_scroll},
Expand Down Expand Up @@ -263,7 +263,7 @@ def to_path_bounce_query(self) -> ast.SelectQuery:
min(session.$start_timestamp) AS start_timestamp
FROM events
WHERE and(
events.event == '$pageview',
or(events.event == '$pageview', events.event == '$screen'),
{inside_periods},
{event_properties},
{session_properties},
Expand All @@ -286,7 +286,7 @@ def to_path_bounce_query(self) -> ast.SelectQuery:
min(session.$start_timestamp) AS start_timestamp
FROM events
WHERE and(
events.event == '$pageview',
or(events.event == '$pageview', events.event == '$screen'),
breakdown_value IS NOT NULL,
{inside_periods},
{event_properties},
Expand Down Expand Up @@ -481,6 +481,8 @@ def _counts_breakdown_value(self):
return self._apply_path_cleaning(ast.Field(chain=["session", "$end_pathname"]))
case WebStatsBreakdown.EXIT_CLICK:
return ast.Field(chain=["session", "$last_external_click_url"])
case WebStatsBreakdown.SCREEN_NAME:
return ast.Field(chain=["events", "properties", "$screen_name"])
case WebStatsBreakdown.INITIAL_REFERRING_DOMAIN:
return ast.Field(chain=["session", "$entry_referring_domain"])
case WebStatsBreakdown.INITIAL_UTM_SOURCE:
Expand Down
55 changes: 54 additions & 1 deletion posthog/hogql_queries/web_analytics/test/test_web_overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
HogQLQueryModifiers,
CustomEventConversionGoal,
ActionConversionGoal,
BounceRatePageViewMode,
)
from posthog.settings import HOGQL_INCREASED_MAX_EXECUTION_TIME
from posthog.test.base import (
Expand Down Expand Up @@ -79,8 +80,11 @@ def _run_web_overview_query(
action: Optional[Action] = None,
custom_event: Optional[str] = None,
includeLCPScore: Optional[bool] = False,
bounce_rate_mode: Optional[BounceRatePageViewMode] = BounceRatePageViewMode.COUNT_PAGEVIEWS,
):
modifiers = HogQLQueryModifiers(sessionTableVersion=session_table_version)
modifiers = HogQLQueryModifiers(
sessionTableVersion=session_table_version, bounceRatePageViewMode=bounce_rate_mode
)
query = WebOverviewQuery(
dateRange=DateRange(date_from=date_from, date_to=date_to),
properties=[],
Expand Down Expand Up @@ -185,6 +189,55 @@ def test_increase_in_users(self):
self.assertEqual(0, bounce.previous)
self.assertEqual(None, bounce.changeFromPreviousPct)

def test_increase_in_users_using_mobile(self):
s1a = str(uuid7("2023-12-02"))
s1b = str(uuid7("2023-12-12"))
s2 = str(uuid7("2023-12-11"))

self._create_events(
[
("p1", [("2023-12-02", s1a), ("2023-12-03", s1a), ("2023-12-12", s1b)]),
("p2", [("2023-12-11", s2)]),
],
event="$screen",
)

results = self._run_web_overview_query(
"2023-12-08",
"2023-12-15",
bounce_rate_mode=BounceRatePageViewMode.UNIQ_PAGE_SCREEN_AUTOCAPTURES, # bounce rate won't work in the other modes
).results

visitors = results[0]
self.assertEqual("visitors", visitors.key)
self.assertEqual(2, visitors.value)
self.assertEqual(1, visitors.previous)
self.assertEqual(100, visitors.changeFromPreviousPct)

views = results[1]
self.assertEqual("views", views.key)
self.assertEqual(2, views.value)
self.assertEqual(2, views.previous)
self.assertEqual(0, views.changeFromPreviousPct)

sessions = results[2]
self.assertEqual("sessions", sessions.key)
self.assertEqual(2, sessions.value)
self.assertEqual(1, sessions.previous)
self.assertEqual(100, sessions.changeFromPreviousPct)

duration_s = results[3]
self.assertEqual("session duration", duration_s.key)
self.assertEqual(0, duration_s.value)
self.assertEqual(60 * 60 * 24, duration_s.previous)
self.assertEqual(-100, duration_s.changeFromPreviousPct)

bounce = results[4]
self.assertEqual("bounce rate", bounce.key)
self.assertEqual(100, bounce.value)
self.assertEqual(0, bounce.previous)
self.assertEqual(None, bounce.changeFromPreviousPct)

def test_all_time(self):
s1a = str(uuid7("2023-12-02"))
s1b = str(uuid7("2023-12-12"))
Expand Down
34 changes: 33 additions & 1 deletion posthog/hogql_queries/web_analytics/test/test_web_stats_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
HogQLQueryModifiers,
CustomEventConversionGoal,
ActionConversionGoal,
BounceRatePageViewMode,
)
from posthog.test.base import (
APIBaseTest,
Expand Down Expand Up @@ -44,8 +45,11 @@ def _create_events(self, data, event="$pageview"):
for timestamp, session_id, *extra in timestamps:
url = None
elements = None
screen_name = None
if event == "$pageview":
url = extra[0] if extra else None
elif event == "$screen":
screen_name = extra[0] if extra else None
elif event == "$autocapture":
elements = extra[0] if extra else None
properties = extra[1] if extra and len(extra) > 1 else {}
Expand All @@ -59,6 +63,7 @@ def _create_events(self, data, event="$pageview"):
"$session_id": session_id,
"$pathname": url,
"$current_url": url,
"$screen_name": screen_name,
**properties,
},
elements=elements,
Expand Down Expand Up @@ -129,8 +134,11 @@ def _run_web_stats_table_query(
custom_event: Optional[str] = None,
session_table_version: SessionTableVersion = SessionTableVersion.V2,
filter_test_accounts: Optional[bool] = False,
bounce_rate_mode: Optional[BounceRatePageViewMode] = BounceRatePageViewMode.COUNT_PAGEVIEWS,
):
modifiers = HogQLQueryModifiers(sessionTableVersion=session_table_version)
modifiers = HogQLQueryModifiers(
sessionTableVersion=session_table_version, bounceRatePageViewMode=bounce_rate_mode
)
query = WebStatsTableQuery(
dateRange=DateRange(date_from=date_from, date_to=date_to),
properties=properties or [],
Expand Down Expand Up @@ -179,6 +187,30 @@ def test_increase_in_users(self):
results,
)

def test_increase_in_users_on_mobile(self):
s1a = str(uuid7("2023-12-02"))
s1b = str(uuid7("2023-12-13"))
s2 = str(uuid7("2023-12-10"))
self._create_events(
[
("p1", [("2023-12-02", s1a, "Home"), ("2023-12-03", s1a, "Login"), ("2023-12-13", s1b, "Docs")]),
("p2", [("2023-12-10", s2, "Home")]),
],
event="$screen",
)

results = self._run_web_stats_table_query(
"2023-12-01", "2023-12-11", breakdown_by=WebStatsBreakdown.SCREEN_NAME
).results

self.assertEqual(
[
["Home", (2, None), (2, None)],
["Login", (1, None), (1, None)],
],
results,
)

def test_all_time(self):
s1a = str(uuid7("2023-12-02"))
s1b = str(uuid7("2023-12-13"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,15 @@ def conversion_person_id_expr(self) -> Optional[ast.Expr]:

@cached_property
def event_type_expr(self) -> ast.Expr:
pageview_expr = ast.CompareOperation(
op=ast.CompareOperationOp.Eq, left=ast.Field(chain=["event"]), right=ast.Constant(value="$pageview")
pageview_expr = ast.Or(
exprs=[
ast.CompareOperation(
op=ast.CompareOperationOp.Eq, left=ast.Field(chain=["event"]), right=ast.Constant(value="$pageview")
),
ast.CompareOperation(
op=ast.CompareOperationOp.Eq, left=ast.Field(chain=["event"]), right=ast.Constant(value="$screen")
),
]
)

if self.conversion_goal_expr:
Expand Down
2 changes: 1 addition & 1 deletion posthog/hogql_queries/web_analytics/web_goals.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def to_query(self) -> ast.SelectQuery | ast.SelectSetQuery:
FROM events
WHERE and(
events.`$session_id` IS NOT NULL,
event = '$pageview' OR {action_where},
event = '$pageview' OR event = '$screen' OR {action_where},
{periods_expression},
{event_properties},
{session_properties}
Expand Down
17 changes: 13 additions & 4 deletions posthog/hogql_queries/web_analytics/web_overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,19 @@ def pageview_count_expression(self) -> ast.Expr:
return ast.Call(
name="countIf",
args=[
ast.CompareOperation(
left=ast.Field(chain=["event"]),
op=ast.CompareOperationOp.Eq,
right=ast.Constant(value="$pageview"),
ast.Or(
exprs=[
ast.CompareOperation(
left=ast.Field(chain=["event"]),
op=ast.CompareOperationOp.Eq,
right=ast.Constant(value="$pageview"),
),
ast.CompareOperation(
left=ast.Field(chain=["event"]),
op=ast.CompareOperationOp.Eq,
right=ast.Constant(value="$screen"),
),
]
)
],
)
Expand Down
1 change: 1 addition & 0 deletions posthog/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -1717,6 +1717,7 @@ class WebStatsBreakdown(StrEnum):
INITIAL_PAGE = "InitialPage"
EXIT_PAGE = "ExitPage"
EXIT_CLICK = "ExitClick"
SCREEN_NAME = "ScreenName"
INITIAL_CHANNEL_TYPE = "InitialChannelType"
INITIAL_REFERRING_DOMAIN = "InitialReferringDomain"
INITIAL_UTM_SOURCE = "InitialUTMSource"
Expand Down

0 comments on commit da23d14

Please sign in to comment.