39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import "server-only";
|
|
|
|
import { getVisitorTrackingConfig } from "@/lib/config/server";
|
|
import { getRedisClient } from "@/lib/redis";
|
|
import {
|
|
getClientAddress,
|
|
hashClientAddress,
|
|
} from "@/lib/visitor/visitor-identifiers";
|
|
|
|
const VISITOR_SET_KEY = "erika:unique_visitors:v2";
|
|
const LEGACY_VISITOR_SET_KEY = "erika:unique_visitors";
|
|
|
|
export async function trackUniqueVisitor(headers: Headers) {
|
|
const client = await getRedisClient();
|
|
const address = getClientAddress(headers);
|
|
|
|
if (address) {
|
|
const { secret } = getVisitorTrackingConfig();
|
|
const identifier = hashClientAddress(address, secret);
|
|
const [isLegacyVisitor, isPrivateVisitor] = await Promise.all([
|
|
client.sismember(LEGACY_VISITOR_SET_KEY, address),
|
|
client.sismember(VISITOR_SET_KEY, identifier),
|
|
]);
|
|
|
|
if (isLegacyVisitor) {
|
|
// Keep the legacy visitor in the old total without counting a revisit twice.
|
|
if (isPrivateVisitor) await client.srem(VISITOR_SET_KEY, identifier);
|
|
} else {
|
|
await client.sadd(VISITOR_SET_KEY, identifier);
|
|
}
|
|
}
|
|
|
|
const [legacyCount, privateCount] = await Promise.all([
|
|
client.scard(LEGACY_VISITOR_SET_KEY),
|
|
client.scard(VISITOR_SET_KEY),
|
|
]);
|
|
return legacyCount + privateCount;
|
|
}
|