rename mixan to OPENPANEL!
This commit is contained in:
@@ -1,19 +1,19 @@
|
||||
import { logger, logInfo, noop } from '@/utils/logger';
|
||||
import { getClientIp, parseIp } from '@/utils/parseIp';
|
||||
import { getReferrerWithQuery, parseReferrer } from '@/utils/parseReferrer';
|
||||
import { isUserAgentSet, parseUserAgent } from '@/utils/parseUserAgent';
|
||||
import { isSameDomain, parsePath } from '@/utils/url';
|
||||
import type { FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { omit } from 'ramda';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { logger, logInfo, noop } from "@/utils/logger";
|
||||
import { getClientIp, parseIp } from "@/utils/parseIp";
|
||||
import { getReferrerWithQuery, parseReferrer } from "@/utils/parseReferrer";
|
||||
import { isUserAgentSet, parseUserAgent } from "@/utils/parseUserAgent";
|
||||
import { isSameDomain, parsePath } from "@/utils/url";
|
||||
import type { FastifyReply, FastifyRequest } from "fastify";
|
||||
import { omit } from "ramda";
|
||||
import { v4 as uuid } from "uuid";
|
||||
|
||||
import { generateDeviceId, getTime, toISOString } from '@mixan/common';
|
||||
import type { IServiceCreateEventPayload } from '@mixan/db';
|
||||
import { createEvent, getEvents, getSalts } from '@mixan/db';
|
||||
import type { JobsOptions } from '@mixan/queue';
|
||||
import { eventsQueue } from '@mixan/queue';
|
||||
import { findJobByPrefix } from '@mixan/queue/src/utils';
|
||||
import type { PostEventPayload } from '@mixan/sdk';
|
||||
import { generateDeviceId, getTime, toISOString } from "@openpanel/common";
|
||||
import type { IServiceCreateEventPayload } from "@openpanel/db";
|
||||
import { createEvent, getEvents, getSalts } from "@openpanel/db";
|
||||
import type { JobsOptions } from "@openpanel/queue";
|
||||
import { eventsQueue } from "@openpanel/queue";
|
||||
import { findJobByPrefix } from "@openpanel/queue/src/utils";
|
||||
import type { PostEventPayload } from "@openpanel/sdk";
|
||||
|
||||
const SESSION_TIMEOUT = 1000 * 60 * 30;
|
||||
const SESSION_END_TIMEOUT = SESSION_TIMEOUT + 1000;
|
||||
@@ -55,7 +55,7 @@ export async function postEvent(
|
||||
request: FastifyRequest<{
|
||||
Body: PostEventPayload;
|
||||
}>,
|
||||
reply: FastifyReply
|
||||
reply: FastifyReply,
|
||||
) {
|
||||
const contextLogger = createContextLogger(request);
|
||||
let deviceId: string | null = null;
|
||||
@@ -65,23 +65,23 @@ export async function postEvent(
|
||||
// replace thing is just for older sdks when we didn't have `__`
|
||||
// remove when kiddokitchen app (24.09.02) is not used anymore
|
||||
return (
|
||||
((properties[name] || properties[name.replace('__', '')]) as
|
||||
((properties[name] || properties[name.replace("__", "")]) as
|
||||
| string
|
||||
| null
|
||||
| undefined) ?? undefined
|
||||
);
|
||||
};
|
||||
const profileId = body.profileId ?? '';
|
||||
const profileId = body.profileId ?? "";
|
||||
const createdAt = new Date(body.timestamp);
|
||||
const url = getProperty('__path');
|
||||
const url = getProperty("__path");
|
||||
const { path, hash, query } = parsePath(url);
|
||||
const referrer = isSameDomain(getProperty('__referrer'), url)
|
||||
const referrer = isSameDomain(getProperty("__referrer"), url)
|
||||
? null
|
||||
: parseReferrer(getProperty('__referrer'));
|
||||
: parseReferrer(getProperty("__referrer"));
|
||||
const utmReferrer = getReferrerWithQuery(query);
|
||||
const ip = getClientIp(request)!;
|
||||
const origin = request.headers.origin!;
|
||||
const ua = request.headers['user-agent']!;
|
||||
const ua = request.headers["user-agent"]!;
|
||||
const uaInfo = parseUserAgent(ua);
|
||||
const salts = await getSalts();
|
||||
const currentDeviceId = generateDeviceId({
|
||||
@@ -101,66 +101,66 @@ export async function postEvent(
|
||||
|
||||
if (isServerEvent) {
|
||||
const [event] = await withTiming(
|
||||
'Get last event (server-event)',
|
||||
"Get last event (server-event)",
|
||||
getEvents(
|
||||
`SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`
|
||||
)
|
||||
`SELECT * FROM events WHERE name = 'screen_view' AND profile_id = '${profileId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`,
|
||||
),
|
||||
);
|
||||
|
||||
eventsQueue.add('event', {
|
||||
type: 'createEvent',
|
||||
eventsQueue.add("event", {
|
||||
type: "createEvent",
|
||||
payload: {
|
||||
name: body.name,
|
||||
deviceId: event?.deviceId || '',
|
||||
sessionId: event?.sessionId || '',
|
||||
deviceId: event?.deviceId || "",
|
||||
sessionId: event?.sessionId || "",
|
||||
profileId,
|
||||
projectId,
|
||||
properties: Object.assign(
|
||||
{},
|
||||
omit(['__path', '__referrer'], properties),
|
||||
omit(["__path", "__referrer"], properties),
|
||||
{
|
||||
hash,
|
||||
query,
|
||||
}
|
||||
},
|
||||
),
|
||||
createdAt,
|
||||
country: event?.country ?? '',
|
||||
city: event?.city ?? '',
|
||||
region: event?.region ?? '',
|
||||
continent: event?.continent ?? '',
|
||||
os: event?.os ?? '',
|
||||
osVersion: event?.osVersion ?? '',
|
||||
browser: event?.browser ?? '',
|
||||
browserVersion: event?.browserVersion ?? '',
|
||||
device: event?.device ?? '',
|
||||
brand: event?.brand ?? '',
|
||||
model: event?.model ?? '',
|
||||
country: event?.country ?? "",
|
||||
city: event?.city ?? "",
|
||||
region: event?.region ?? "",
|
||||
continent: event?.continent ?? "",
|
||||
os: event?.os ?? "",
|
||||
osVersion: event?.osVersion ?? "",
|
||||
browser: event?.browser ?? "",
|
||||
browserVersion: event?.browserVersion ?? "",
|
||||
device: event?.device ?? "",
|
||||
brand: event?.brand ?? "",
|
||||
model: event?.model ?? "",
|
||||
duration: 0,
|
||||
path: event?.path ?? '',
|
||||
referrer: event?.referrer ?? '',
|
||||
referrerName: event?.referrerName ?? '',
|
||||
referrerType: event?.referrerType ?? '',
|
||||
path: event?.path ?? "",
|
||||
referrer: event?.referrer ?? "",
|
||||
referrerName: event?.referrerName ?? "",
|
||||
referrerType: event?.referrerType ?? "",
|
||||
profile: undefined,
|
||||
meta: undefined,
|
||||
},
|
||||
});
|
||||
return reply.status(200).send('');
|
||||
return reply.status(200).send("");
|
||||
}
|
||||
|
||||
const [geo, sessionEndJobCurrentDeviceId, sessionEndJobPreviousDeviceId] =
|
||||
await withTiming(
|
||||
'Get geo and jobs from queue',
|
||||
"Get geo and jobs from queue",
|
||||
Promise.all([
|
||||
parseIp(ip),
|
||||
findJobByPrefix(
|
||||
eventsQueue,
|
||||
`sessionEnd:${projectId}:${currentDeviceId}:`
|
||||
`sessionEnd:${projectId}:${currentDeviceId}:`,
|
||||
),
|
||||
findJobByPrefix(
|
||||
eventsQueue,
|
||||
`sessionEnd:${projectId}:${previousDeviceId}:`
|
||||
`sessionEnd:${projectId}:${previousDeviceId}:`,
|
||||
),
|
||||
])
|
||||
]),
|
||||
);
|
||||
|
||||
const createSessionStart =
|
||||
@@ -178,9 +178,9 @@ export async function postEvent(
|
||||
deviceId = currentDeviceId;
|
||||
// Queue session end
|
||||
eventsQueue.add(
|
||||
'event',
|
||||
"event",
|
||||
{
|
||||
type: 'createSessionEnd',
|
||||
type: "createSessionEnd",
|
||||
payload: {
|
||||
deviceId,
|
||||
},
|
||||
@@ -188,27 +188,27 @@ export async function postEvent(
|
||||
{
|
||||
delay: SESSION_END_TIMEOUT,
|
||||
jobId: `sessionEnd:${projectId}:${deviceId}:${Date.now()}`,
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const [[sessionStartEvent], prevEventJob] = await withTiming(
|
||||
'Get session start event',
|
||||
"Get session start event",
|
||||
Promise.all([
|
||||
getEvents(
|
||||
`SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`
|
||||
`SELECT * FROM events WHERE name = 'session_start' AND device_id = '${deviceId}' AND project_id = '${projectId}' ORDER BY created_at DESC LIMIT 1`,
|
||||
),
|
||||
findJobByPrefix(eventsQueue, `event:${projectId}:${deviceId}:`),
|
||||
])
|
||||
]),
|
||||
);
|
||||
|
||||
const payload: Omit<IServiceCreateEventPayload, 'id'> = {
|
||||
const payload: Omit<IServiceCreateEventPayload, "id"> = {
|
||||
name: body.name,
|
||||
deviceId,
|
||||
profileId,
|
||||
projectId,
|
||||
sessionId: createSessionStart ? uuid() : sessionStartEvent?.sessionId ?? '',
|
||||
properties: Object.assign({}, omit(['__path', '__referrer'], properties), {
|
||||
sessionId: createSessionStart ? uuid() : sessionStartEvent?.sessionId ?? "",
|
||||
properties: Object.assign({}, omit(["__path", "__referrer"], properties), {
|
||||
hash,
|
||||
query,
|
||||
}),
|
||||
@@ -227,27 +227,27 @@ export async function postEvent(
|
||||
duration: 0,
|
||||
path: path,
|
||||
referrer: referrer?.url,
|
||||
referrerName: referrer?.name ?? utmReferrer?.name ?? '',
|
||||
referrerType: referrer?.type ?? utmReferrer?.type ?? '',
|
||||
referrerName: referrer?.name ?? utmReferrer?.name ?? "",
|
||||
referrerType: referrer?.type ?? utmReferrer?.type ?? "",
|
||||
profile: undefined,
|
||||
meta: undefined,
|
||||
};
|
||||
|
||||
const isDelayed = prevEventJob ? await prevEventJob?.isDelayed() : false;
|
||||
|
||||
if (isDelayed && prevEventJob && prevEventJob.data.type === 'createEvent') {
|
||||
if (isDelayed && prevEventJob && prevEventJob.data.type === "createEvent") {
|
||||
const prevEvent = prevEventJob.data.payload;
|
||||
const duration = getTime(payload.createdAt) - getTime(prevEvent.createdAt);
|
||||
contextLogger.add('prevEvent', prevEvent);
|
||||
contextLogger.add("prevEvent", prevEvent);
|
||||
|
||||
// Set path from prev screen_view event if current event is not a screen_view
|
||||
if (payload.name != 'screen_view') {
|
||||
if (payload.name != "screen_view") {
|
||||
payload.path = prevEvent.path;
|
||||
}
|
||||
|
||||
if (payload.name === 'screen_view') {
|
||||
if (payload.name === "screen_view") {
|
||||
if (duration < 0) {
|
||||
contextLogger.send('duration is wrong', {
|
||||
contextLogger.send("duration is wrong", {
|
||||
payload,
|
||||
duration,
|
||||
});
|
||||
@@ -255,21 +255,21 @@ export async function postEvent(
|
||||
// Skip update duration if it's wrong
|
||||
// Seems like request is not in right order
|
||||
await withTiming(
|
||||
'Update previous job with duration',
|
||||
"Update previous job with duration",
|
||||
prevEventJob.updateData({
|
||||
type: 'createEvent',
|
||||
type: "createEvent",
|
||||
payload: {
|
||||
...prevEvent,
|
||||
duration,
|
||||
},
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
await withTiming('Promote previous job', prevEventJob.promote());
|
||||
await withTiming("Promote previous job", prevEventJob.promote());
|
||||
}
|
||||
} else if (payload.name !== 'screen_view') {
|
||||
contextLogger.send('no previous job', {
|
||||
} else if (payload.name !== "screen_view") {
|
||||
contextLogger.send("no previous job", {
|
||||
prevEventJob,
|
||||
payload,
|
||||
});
|
||||
@@ -278,23 +278,23 @@ export async function postEvent(
|
||||
if (createSessionStart) {
|
||||
// We do not need to queue session_start
|
||||
await withTiming(
|
||||
'Create session start event',
|
||||
"Create session start event",
|
||||
createEvent({
|
||||
...payload,
|
||||
name: 'session_start',
|
||||
name: "session_start",
|
||||
// @ts-expect-error
|
||||
createdAt: toISOString(getTime(payload.createdAt) - 100),
|
||||
})
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
const options: JobsOptions = {};
|
||||
if (payload.name === 'screen_view') {
|
||||
if (payload.name === "screen_view") {
|
||||
options.delay = SESSION_TIMEOUT;
|
||||
options.jobId = `event:${projectId}:${deviceId}:${Date.now()}`;
|
||||
}
|
||||
|
||||
contextLogger.send('event is queued', {
|
||||
contextLogger.send("event is queued", {
|
||||
ip,
|
||||
origin,
|
||||
ua,
|
||||
@@ -312,14 +312,14 @@ export async function postEvent(
|
||||
// Queue current event
|
||||
eventsQueue
|
||||
.add(
|
||||
'event',
|
||||
"event",
|
||||
{
|
||||
type: 'createEvent',
|
||||
type: "createEvent",
|
||||
payload,
|
||||
},
|
||||
options
|
||||
options,
|
||||
)
|
||||
.catch(noop('Failed to queue event'));
|
||||
.catch(noop("Failed to queue event"));
|
||||
|
||||
reply.status(202).send(deviceId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user