mirror of
https://github.com/kremalicious/umami.git
synced 2025-02-14 21:10:34 +01:00
Merge pull request #1376 from umami-software/brian/um-24-event-data
Brian/um 24 event data
This commit is contained in:
commit
df1c203c38
@ -12,7 +12,7 @@ export default function EventsChart({ websiteId, className, token }) {
|
|||||||
const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId);
|
const [{ startDate, endDate, unit, modified }] = useDateRange(websiteId);
|
||||||
const [timezone] = useTimezone();
|
const [timezone] = useTimezone();
|
||||||
const {
|
const {
|
||||||
query: { url, eventType },
|
query: { url, eventName },
|
||||||
} = usePageQuery();
|
} = usePageQuery();
|
||||||
|
|
||||||
const { data, loading } = useFetch(
|
const { data, loading } = useFetch(
|
||||||
@ -24,11 +24,11 @@ export default function EventsChart({ websiteId, className, token }) {
|
|||||||
unit,
|
unit,
|
||||||
tz: timezone,
|
tz: timezone,
|
||||||
url,
|
url,
|
||||||
event_type: eventType,
|
event_name: eventName,
|
||||||
token,
|
token,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
[modified, eventType],
|
[modified, eventName],
|
||||||
);
|
);
|
||||||
|
|
||||||
const datasets = useMemo(() => {
|
const datasets = useMemo(() => {
|
||||||
|
@ -92,8 +92,7 @@ export default function RealtimeLog({ data, websites, websiteId }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getDetail({
|
function getDetail({
|
||||||
event_type,
|
event_name,
|
||||||
event_value,
|
|
||||||
view_id,
|
view_id,
|
||||||
session_id,
|
session_id,
|
||||||
url,
|
url,
|
||||||
@ -103,10 +102,10 @@ export default function RealtimeLog({ data, websites, websiteId }) {
|
|||||||
device,
|
device,
|
||||||
website_id,
|
website_id,
|
||||||
}) {
|
}) {
|
||||||
if (event_type) {
|
if (event_name) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Tag>{event_type}</Tag> {event_value}
|
<Tag>{event_name}</Tag>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,8 @@ export default function TestConsole() {
|
|||||||
function handleClick() {
|
function handleClick() {
|
||||||
window.umami('event (default)');
|
window.umami('event (default)');
|
||||||
window.umami.trackView('/page-view', 'https://www.google.com');
|
window.umami.trackView('/page-view', 'https://www.google.com');
|
||||||
window.umami.trackEvent('event (custom)', 'custom-type');
|
window.umami.trackEvent('event (custom)', null, 'custom-type');
|
||||||
|
window.umami.trackEvent('event (custom)', { test: 'test-data' }, 'custom-data-type');
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
62
db/mysql/migrations/02_add_event_data/migration.sql
Normal file
62
db/mysql/migrations/02_add_event_data/migration.sql
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_1`;
|
||||||
|
ALTER TABLE `event` DROP FOREIGN KEY `event_ibfk_2`;
|
||||||
|
|
||||||
|
DROP INDEX `event_created_at_idx` ON `event`;
|
||||||
|
DROP INDEX `event_session_id_idx` ON `event`;
|
||||||
|
DROP INDEX `event_website_id_idx` ON `event`;
|
||||||
|
|
||||||
|
CREATE INDEX `event_old_created_at_idx` ON `event` (created_at);
|
||||||
|
CREATE INDEX `event_old_session_id_idx` ON `event` (session_id);
|
||||||
|
CREATE INDEX `event_old_website_id_idx` ON `event` (website_id);
|
||||||
|
|
||||||
|
-- RenameTable
|
||||||
|
RENAME TABLE `event` TO `_event_old`;
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE `event`
|
||||||
|
(
|
||||||
|
`event_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`website_id` INTEGER UNSIGNED NOT NULL,
|
||||||
|
`session_id` INTEGER UNSIGNED NOT NULL,
|
||||||
|
`created_at` TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||||
|
`url` VARCHAR(500) NOT NULL,
|
||||||
|
`event_name` VARCHAR(50) NOT NULL,
|
||||||
|
|
||||||
|
INDEX `event_created_at_idx`(`created_at`),
|
||||||
|
INDEX `event_session_id_idx`(`session_id`),
|
||||||
|
INDEX `event_website_id_idx`(`website_id`),
|
||||||
|
PRIMARY KEY (`event_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_2` FOREIGN KEY (`session_id`) REFERENCES `session`(`session_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `event` ADD CONSTRAINT `event_ibfk_1` FOREIGN KEY (`website_id`) REFERENCES `website`(`website_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||||
|
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE `event_data` (
|
||||||
|
`event_data_id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||||
|
`event_id` INTEGER UNSIGNED NOT NULL,
|
||||||
|
`event_data` JSON NOT NULL,
|
||||||
|
|
||||||
|
UNIQUE INDEX `event_data_event_id_key`(`event_id`),
|
||||||
|
PRIMARY KEY (`event_data_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE `event_data` ADD CONSTRAINT `event_data_event_id_fkey` FOREIGN KEY (`event_id`) REFERENCES `event`(`event_id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER TABLE `account` RENAME INDEX `username` TO `account_username_key`;
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER TABLE `session` RENAME INDEX `session_uuid` TO `session_session_uuid_key`;
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER TABLE `website` RENAME INDEX `share_id` TO `website_share_id_key`;
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER TABLE `website` RENAME INDEX `website_uuid` TO `website_website_uuid_key`;
|
@ -9,7 +9,7 @@ datasource db {
|
|||||||
|
|
||||||
model account {
|
model account {
|
||||||
user_id Int @id @default(autoincrement()) @db.UnsignedInt
|
user_id Int @id @default(autoincrement()) @db.UnsignedInt
|
||||||
username String @unique(map: "username") @db.VarChar(255)
|
username String @unique() @db.VarChar(255)
|
||||||
password String @db.VarChar(60)
|
password String @db.VarChar(60)
|
||||||
is_admin Boolean @default(false)
|
is_admin Boolean @default(false)
|
||||||
created_at DateTime? @default(now()) @db.Timestamp(0)
|
created_at DateTime? @default(now()) @db.Timestamp(0)
|
||||||
@ -18,21 +18,28 @@ model account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model event {
|
model event {
|
||||||
event_id Int @id @default(autoincrement()) @db.UnsignedInt
|
event_id Int @id @default(autoincrement()) @db.UnsignedInt
|
||||||
website_id Int @db.UnsignedInt
|
website_id Int @db.UnsignedInt
|
||||||
session_id Int @db.UnsignedInt
|
session_id Int @db.UnsignedInt
|
||||||
created_at DateTime? @default(now()) @db.Timestamp(0)
|
created_at DateTime? @default(now()) @db.Timestamp(0)
|
||||||
url String @db.VarChar(500)
|
url String @db.VarChar(500)
|
||||||
event_type String @db.VarChar(50)
|
event_name String @db.VarChar(50)
|
||||||
event_value String @db.VarChar(50)
|
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2")
|
||||||
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_2")
|
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1")
|
||||||
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction, map: "event_ibfk_1")
|
event_data event_data?
|
||||||
|
|
||||||
@@index([created_at])
|
@@index([created_at])
|
||||||
@@index([session_id])
|
@@index([session_id])
|
||||||
@@index([website_id])
|
@@index([website_id])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model event_data {
|
||||||
|
event_data_id Int @id @default(autoincrement())
|
||||||
|
event_id Int @unique @db.UnsignedInt
|
||||||
|
event_data Json
|
||||||
|
event event @relation(fields: [event_id], references: [event_id])
|
||||||
|
}
|
||||||
|
|
||||||
model pageview {
|
model pageview {
|
||||||
view_id Int @id @default(autoincrement()) @db.UnsignedInt
|
view_id Int @id @default(autoincrement()) @db.UnsignedInt
|
||||||
website_id Int @db.UnsignedInt
|
website_id Int @db.UnsignedInt
|
||||||
@ -52,7 +59,7 @@ model pageview {
|
|||||||
|
|
||||||
model session {
|
model session {
|
||||||
session_id Int @id @default(autoincrement()) @db.UnsignedInt
|
session_id Int @id @default(autoincrement()) @db.UnsignedInt
|
||||||
session_uuid String @unique(map: "session_uuid") @db.VarChar(36)
|
session_uuid String @unique() @db.VarChar(36)
|
||||||
website_id Int @db.UnsignedInt
|
website_id Int @db.UnsignedInt
|
||||||
created_at DateTime? @default(now()) @db.Timestamp(0)
|
created_at DateTime? @default(now()) @db.Timestamp(0)
|
||||||
hostname String? @db.VarChar(100)
|
hostname String? @db.VarChar(100)
|
||||||
@ -72,11 +79,11 @@ model session {
|
|||||||
|
|
||||||
model website {
|
model website {
|
||||||
website_id Int @id @default(autoincrement()) @db.UnsignedInt
|
website_id Int @id @default(autoincrement()) @db.UnsignedInt
|
||||||
website_uuid String @unique(map: "website_uuid") @db.VarChar(36)
|
website_uuid String @unique() @db.VarChar(36)
|
||||||
user_id Int @db.UnsignedInt
|
user_id Int @db.UnsignedInt
|
||||||
name String @db.VarChar(100)
|
name String @db.VarChar(100)
|
||||||
domain String? @db.VarChar(500)
|
domain String? @db.VarChar(500)
|
||||||
share_id String? @unique(map: "share_id") @db.VarChar(64)
|
share_id String? @unique() @db.VarChar(64)
|
||||||
created_at DateTime? @default(now()) @db.Timestamp(0)
|
created_at DateTime? @default(now()) @db.Timestamp(0)
|
||||||
account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade, onUpdate: NoAction, map: "website_ibfk_1")
|
account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade, onUpdate: NoAction, map: "website_ibfk_1")
|
||||||
event event[]
|
event event[]
|
||||||
|
66
db/postgresql/migrations/02_add_event_data/migration.sql
Normal file
66
db/postgresql/migrations/02_add_event_data/migration.sql
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
-- DropForeignKey
|
||||||
|
ALTER TABLE "event" DROP CONSTRAINT "event_session_id_fkey";
|
||||||
|
ALTER TABLE "event" DROP CONSTRAINT "event_website_id_fkey";
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER INDEX "event_pkey" RENAME TO "event_old_pkey";
|
||||||
|
ALTER INDEX "event_created_at_idx" RENAME TO "event_old_created_at_idx";
|
||||||
|
ALTER INDEX "event_session_id_idx" RENAME TO "event_old_session_id_idx";
|
||||||
|
ALTER INDEX "event_website_id_idx" RENAME TO "event_old_website_id_idx";
|
||||||
|
|
||||||
|
-- RenameTable
|
||||||
|
ALTER TABLE "event" RENAME TO "_event_old";
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "event" (
|
||||||
|
"event_id" SERIAL NOT NULL,
|
||||||
|
"website_id" INTEGER NOT NULL,
|
||||||
|
"session_id" INTEGER NOT NULL,
|
||||||
|
"created_at" TIMESTAMPTZ(6) DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"url" VARCHAR(500) NOT NULL,
|
||||||
|
"event_name" VARCHAR(50) NOT NULL,
|
||||||
|
|
||||||
|
PRIMARY KEY ("event_id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "event_created_at_idx" ON "event"("created_at");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "event_session_id_idx" ON "event"("session_id");
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE INDEX "event_website_id_idx" ON "event"("website_id");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "event" ADD CONSTRAINT "event_session_id_fkey" FOREIGN KEY ("session_id") REFERENCES "session"("session_id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "event" ADD CONSTRAINT "event_website_id_fkey" FOREIGN KEY ("website_id") REFERENCES "website"("website_id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- CreateTable
|
||||||
|
CREATE TABLE "event_data" (
|
||||||
|
"event_data_id" SERIAL NOT NULL,
|
||||||
|
"event_id" INTEGER NOT NULL,
|
||||||
|
"event_data" JSONB NOT NULL,
|
||||||
|
|
||||||
|
CONSTRAINT "event_data_pkey" PRIMARY KEY ("event_data_id")
|
||||||
|
);
|
||||||
|
|
||||||
|
-- CreateIndex
|
||||||
|
CREATE UNIQUE INDEX "event_data_event_id_key" ON "event_data"("event_id");
|
||||||
|
|
||||||
|
-- AddForeignKey
|
||||||
|
ALTER TABLE "event_data" ADD CONSTRAINT "event_data_event_id_fkey" FOREIGN KEY ("event_id") REFERENCES "event"("event_id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER INDEX "account.username_unique" RENAME TO "account_username_key";
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER INDEX "session.session_uuid_unique" RENAME TO "session_session_uuid_key";
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER INDEX "website.share_id_unique" RENAME TO "website_share_id_key";
|
||||||
|
|
||||||
|
-- RenameIndex
|
||||||
|
ALTER INDEX "website.website_uuid_unique" RENAME TO "website_website_uuid_key";
|
@ -18,21 +18,28 @@ model account {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model event {
|
model event {
|
||||||
event_id Int @id @default(autoincrement())
|
event_id Int @id @default(autoincrement())
|
||||||
website_id Int
|
website_id Int
|
||||||
session_id Int
|
session_id Int
|
||||||
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
||||||
url String @db.VarChar(500)
|
url String @db.VarChar(500)
|
||||||
event_type String @db.VarChar(50)
|
event_name String @db.VarChar(50)
|
||||||
event_value String @db.VarChar(50)
|
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade)
|
||||||
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction)
|
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
|
||||||
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction)
|
event_data event_data?
|
||||||
|
|
||||||
@@index([created_at])
|
@@index([created_at])
|
||||||
@@index([session_id])
|
@@index([session_id])
|
||||||
@@index([website_id])
|
@@index([website_id])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model event_data {
|
||||||
|
event_data_id Int @id @default(autoincrement())
|
||||||
|
event_id Int @unique
|
||||||
|
event_data Json
|
||||||
|
event event @relation(fields: [event_id], references: [event_id])
|
||||||
|
}
|
||||||
|
|
||||||
model pageview {
|
model pageview {
|
||||||
view_id Int @id @default(autoincrement())
|
view_id Int @id @default(autoincrement())
|
||||||
website_id Int
|
website_id Int
|
||||||
@ -40,8 +47,8 @@ model pageview {
|
|||||||
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
||||||
url String @db.VarChar(500)
|
url String @db.VarChar(500)
|
||||||
referrer String? @db.VarChar(500)
|
referrer String? @db.VarChar(500)
|
||||||
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade, onUpdate: NoAction)
|
session session @relation(fields: [session_id], references: [session_id], onDelete: Cascade)
|
||||||
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction)
|
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
|
||||||
|
|
||||||
@@index([created_at])
|
@@index([created_at])
|
||||||
@@index([session_id])
|
@@index([session_id])
|
||||||
@ -58,13 +65,13 @@ model session {
|
|||||||
hostname String? @db.VarChar(100)
|
hostname String? @db.VarChar(100)
|
||||||
browser String? @db.VarChar(20)
|
browser String? @db.VarChar(20)
|
||||||
os String? @db.VarChar(20)
|
os String? @db.VarChar(20)
|
||||||
|
device String? @db.VarChar(20)
|
||||||
screen String? @db.VarChar(11)
|
screen String? @db.VarChar(11)
|
||||||
language String? @db.VarChar(35)
|
language String? @db.VarChar(35)
|
||||||
country String? @db.Char(2)
|
country String? @db.Char(2)
|
||||||
device String? @db.VarChar(20)
|
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade)
|
||||||
website website @relation(fields: [website_id], references: [website_id], onDelete: Cascade, onUpdate: NoAction)
|
|
||||||
event event[]
|
|
||||||
pageview pageview[]
|
pageview pageview[]
|
||||||
|
event event[]
|
||||||
|
|
||||||
@@index([created_at])
|
@@index([created_at])
|
||||||
@@index([website_id])
|
@@index([website_id])
|
||||||
@ -73,15 +80,15 @@ model session {
|
|||||||
model website {
|
model website {
|
||||||
website_id Int @id @default(autoincrement())
|
website_id Int @id @default(autoincrement())
|
||||||
website_uuid String @unique @db.Uuid
|
website_uuid String @unique @db.Uuid
|
||||||
name String @db.VarChar(100)
|
|
||||||
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
|
||||||
user_id Int
|
user_id Int
|
||||||
|
name String @db.VarChar(100)
|
||||||
domain String? @db.VarChar(500)
|
domain String? @db.VarChar(500)
|
||||||
share_id String? @unique(map: "website_share_id_idx") @db.VarChar(64)
|
share_id String? @unique @db.VarChar(64)
|
||||||
account account @relation(fields: [user_id], references: [user_id], onDelete: NoAction, onUpdate: NoAction)
|
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
||||||
event event[]
|
account account @relation(fields: [user_id], references: [user_id], onDelete: Cascade)
|
||||||
pageview pageview[]
|
pageview pageview[]
|
||||||
session session[]
|
session session[]
|
||||||
|
event event[]
|
||||||
|
|
||||||
@@index([user_id])
|
@@index([user_id])
|
||||||
}
|
}
|
||||||
|
@ -182,7 +182,7 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'event_type':
|
case 'event_name':
|
||||||
if (table === 'event') {
|
if (table === 'event') {
|
||||||
arr.push(`and ${table}.${key}=$${params.length + 1}`);
|
arr.push(`and ${table}.${key}=$${params.length + 1}`);
|
||||||
params.push(decodeURIComponent(filter));
|
params.push(decodeURIComponent(filter));
|
||||||
@ -212,17 +212,17 @@ export function getFilterQuery(table, column, filters = {}, params = []) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function parseFilters(table, column, filters = {}, params = [], sessionKey = 'session_id') {
|
export function parseFilters(table, column, filters = {}, params = [], sessionKey = 'session_id') {
|
||||||
const { domain, url, event_url, referrer, os, browser, device, country, event_type } = filters;
|
const { domain, url, event_url, referrer, os, browser, device, country, event_name } = filters;
|
||||||
|
|
||||||
const pageviewFilters = { domain, url, referrer };
|
const pageviewFilters = { domain, url, referrer };
|
||||||
const sessionFilters = { os, browser, device, country };
|
const sessionFilters = { os, browser, device, country };
|
||||||
const eventFilters = { url: event_url, event_type };
|
const eventFilters = { url: event_url, event_name };
|
||||||
|
|
||||||
return {
|
return {
|
||||||
pageviewFilters,
|
pageviewFilters,
|
||||||
sessionFilters,
|
sessionFilters,
|
||||||
eventFilters,
|
eventFilters,
|
||||||
event: { event_type },
|
event: { event_name },
|
||||||
joinSession:
|
joinSession:
|
||||||
os || browser || device || country
|
os || browser || device || country
|
||||||
? `inner join session on ${table}.${sessionKey} = session.${sessionKey}`
|
? `inner join session on ${table}.${sessionKey} = session.${sessionKey}`
|
||||||
|
@ -65,7 +65,7 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
const { type, payload } = getJsonBody(req);
|
const { type, payload } = getJsonBody(req);
|
||||||
|
|
||||||
let { url, referrer, event_type, event_value } = payload;
|
let { url, referrer, event_name, event_data } = payload;
|
||||||
|
|
||||||
if (process.env.REMOVE_TRAILING_SLASH) {
|
if (process.env.REMOVE_TRAILING_SLASH) {
|
||||||
url = removeTrailingSlash(url);
|
url = removeTrailingSlash(url);
|
||||||
@ -74,7 +74,7 @@ export default async (req, res) => {
|
|||||||
if (type === 'pageview') {
|
if (type === 'pageview') {
|
||||||
await savePageView(website_id, { session_id, session_uuid, url, referrer });
|
await savePageView(website_id, { session_id, session_uuid, url, referrer });
|
||||||
} else if (type === 'event') {
|
} else if (type === 'event') {
|
||||||
await saveEvent(website_id, { session_id, session_uuid, url, event_type, event_value });
|
await saveEvent(website_id, { session_id, session_uuid, url, event_name, event_data });
|
||||||
} else {
|
} else {
|
||||||
return badRequest(res);
|
return badRequest(res);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ export default async (req, res) => {
|
|||||||
return unauthorized(res);
|
return unauthorized(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { id, start_at, end_at, unit, tz, url, event_type } = req.query;
|
const { id, start_at, end_at, unit, tz, url, event_name } = req.query;
|
||||||
|
|
||||||
if (!moment.tz.zone(tz) || !unitTypes.includes(unit)) {
|
if (!moment.tz.zone(tz) || !unitTypes.includes(unit)) {
|
||||||
return badRequest(res);
|
return badRequest(res);
|
||||||
@ -26,7 +26,7 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
const events = await getEventMetrics(websiteId, startDate, endDate, tz, unit, {
|
const events = await getEventMetrics(websiteId, startDate, endDate, tz, unit, {
|
||||||
url,
|
url,
|
||||||
event_type,
|
event_name,
|
||||||
});
|
});
|
||||||
|
|
||||||
return ok(res, events);
|
return ok(res, events);
|
||||||
|
@ -22,7 +22,7 @@ function getTable(type) {
|
|||||||
|
|
||||||
function getColumn(type) {
|
function getColumn(type) {
|
||||||
if (type === 'event') {
|
if (type === 'event') {
|
||||||
return `concat(event_type, '\t', event_value)`;
|
return `event_name`;
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ async function relationalQuery(
|
|||||||
return rawQuery(
|
return rawQuery(
|
||||||
`
|
`
|
||||||
select
|
select
|
||||||
event_value x,
|
event_name x,
|
||||||
${getDateQuery('created_at', unit, timezone)} t,
|
${getDateQuery('created_at', unit, timezone)} t,
|
||||||
count(*) y
|
count(*) y
|
||||||
from event
|
from event
|
||||||
|
@ -40,7 +40,7 @@ function clickhouseQuery(websites, start_at) {
|
|||||||
session_id,
|
session_id,
|
||||||
created_at,
|
created_at,
|
||||||
url,
|
url,
|
||||||
event_type
|
event_name
|
||||||
from event
|
from event
|
||||||
where website_id in (${websites.join[',']}
|
where website_id in (${websites.join[',']}
|
||||||
and created_at >= ${getDateFormatClickhouse(start_at)})
|
and created_at >= ${getDateFormatClickhouse(start_at)})
|
||||||
|
@ -14,33 +14,36 @@ export async function saveEvent(...args) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function relationalQuery(website_id, { session_id, url, event_type, event_value }) {
|
async function relationalQuery(website_id, { session_id, url, event_name, event_data }) {
|
||||||
|
const data = {
|
||||||
|
website_id,
|
||||||
|
session_id,
|
||||||
|
url: url?.substr(0, URL_LENGTH),
|
||||||
|
event_name: event_name?.substr(0, 50),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (event_data) {
|
||||||
|
data.event_data = {
|
||||||
|
create: {
|
||||||
|
event_data: event_data,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return runQuery(
|
return runQuery(
|
||||||
prisma.event.create({
|
prisma.event.create({
|
||||||
data: {
|
data,
|
||||||
website_id,
|
|
||||||
session_id,
|
|
||||||
url: url?.substr(0, URL_LENGTH),
|
|
||||||
event_type: event_type?.substr(0, 50),
|
|
||||||
event_value: event_value?.substr(0, 50),
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function clickhouseQuery(website_id, { session_uuid, url, event_type, event_value }) {
|
async function clickhouseQuery(website_id, { session_uuid, url, event_name }) {
|
||||||
const params = [
|
const params = [website_id, session_uuid, url?.substr(0, URL_LENGTH), event_name?.substr(0, 50)];
|
||||||
website_id,
|
|
||||||
session_uuid,
|
|
||||||
url?.substr(0, URL_LENGTH),
|
|
||||||
event_type?.substr(0, 50),
|
|
||||||
event_value?.substr(0, 50),
|
|
||||||
];
|
|
||||||
|
|
||||||
return rawQueryClickhouse(
|
return rawQueryClickhouse(
|
||||||
`
|
`
|
||||||
insert into umami_dev.event (created_at, website_id, session_uuid, url, event_type, event_value)
|
insert into umami_dev.event (created_at, website_id, session_uuid, url, event_name)
|
||||||
values (${getDateFormatClickhouse(new Date())}, $1, $2, $3, $4, $5);`,
|
values (${getDateFormatClickhouse(new Date())}, $1, $2, $3, $4);`,
|
||||||
params,
|
params,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,17 @@ async function checkMigrations() {
|
|||||||
const output = await run('prisma', ['migrate', 'status']);
|
const output = await run('prisma', ['migrate', 'status']);
|
||||||
|
|
||||||
const missingMigrations = output.includes('have not yet been applied');
|
const missingMigrations = output.includes('have not yet been applied');
|
||||||
|
const missingInitialMigration = output.includes('01_init');
|
||||||
const notManaged = output.includes('The current database is not managed');
|
const notManaged = output.includes('The current database is not managed');
|
||||||
|
|
||||||
if (notManaged || missingMigrations) {
|
if (notManaged || missingMigrations) {
|
||||||
console.log('Running update...');
|
console.log('Running update...');
|
||||||
|
|
||||||
console.log(execSync('prisma migrate resolve --applied "01_init"').toString());
|
if (missingInitialMigration) {
|
||||||
|
console.log(execSync('prisma migrate resolve --applied "01_init"').toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(execSync('prisma migrate deploy').toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
success('Database is up to date.');
|
success('Database is up to date.');
|
||||||
|
@ -97,25 +97,24 @@ import { removeTrailingSlash } from '../lib/url';
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const trackEvent = (event_value, event_type = 'custom', url = currentUrl, uuid = website) => {
|
const trackEvent = (event_name = 'custom', event_data, url = currentUrl, uuid = website) => {
|
||||||
collect(
|
collect(
|
||||||
'event',
|
'event',
|
||||||
assign(getPayload(), {
|
assign(getPayload(), {
|
||||||
website: uuid,
|
website: uuid,
|
||||||
url,
|
url,
|
||||||
event_type,
|
event_name,
|
||||||
event_value,
|
event_data,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Handle events */
|
/* Handle events */
|
||||||
|
|
||||||
const sendEvent = (value, type) => {
|
const sendEvent = name => {
|
||||||
const payload = getPayload();
|
const payload = getPayload();
|
||||||
|
|
||||||
payload.event_type = type;
|
payload.event_name = name;
|
||||||
payload.event_value = value;
|
|
||||||
|
|
||||||
const data = JSON.stringify({
|
const data = JSON.stringify({
|
||||||
type: 'event',
|
type: 'event',
|
||||||
@ -138,14 +137,15 @@ import { removeTrailingSlash } from '../lib/url';
|
|||||||
(element.getAttribute('class') || '').split(' ').forEach(className => {
|
(element.getAttribute('class') || '').split(' ').forEach(className => {
|
||||||
if (!eventClass.test(className)) return;
|
if (!eventClass.test(className)) return;
|
||||||
|
|
||||||
const [, type, value] = className.split('--');
|
const [, type, name] = className.split('--');
|
||||||
|
|
||||||
const listener = listeners[className]
|
const listener = listeners[className]
|
||||||
? listeners[className]
|
? listeners[className]
|
||||||
: (listeners[className] = () => {
|
: (listeners[className] = () => {
|
||||||
if (element.tagName === 'A') {
|
if (element.tagName === 'A') {
|
||||||
sendEvent(value, type);
|
sendEvent(name);
|
||||||
} else {
|
} else {
|
||||||
trackEvent(value, type);
|
trackEvent(name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user