Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connect EventTracker to TB endpoint #7240

Merged
merged 14 commits into from
Sep 26, 2024
Merged

Connect EventTracker to TB endpoint #7240

merged 14 commits into from
Sep 26, 2024

Conversation

anamarn
Copy link
Contributor

@anamarn anamarn commented Sep 24, 2024

#7091
EventTrackers send information of events to the TinyBird instance:

In order to test:

  1. Set ANALYTICS_ENABLED= true and TELEMETRY_ENABLED=true in evironment-variables.ts
  2. Set the TINYBIRD_TOKEN in environment variables (go to TiniyBird Tokens)
  3. Log in to twenty's TinyBird and go to datasources/analytics_events in twenty_analytics workspace
  4. Run twenty and navigate it
  5. New events will be logged in the datasources, containing their timestamp, sessionId and payload.
Screenshot 2024-09-24 at 17 23 01 Example of payload when user is not logged in
{"hostName":"localhost",
"pathname":"/welcome",
"locale":"en-US",
"userAgent":"Mozilla/5.0",
"href":"http://localhost:3001/welcome",
"referrer":"",
"timeZone":"Europe/Barcelona"}

Example of payload when user is logged in

{"userId":"2020202",
"workspaceId":"202",
"workspaceDisplayName":"Apple",
"workspaceDomainName":"apple.dev",
"hostName":"localhost",
"pathname":"/objects/companies",
"locale":"en-US",
"userAgent":"Mozilla/5.0Chrome/128.0.0.0Safari/537.36",
"href":"http://localhost:3001/objects/companies",
"referrer":"",
"timeZone":"Europe/Paris"}

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

This PR implements a new analytics system using TinyBird, replacing the previous Cloudflare-based solution. The changes focus on improving data collection and separating cloud analytics from self-hosted telemetry.

  • Added sessionId to analytics tracking in both frontend and backend
  • Introduced ANALYTICS_ENABLED and TINYBIRD_TOKEN environment variables
  • Updated AnalyticsService to use TinyBird's API for event tracking
  • Removed telemetry field from ClientConfig and related components
  • Modified PageChangeEffect to collect more detailed event data

22 file(s) reviewed, 5 comment(s)
Edit PR Review Bot Settings

userAgent: window.navigator.userAgent,
href: window.location.href,
referrer: document.referrer,
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
});
}, 500);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider removing or explaining the 500ms delay

Comment on lines 21 to 27
export const setSessionId = (cookieName: string, domain?: string): void => {
const sessionId = getSessionId(cookieName) || crypto.randomUUID();
const baseCookie = `${cookieName}=${sessionId}; Max-Age=1800; path=/; secure`;
const cookie = domain ? baseCookie + `; domain=${domain}` : baseCookie;

document.cookie = cookie;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Ensure cookie is set with appropriate security flags (HttpOnly, SameSite) to mitigate XSS and CSRF risks

Comment on lines +44 to +45
mutation Track($type: String!, $sessionId: String!, $data: JSON!) {
track(type: $type, sessionId: $sessionId, data: $data) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Track mutation updated to include sessionId, but test data not provided

Comment on lines 32 to 34
if (!this.environmentService.get('ANALYTICS_ENABLED')) {
return { success: true };
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider combining ANALYTICS_ENABLED and TELEMETRY_ENABLED checks to simplify logic

(eventType: string, sessionId: string, eventData: EventData) => {
createEventMutation({
variables: {
type: eventType,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not copy the payload from the example? Here we send pageview event from the frontend but you'll want to track other types of event

version: '1',
session_id: createEventInput.sessionId,
payload: {
userId: userId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If data within the payload is in camelCase (which make sense, it's what we usually use) then you should adapt your tinybird data model to also be in snakeCase (sessionId not session_id)

@@ -25,6 +25,7 @@ export class TelemetryListener {
data: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove type: track and pass action instead with payload.name as its value? eventName isn't part of your schema is it?

@@ -48,6 +49,7 @@ export class TelemetryListener {
data: {
eventName: 'user.signup',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be passed as action?

@@ -48,6 +49,7 @@ export class TelemetryListener {
data: {
eventName: 'user.signup',
},
sessionId: '',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could maybe create a @Session decorator to get the session during signup (from the cookie) and then pass it down to the backend events, the same way we pass userId / workspaceId?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can push this to a later PR

data: object;
};

@Injectable()
export class AnalyticsService {
private readonly logger = new Logger(AnalyticsService.name);
private readonly datasource = 'analytics_events';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also switch everything to camelCase and singular? That's our current convention in our Postgres database

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I see in Tinybird a table with the singular name has already been created, is this used for testing? you can create branch environments for testing if you need to

@FelixMalfait FelixMalfait merged commit 16bb1f2 into main Sep 26, 2024
11 of 16 checks passed
@FelixMalfait FelixMalfait deleted the feat/analytics-v1 branch September 26, 2024 08:53
Copy link

Thanks @anamarn for your contribution!
This marks your 3rd PR on the repo. You're top 12% of all our contributors 🎉
See contributor page - Share on LinkedIn - Share on Twitter

Contributions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants