2023-09-17 11:59:34 +00:00
|
|
|
import { TelemetrySession } from '@prisma/client';
|
|
|
|
import { Request } from 'express';
|
|
|
|
import { hashUuid } from '../utils/common';
|
|
|
|
import { getRequestInfo } from '../utils/detect';
|
|
|
|
import { prisma } from './_client';
|
|
|
|
|
|
|
|
export async function recordTelemetryEvent(req: Request) {
|
2023-10-31 14:36:32 +00:00
|
|
|
const { url = req.headers.referer, name, ...others } = req.query;
|
|
|
|
|
2023-09-17 11:59:34 +00:00
|
|
|
if (!(url && typeof url === 'string')) {
|
|
|
|
return;
|
|
|
|
}
|
2023-10-31 14:36:32 +00:00
|
|
|
const eventName = name ? String(name) : undefined;
|
2023-09-17 11:59:34 +00:00
|
|
|
|
|
|
|
const session = await findSession(req, url);
|
|
|
|
if (!session) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-17 16:13:03 +00:00
|
|
|
const workspaceId = req.params.workspaceId;
|
|
|
|
if (!workspaceId) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-17 11:59:34 +00:00
|
|
|
const { origin, pathname } = new URL(url);
|
2023-10-31 14:36:32 +00:00
|
|
|
const payload = Object.keys(others).length > 0 ? others : undefined;
|
2023-09-17 11:59:34 +00:00
|
|
|
|
|
|
|
await prisma.telemetryEvent.create({
|
|
|
|
data: {
|
|
|
|
sessionId: session.id,
|
2023-09-17 16:13:03 +00:00
|
|
|
workspaceId,
|
|
|
|
eventName,
|
2023-09-17 11:59:34 +00:00
|
|
|
urlOrigin: origin,
|
|
|
|
urlPath: pathname,
|
2023-10-31 14:36:32 +00:00
|
|
|
payload,
|
2023-09-17 11:59:34 +00:00
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function sumTelemetryEvent(req: Request): Promise<number> {
|
|
|
|
const url = req.query.url ?? req.headers.referer;
|
|
|
|
if (!(url && typeof url === 'string')) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-09-17 16:13:03 +00:00
|
|
|
const eventName = req.query.name ? String(req.query.name) : undefined;
|
|
|
|
|
|
|
|
const workspaceId = req.params.workspaceId;
|
|
|
|
if (!workspaceId) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-09-17 11:59:34 +00:00
|
|
|
const { origin, pathname } = new URL(url);
|
|
|
|
|
|
|
|
const number = await prisma.telemetryEvent.count({
|
|
|
|
where: {
|
2023-09-17 16:13:03 +00:00
|
|
|
workspaceId,
|
|
|
|
eventName,
|
2023-09-17 11:59:34 +00:00
|
|
|
urlOrigin: origin,
|
|
|
|
urlPath: pathname,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function findSession(req: Request, url: string) {
|
|
|
|
const { hostname } = new URL(url);
|
2023-09-17 16:13:03 +00:00
|
|
|
const workspaceId = req.params.workspaceId;
|
|
|
|
if (!workspaceId) {
|
|
|
|
throw new Error('Not found workspaceId');
|
|
|
|
}
|
2023-09-17 11:59:34 +00:00
|
|
|
|
|
|
|
const {
|
|
|
|
userAgent,
|
|
|
|
browser,
|
|
|
|
os,
|
|
|
|
ip,
|
|
|
|
country,
|
|
|
|
subdivision1,
|
|
|
|
subdivision2,
|
|
|
|
city,
|
|
|
|
} = await getRequestInfo(req);
|
|
|
|
|
2023-09-17 16:13:03 +00:00
|
|
|
const sessionId = hashUuid(workspaceId, hostname, ip, userAgent!);
|
2023-09-17 11:59:34 +00:00
|
|
|
|
|
|
|
let session = await loadSession(sessionId);
|
|
|
|
if (!session) {
|
|
|
|
try {
|
|
|
|
session = await prisma.telemetrySession.create({
|
|
|
|
data: {
|
|
|
|
id: sessionId,
|
2023-09-17 16:13:03 +00:00
|
|
|
workspaceId,
|
2023-09-17 11:59:34 +00:00
|
|
|
hostname,
|
|
|
|
browser,
|
|
|
|
os,
|
2023-11-27 16:45:13 +00:00
|
|
|
ip,
|
2023-09-17 11:59:34 +00:00
|
|
|
country,
|
|
|
|
subdivision1,
|
|
|
|
subdivision2,
|
|
|
|
city,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
} catch (e: any) {
|
|
|
|
if (!e.message.toLowerCase().includes('unique constraint')) {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return session;
|
|
|
|
}
|
|
|
|
|
|
|
|
async function loadSession(
|
|
|
|
sessionId: string
|
|
|
|
): Promise<TelemetrySession | null> {
|
|
|
|
const session = await prisma.telemetrySession.findUnique({
|
|
|
|
where: {
|
|
|
|
id: sessionId,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
if (!session) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return session;
|
|
|
|
}
|