fix(api): sending duplicated responses for bot events (improved code as well)

This commit is contained in:
Carl-Gerhard Lindesvärd
2024-11-30 21:40:25 +01:00
parent d80754a6fd
commit afff099c5b
6 changed files with 101 additions and 144 deletions

View File

@@ -0,0 +1,26 @@
import { SdkAuthError, validateSdkRequest } from '@/utils/auth';
import type { TrackHandlerPayload } from '@openpanel/sdk';
import type {
FastifyReply,
FastifyRequest,
HookHandlerDoneFunction,
} from 'fastify';
export async function clientHook(
req: FastifyRequest<{
Body: TrackHandlerPayload;
}>,
reply: FastifyReply,
) {
try {
const client = await validateSdkRequest(req.headers);
req.projectId = client.projectId;
req.client = client;
} catch (error) {
if (error instanceof SdkAuthError) {
return reply.status(401).send(error.message);
}
return reply.status(500).send('Internal server error');
}
}

View File

@@ -0,0 +1,51 @@
import { isBot } from '@/bots';
import { createBotEvent } from '@openpanel/db';
import type { TrackHandlerPayload } from '@openpanel/sdk';
import type { FastifyReply, FastifyRequest } from 'fastify';
type DeprecatedEventPayload = {
name: string;
properties: Record<string, unknown>;
timestamp: string;
};
export async function isBotHook(
req: FastifyRequest<{
Body: TrackHandlerPayload | DeprecatedEventPayload;
}>,
reply: FastifyReply,
) {
const bot = req.headers['user-agent']
? isBot(req.headers['user-agent'])
: null;
if (bot && req.client?.projectId) {
if ('type' in req.body && req.body.type === 'track') {
const path = (req.body.payload.properties?.__path ||
req.body.payload.properties?.path) as string | undefined;
if (path) {
await createBotEvent({
...bot,
projectId: req.client.projectId,
path: path ?? '',
createdAt: new Date(),
});
}
// Handle deprecated events (v1)
} else if ('name' in req.body && 'properties' in req.body) {
const path = (req.body.properties?.__path || req.body.properties?.path) as
| string
| undefined;
if (path) {
await createBotEvent({
...bot,
projectId: req.client.projectId,
path: path ?? '',
createdAt: new Date(),
});
}
}
return reply.status(202).send('OK');
}
}