aboutsummaryrefslogtreecommitdiff
path: root/scripts/seed/generators/events.ts
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-01-24 13:09:50 +0000
committerFuwn <[email protected]>2026-01-24 13:09:50 +0000
commit396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b (patch)
treeb9df4ca6a70db45cfffbae6fdd7252e20fb8e93c /scripts/seed/generators/events.ts
downloadumami-main.tar.xz
umami-main.zip
Initial commitHEADmain
Created from https://vercel.com/new
Diffstat (limited to 'scripts/seed/generators/events.ts')
-rw-r--r--scripts/seed/generators/events.ts191
1 files changed, 191 insertions, 0 deletions
diff --git a/scripts/seed/generators/events.ts b/scripts/seed/generators/events.ts
new file mode 100644
index 0000000..7242906
--- /dev/null
+++ b/scripts/seed/generators/events.ts
@@ -0,0 +1,191 @@
+import { uuid, addSeconds, randomInt } from '../utils.js';
+import { getRandomReferrer } from '../distributions/referrers.js';
+import type { SessionData } from './sessions.js';
+
+export const EVENT_TYPE = {
+ pageView: 1,
+ customEvent: 2,
+} as const;
+
+export interface PageConfig {
+ path: string;
+ title: string;
+ weight: number;
+ avgTimeOnPage: number;
+}
+
+export interface CustomEventConfig {
+ name: string;
+ weight: number;
+ pages?: string[];
+ data?: Record<string, string[] | number[]>;
+}
+
+export interface JourneyConfig {
+ pages: string[];
+ weight: number;
+}
+
+export interface EventData {
+ id: string;
+ websiteId: string;
+ sessionId: string;
+ visitId: string;
+ eventType: number;
+ urlPath: string;
+ urlQuery: string | null;
+ pageTitle: string | null;
+ hostname: string;
+ referrerDomain: string | null;
+ referrerPath: string | null;
+ utmSource: string | null;
+ utmMedium: string | null;
+ utmCampaign: string | null;
+ utmContent: string | null;
+ utmTerm: string | null;
+ gclid: string | null;
+ fbclid: string | null;
+ eventName: string | null;
+ tag: string | null;
+ createdAt: Date;
+}
+
+export interface EventDataEntry {
+ id: string;
+ websiteId: string;
+ websiteEventId: string;
+ dataKey: string;
+ stringValue: string | null;
+ numberValue: number | null;
+ dateValue: Date | null;
+ dataType: number;
+ createdAt: Date;
+}
+
+export interface SiteConfig {
+ hostname: string;
+ pages: PageConfig[];
+ journeys: JourneyConfig[];
+ customEvents: CustomEventConfig[];
+}
+
+function getPageTitle(pages: PageConfig[], path: string): string | null {
+ const page = pages.find(p => p.path === path);
+ return page?.title ?? null;
+}
+
+function getPageTimeOnPage(pages: PageConfig[], path: string): number {
+ const page = pages.find(p => p.path === path);
+ return page?.avgTimeOnPage ?? 30;
+}
+
+export function generateEventsForSession(
+ session: SessionData,
+ siteConfig: SiteConfig,
+ journey: string[],
+): { events: EventData[]; eventDataEntries: EventDataEntry[] } {
+ const events: EventData[] = [];
+ const eventDataEntries: EventDataEntry[] = [];
+ const visitId = uuid();
+
+ let currentTime = session.createdAt;
+ const referrer = getRandomReferrer();
+
+ for (let i = 0; i < journey.length; i++) {
+ const pagePath = journey[i];
+ const isFirstPage = i === 0;
+
+ const eventId = uuid();
+ const pageTitle = getPageTitle(siteConfig.pages, pagePath);
+
+ events.push({
+ id: eventId,
+ websiteId: session.websiteId,
+ sessionId: session.id,
+ visitId,
+ eventType: EVENT_TYPE.pageView,
+ urlPath: pagePath,
+ urlQuery: null,
+ pageTitle,
+ hostname: siteConfig.hostname,
+ referrerDomain: isFirstPage ? referrer.domain : null,
+ referrerPath: isFirstPage ? referrer.path : null,
+ utmSource: isFirstPage ? referrer.utmSource : null,
+ utmMedium: isFirstPage ? referrer.utmMedium : null,
+ utmCampaign: isFirstPage ? referrer.utmCampaign : null,
+ utmContent: isFirstPage ? referrer.utmContent : null,
+ utmTerm: isFirstPage ? referrer.utmTerm : null,
+ gclid: isFirstPage ? referrer.gclid : null,
+ fbclid: isFirstPage ? referrer.fbclid : null,
+ eventName: null,
+ tag: null,
+ createdAt: currentTime,
+ });
+
+ // Check for custom events on this page
+ for (const customEvent of siteConfig.customEvents) {
+ // Check if this event can occur on this page
+ if (customEvent.pages && !customEvent.pages.includes(pagePath)) {
+ continue;
+ }
+
+ // Random chance based on weight
+ if (Math.random() < customEvent.weight) {
+ currentTime = addSeconds(currentTime, randomInt(2, 15));
+
+ const customEventId = uuid();
+ events.push({
+ id: customEventId,
+ websiteId: session.websiteId,
+ sessionId: session.id,
+ visitId,
+ eventType: EVENT_TYPE.customEvent,
+ urlPath: pagePath,
+ urlQuery: null,
+ pageTitle,
+ hostname: siteConfig.hostname,
+ referrerDomain: null,
+ referrerPath: null,
+ utmSource: null,
+ utmMedium: null,
+ utmCampaign: null,
+ utmContent: null,
+ utmTerm: null,
+ gclid: null,
+ fbclid: null,
+ eventName: customEvent.name,
+ tag: null,
+ createdAt: currentTime,
+ });
+
+ // Generate event data if configured
+ if (customEvent.data) {
+ for (const [key, values] of Object.entries(customEvent.data)) {
+ const value = values[Math.floor(Math.random() * values.length)];
+ const isNumber = typeof value === 'number';
+
+ eventDataEntries.push({
+ id: uuid(),
+ websiteId: session.websiteId,
+ websiteEventId: customEventId,
+ dataKey: key,
+ stringValue: isNumber ? null : String(value),
+ numberValue: isNumber ? value : null,
+ dateValue: null,
+ dataType: isNumber ? 2 : 1, // 1 = string, 2 = number
+ createdAt: currentTime,
+ });
+ }
+ }
+ }
+ }
+
+ // Time spent on page before navigating
+ const timeOnPage = getPageTimeOnPage(siteConfig.pages, pagePath);
+ const variance = Math.floor(timeOnPage * 0.5);
+ const actualTime = timeOnPage + randomInt(-variance, variance);
+ currentTime = addSeconds(currentTime, Math.max(5, actualTime));
+ }
+
+ return { events, eventDataEntries };
+}