feat: telemetry add workspaceId and eventName
This commit is contained in:
parent
bd15e47765
commit
66f713e8f6
@ -106,7 +106,6 @@ model WebsiteEvent {
|
||||
id String @id() @default(uuid()) @db.Uuid
|
||||
websiteId String @db.Uuid
|
||||
sessionId String @db.Uuid
|
||||
createdAt DateTime? @default(now()) @db.Timestamptz(6)
|
||||
urlPath String @db.VarChar(500)
|
||||
urlQuery String? @db.VarChar(500)
|
||||
referrerPath String? @db.VarChar(500)
|
||||
@ -115,6 +114,7 @@ model WebsiteEvent {
|
||||
pageTitle String? @db.VarChar(500)
|
||||
eventType Int @default(1) @db.Integer
|
||||
eventName String? @db.VarChar(50)
|
||||
createdAt DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
eventData WebsiteEventData[]
|
||||
session WebsiteSession @relation(fields: [sessionId], references: [id])
|
||||
@ -173,6 +173,7 @@ model WebsiteSessionData {
|
||||
|
||||
model TelemetrySession {
|
||||
id String @id @unique @db.Uuid
|
||||
workspaceId String @db.Uuid
|
||||
hostname String? @db.VarChar(100)
|
||||
browser String? @db.VarChar(20)
|
||||
os String? @db.VarChar(20)
|
||||
@ -185,17 +186,22 @@ model TelemetrySession {
|
||||
telemetryEvent TelemetryEvent[]
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([workspaceId, createdAt])
|
||||
}
|
||||
|
||||
model TelemetryEvent {
|
||||
id String @id() @default(uuid()) @db.Uuid
|
||||
sessionId String @db.Uuid
|
||||
createdAt DateTime? @default(now()) @db.Timestamptz(6)
|
||||
urlOrigin String @db.VarChar(500)
|
||||
urlPath String @db.VarChar(500)
|
||||
id String @id() @default(uuid()) @db.Uuid
|
||||
sessionId String @db.Uuid
|
||||
workspaceId String @db.Uuid
|
||||
eventName String? @db.VarChar(100)
|
||||
urlOrigin String @db.VarChar(500)
|
||||
urlPath String @db.VarChar(500)
|
||||
createdAt DateTime? @default(now()) @db.Timestamptz(6)
|
||||
|
||||
session TelemetrySession @relation(fields: [sessionId], references: [id])
|
||||
|
||||
@@index([createdAt])
|
||||
@@index([sessionId])
|
||||
@@index([workspaceId])
|
||||
@@index([workspaceId, createdAt])
|
||||
}
|
||||
|
@ -9,17 +9,25 @@ export async function recordTelemetryEvent(req: Request) {
|
||||
if (!(url && typeof url === 'string')) {
|
||||
return;
|
||||
}
|
||||
const eventName = req.query.name ? String(req.query.name) : undefined;
|
||||
|
||||
const session = await findSession(req, url);
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workspaceId = req.params.workspaceId;
|
||||
if (!workspaceId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { origin, pathname } = new URL(url);
|
||||
|
||||
await prisma.telemetryEvent.create({
|
||||
data: {
|
||||
sessionId: session.id,
|
||||
workspaceId,
|
||||
eventName,
|
||||
urlOrigin: origin,
|
||||
urlPath: pathname,
|
||||
},
|
||||
@ -32,10 +40,19 @@ export async function sumTelemetryEvent(req: Request): Promise<number> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const eventName = req.query.name ? String(req.query.name) : undefined;
|
||||
|
||||
const workspaceId = req.params.workspaceId;
|
||||
if (!workspaceId) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const { origin, pathname } = new URL(url);
|
||||
|
||||
const number = await prisma.telemetryEvent.count({
|
||||
where: {
|
||||
workspaceId,
|
||||
eventName,
|
||||
urlOrigin: origin,
|
||||
urlPath: pathname,
|
||||
},
|
||||
@ -46,6 +63,10 @@ export async function sumTelemetryEvent(req: Request): Promise<number> {
|
||||
|
||||
async function findSession(req: Request, url: string) {
|
||||
const { hostname } = new URL(url);
|
||||
const workspaceId = req.params.workspaceId;
|
||||
if (!workspaceId) {
|
||||
throw new Error('Not found workspaceId');
|
||||
}
|
||||
|
||||
const {
|
||||
userAgent,
|
||||
@ -58,7 +79,7 @@ async function findSession(req: Request, url: string) {
|
||||
city,
|
||||
} = await getRequestInfo(req);
|
||||
|
||||
const sessionId = hashUuid(hostname, ip, userAgent!);
|
||||
const sessionId = hashUuid(workspaceId, hostname, ip, userAgent!);
|
||||
|
||||
let session = await loadSession(sessionId);
|
||||
if (!session) {
|
||||
@ -66,6 +87,7 @@ async function findSession(req: Request, url: string) {
|
||||
session = await prisma.telemetrySession.create({
|
||||
data: {
|
||||
id: sessionId,
|
||||
workspaceId,
|
||||
hostname,
|
||||
browser,
|
||||
os,
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { prisma } from './_client';
|
||||
import { QueryFilters, parseFilters, getDateQuery } from '../utils/prisma';
|
||||
import { DEFAULT_RESET_DATE, EVENT_TYPE } from '../utils/const';
|
||||
import { Prisma } from '@prisma/client';
|
||||
|
||||
export async function getWorkspaceUser(workspaceId: string, userId: string) {
|
||||
const info = await prisma.workspacesOnUsers.findFirst({
|
||||
@ -27,6 +26,14 @@ export async function checkIsWorkspaceUser(
|
||||
}
|
||||
}
|
||||
|
||||
export async function getWorkspace(workspaceId: string) {
|
||||
return prisma.workspace.findUnique({
|
||||
where: {
|
||||
id: workspaceId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function getWorkspaceWebsites(workspaceId: string) {
|
||||
const workspace = await prisma.workspace.findUnique({
|
||||
where: {
|
||||
|
@ -1,42 +1,57 @@
|
||||
import { Router } from 'express';
|
||||
import { query, validate } from '../middleware/validate';
|
||||
import { recordTelemetryEvent, sumTelemetryEvent } from '../model/telemetry';
|
||||
import { numify } from '../utils/common';
|
||||
const openBadge = require('openbadge');
|
||||
|
||||
export const telemetryRouter = Router();
|
||||
|
||||
telemetryRouter.get('/blank.gif', async (req, res) => {
|
||||
const buffer = Buffer.from(
|
||||
'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
|
||||
'base64'
|
||||
);
|
||||
|
||||
recordTelemetryEvent(req);
|
||||
|
||||
res.header('Content-Type', 'image/gif').send(buffer);
|
||||
});
|
||||
|
||||
telemetryRouter.get('/badge.svg', async (req, res) => {
|
||||
const title = req.query.title || 'visitor';
|
||||
const start = req.query.start ? Number(req.query.start) : 0;
|
||||
|
||||
recordTelemetryEvent(req);
|
||||
const num = await sumTelemetryEvent(req);
|
||||
|
||||
const svg = await new Promise((resolve, reject) => {
|
||||
openBadge(
|
||||
{
|
||||
text: [title, numify(num + start)],
|
||||
},
|
||||
(err: any, badgeSvg: string) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(badgeSvg);
|
||||
}
|
||||
}
|
||||
telemetryRouter.get(
|
||||
'/:workspaceId/blank.gif',
|
||||
validate(
|
||||
query('name').optional().isString(),
|
||||
query('url').optional().isURL()
|
||||
),
|
||||
async (req, res) => {
|
||||
const buffer = Buffer.from(
|
||||
'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
|
||||
'base64'
|
||||
);
|
||||
});
|
||||
|
||||
res.header('Content-Type', 'image/svg+xml').send(svg);
|
||||
});
|
||||
recordTelemetryEvent(req);
|
||||
|
||||
res.header('Content-Type', 'image/gif').send(buffer);
|
||||
}
|
||||
);
|
||||
|
||||
telemetryRouter.get(
|
||||
'/:workspaceId/badge.svg',
|
||||
validate(
|
||||
query('name').optional().isString(),
|
||||
query('url').optional().isURL()
|
||||
),
|
||||
async (req, res) => {
|
||||
const title = req.query.title || 'visitor';
|
||||
const start = req.query.start ? Number(req.query.start) : 0;
|
||||
|
||||
recordTelemetryEvent(req);
|
||||
const num = await sumTelemetryEvent(req);
|
||||
|
||||
const svg = await new Promise((resolve, reject) => {
|
||||
openBadge(
|
||||
{
|
||||
text: [title, numify(num + start)],
|
||||
},
|
||||
(err: any, badgeSvg: string) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(badgeSvg);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
res.header('Content-Type', 'image/svg+xml').send(svg);
|
||||
}
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user