Skip to content

Commit c5cae77

Browse files
authored
add telemetry scripts (#34)
1 parent 5b5479a commit c5cae77

File tree

7 files changed

+327
-0
lines changed

7 files changed

+327
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""Telemetry blocks for the Reflex UI library."""
2+
3+
from .clearbit import get_clearbit_trackers
4+
from .common_room import get_common_room_trackers, identify_common_room_user
5+
from .google import get_google_analytics_trackers
6+
from .koala import get_koala_trackers
7+
from .posthog import get_posthog_trackers
8+
from .rb2b import get_rb2b_trackers
9+
10+
__all__ = [
11+
"get_clearbit_trackers",
12+
"get_common_room_trackers",
13+
"get_google_analytics_trackers",
14+
"get_koala_trackers",
15+
"get_posthog_trackers",
16+
"get_rb2b_trackers",
17+
"identify_common_room_user",
18+
]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""Clearbit analytics tracking integration for Reflex applications."""
2+
3+
import reflex as rx
4+
5+
CLEARBIT_SCRIPT_URL_TEMPLATE: str = (
6+
"https://tag.clearbitscripts.com/v1/{public_key}/tags.js"
7+
)
8+
9+
10+
def get_clearbit_trackers(public_key: str) -> rx.Component:
11+
"""Generate Clearbit tracking component for a Reflex application.
12+
13+
Args:
14+
public_key: Clearbit public key (defaults to app's public key)
15+
16+
Returns:
17+
rx.Component: Script component needed for Clearbit tracking
18+
"""
19+
return rx.el.script(
20+
src=CLEARBIT_SCRIPT_URL_TEMPLATE.format(public_key=public_key),
21+
referrer_policy="strict-origin-when-cross-origin",
22+
)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""Common Room website visitor tracking integration for Reflex applications."""
2+
3+
import json
4+
5+
import reflex as rx
6+
7+
# Common Room tracking configuration
8+
COMMON_ROOM_CDN_URL_TEMPLATE: str = (
9+
"https://cdn.cr-relay.com/v1/site/{site_id}/signals.js"
10+
)
11+
12+
# Common Room tracking script template
13+
COMMON_ROOM_SCRIPT_TEMPLATE: str = """
14+
(function() {{
15+
if (typeof window === 'undefined') return;
16+
if (typeof window.signals !== 'undefined') return;
17+
var script = document.createElement('script');
18+
script.src = '{cdn_url}';
19+
script.async = true;
20+
window.signals = Object.assign(
21+
[],
22+
['page', 'identify', 'form', 'track'].reduce(function (acc, method) {{
23+
acc[method] = function () {{
24+
signals.push([method, arguments]);
25+
return signals;
26+
}};
27+
return acc;
28+
}}, {{}})
29+
);
30+
document.head.appendChild(script);
31+
}})();
32+
"""
33+
34+
35+
def get_common_room_trackers(site_id: str) -> rx.Component:
36+
"""Generate Common Room tracking component for a Reflex application.
37+
38+
Args:
39+
site_id: Your Common Room site ID (found in your tracking snippet)
40+
41+
Returns:
42+
rx.Component: Script component needed for Common Room tracking
43+
"""
44+
cdn_url = COMMON_ROOM_CDN_URL_TEMPLATE.format(site_id=site_id)
45+
46+
return rx.script(COMMON_ROOM_SCRIPT_TEMPLATE.format(cdn_url=cdn_url))
47+
48+
49+
def identify_common_room_user(
50+
email: str, name: str | None = None
51+
) -> rx.event.EventSpec:
52+
"""Identify a user in Common Room analytics after form submission or login.
53+
54+
This should be called when you have user identity information available,
55+
such as after a form submission or user login.
56+
57+
Args:
58+
email: User's email address
59+
name: User's full name (optional)
60+
61+
Returns:
62+
rx.Component: Script component that identifies the user in Common Room
63+
"""
64+
identify_data = {"email": email}
65+
if name:
66+
identify_data["name"] = name
67+
68+
js_data = json.dumps(identify_data)
69+
70+
return rx.call_script(
71+
f"""
72+
// Identify user in Common Room after form submission or login
73+
if (typeof window.signals !== 'undefined' && window.signals.identify) {{
74+
window.signals.identify({js_data});
75+
}}
76+
"""
77+
)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""Google Analytics tracking integration for Reflex applications."""
2+
3+
import reflex as rx
4+
5+
# Google Tag Manager script template
6+
GTAG_SCRIPT_TEMPLATE: str = """
7+
window.dataLayer = window.dataLayer || [];
8+
function gtag() {{
9+
window.dataLayer.push(arguments);
10+
}}
11+
gtag('js', new Date());
12+
gtag('config', '{tracking_id}');
13+
"""
14+
15+
# Google Tag Manager script URL template
16+
GTAG_SCRIPT_URL_TEMPLATE: str = (
17+
"https://www.googletagmanager.com/gtag/js?id={tracking_id}"
18+
)
19+
20+
21+
def get_google_analytics_trackers(
22+
tracking_id: str,
23+
) -> list[rx.Component]:
24+
"""Generate Google Analytics tracking components for a Reflex application.
25+
26+
Args:
27+
tracking_id: Google Analytics tracking ID (defaults to app's tracking ID)
28+
29+
Returns:
30+
list[rx.Component]: Script components needed for Google Analytics tracking
31+
"""
32+
# Load Google Tag Manager script
33+
return [
34+
rx.script(src=GTAG_SCRIPT_URL_TEMPLATE.format(tracking_id=tracking_id)),
35+
rx.script(GTAG_SCRIPT_TEMPLATE.format(tracking_id=tracking_id)),
36+
]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""Koala analytics tracking integration for Reflex applications."""
2+
3+
import reflex as rx
4+
5+
# Koala tracking configuration
6+
KOALA_SCRIPT_URL_TEMPLATE: str = "https://cdn.getkoala.com/v1/{public_api_key}/sdk.js"
7+
8+
# Koala initialization script template
9+
KOALA_SCRIPT_TEMPLATE: str = """
10+
!function(t) {{
11+
if (window.ko) return;
12+
window.ko = [];
13+
[
14+
"identify",
15+
"track",
16+
"removeListeners",
17+
"on",
18+
"off",
19+
"qualify",
20+
"ready"
21+
].forEach(function(t) {{
22+
ko[t] = function() {{
23+
var n = [].slice.call(arguments);
24+
return n.unshift(t), ko.push(n), ko;
25+
}};
26+
}});
27+
var n = document.createElement("script");
28+
n.async = !0;
29+
n.setAttribute("src", "{script_url}");
30+
(document.body || document.head).appendChild(n);
31+
}}();
32+
"""
33+
34+
35+
def get_koala_trackers(public_api_key: str) -> rx.Component:
36+
"""Generate Koala tracking component for a Reflex application.
37+
38+
Args:
39+
public_api_key: Koala public API key
40+
41+
Returns:
42+
rx.Component: Script component needed for Koala tracking
43+
"""
44+
script_url = KOALA_SCRIPT_URL_TEMPLATE.format(public_api_key=public_api_key)
45+
46+
return rx.script(KOALA_SCRIPT_TEMPLATE.format(script_url=script_url))
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""PostHog analytics tracking integration for Reflex applications."""
2+
3+
import json
4+
5+
import reflex as rx
6+
7+
# PostHog tracking configuration
8+
POSTHOG_API_HOST: str = "https://us.i.posthog.com"
9+
10+
# PostHog initialization script template
11+
POSTHOG_SCRIPT_TEMPLATE: str = """
12+
!function(t,e){{
13+
var o,n,p,r;
14+
e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){{
15+
function g(t,e){{
16+
var o=e.split(".");
17+
2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){{
18+
t.push([e].concat(Array.prototype.slice.call(arguments,0)))
19+
}}
20+
}}
21+
(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);
22+
var u=e;
23+
for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){{
24+
var e="posthog";
25+
return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e
26+
}},u.people.toString=function(){{
27+
return u.toString(1)+".people (stub)"
28+
}},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId setPersonProperties".split(" "),n=0;n<o.length;n++)g(u,o[n]);
29+
e._i.push([i,s,a])
30+
}},e.__SV=1)
31+
}}(document,window.posthog||[]);
32+
33+
posthog.init('{project_id}', {{
34+
api_host: '{api_host}',
35+
person_profiles: 'always',
36+
session_recording: {{
37+
recordCrossOriginIframes: true,
38+
}}
39+
}});
40+
"""
41+
42+
43+
def identify_posthog_user(user_id: str) -> rx.event.EventSpec:
44+
"""Identify a user in PostHog analytics.
45+
46+
Args:
47+
user_id: Unique identifier for the user
48+
49+
Returns:
50+
rx.event.EventSpec: Event specification for identifying the user in PostHog
51+
"""
52+
user_id = json.dumps(user_id)
53+
54+
return rx.call_script(
55+
f"""
56+
if (typeof posthog !== 'undefined') {{
57+
posthog.identify({user_id});
58+
}}
59+
"""
60+
)
61+
62+
63+
def get_posthog_trackers(
64+
project_id: str,
65+
api_host: str = POSTHOG_API_HOST,
66+
) -> rx.Component:
67+
"""Generate PostHog tracking component for a Reflex application.
68+
69+
Args:
70+
project_id: PostHog project ID (defaults to app's project ID)
71+
api_host: PostHog API host URL (defaults to US instance)
72+
73+
Returns:
74+
rx.Component: Script component needed for PostHog tracking
75+
"""
76+
return rx.script(
77+
POSTHOG_SCRIPT_TEMPLATE.format(
78+
project_id=project_id,
79+
api_host=api_host,
80+
)
81+
)

reflex_ui/blocks/telemetry/rb2b.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""RB2B (Reveal Bot to Bot) analytics tracking integration for Reflex applications."""
2+
3+
import reflex as rx
4+
5+
# RB2B tracking script template
6+
RB2B_SCRIPT_TEMPLATE: str = """
7+
!function () {{
8+
var reb2b = window.reb2b = window.reb2b || [];
9+
if (reb2b.invoked) return;
10+
reb2b.invoked = true;
11+
reb2b.methods = ["identify", "collect"];
12+
reb2b.factory = function (method) {{
13+
return function () {{
14+
var args = Array.prototype.slice.call(arguments);
15+
args.unshift(method);
16+
reb2b.push(args);
17+
return reb2b;
18+
}};
19+
}};
20+
for (var i = 0; i < reb2b.methods.length; i++) {{
21+
var key = reb2b.methods[i];
22+
reb2b[key] = reb2b.factory(key);
23+
}}
24+
reb2b.load = function (key) {{
25+
var script = document.createElement("script");
26+
script.type = "text/javascript";
27+
script.async = true;
28+
script.src = "https://s3-us-west-2.amazonaws.com/b2bjsstore/b/" + key + "/reb2b.js.gz";
29+
var first = document.getElementsByTagName("script")[0];
30+
first.parentNode.insertBefore(script, first);
31+
}};
32+
reb2b.SNIPPET_VERSION = "1.0.1";
33+
reb2b.load("{api_key}");
34+
}}();
35+
"""
36+
37+
38+
def get_rb2b_trackers(api_key: str) -> rx.Component:
39+
"""Generate RB2B tracking component for a Reflex application.
40+
41+
Args:
42+
api_key: Your RB2B API key (found in your RB2B dashboard)
43+
44+
Returns:
45+
rx.Component: Script component needed for RB2B tracking
46+
"""
47+
return rx.script(RB2B_SCRIPT_TEMPLATE.format(api_key=api_key))

0 commit comments

Comments
 (0)