-
Notifications
You must be signed in to change notification settings - Fork 242
Expand file tree
/
Copy pathroute.ts
More file actions
90 lines (81 loc) · 2.75 KB
/
route.ts
File metadata and controls
90 lines (81 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { NextRequest, NextResponse } from "next/server";
import DomainModel, { Domain } from "@models/Domain";
import EmailEventModel from "@models/EmailEvent";
import UserModel from "@models/User";
import SequenceModel from "@models/Sequence";
import { Constants, Sequence, User } from "@courselit/common-models";
import { error } from "@/services/logger";
import { jwtUtils } from "@courselit/utils";
function getJwtSecret(): string {
const jwtSecret = process.env.PIXEL_SIGNING_SECRET;
if (!jwtSecret) {
throw new Error("PIXEL_SIGNING_SECRET is not defined");
}
return jwtSecret;
}
// 1x1 transparent PNG buffer
const pixelBuffer = Buffer.from(
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/w8AAgMBApUe1ZkAAAAASUVORK5CYII=",
"base64",
);
const pixelResponse = new NextResponse(pixelBuffer, {
status: 200,
headers: {
"Content-Type": "image/png",
"Cache-Control": "no-store",
},
});
export async function GET(req: NextRequest) {
if (!process.env.PIXEL_SIGNING_SECRET) {
error(
"PIXEL_SIGNING_SECRET environment variable is not defined. No pixel tracking is done.",
);
return pixelResponse;
}
try {
const domainName = req.headers.get("domain");
const domain = await DomainModel.findOne<Domain>({
name: domainName,
});
if (!domain) {
throw new Error(`Domain not found: ${domainName}`);
}
const { searchParams } = new URL(req.url);
const d = searchParams.get("d");
if (!d) {
throw new Error("Missing data query parameter");
}
const jwtSecret = getJwtSecret();
const payload = jwtUtils.verifyToken(d, jwtSecret);
const { userId, sequenceId, emailId } = payload as any;
if (!userId || !sequenceId || !emailId) {
throw new Error(
`Invalid payload: Not all required fields are present: ${JSON.stringify(payload)}`,
);
}
const sequence = await SequenceModel.findOne<Sequence>({
domain: domain._id,
sequenceId,
});
const user = await UserModel.findOne<User>({
domain: domain._id,
userId,
});
const email = sequence?.emails.find((e) => e.emailId === emailId);
if (sequence && user && email) {
await EmailEventModel.create({
domain: domain._id,
sequenceId,
userId,
emailId,
action: Constants.EmailEventAction.OPEN,
});
}
} catch (err) {
error(`Invalid pixel data`, {
fileName: "pixel.route.ts",
stack: err.stack,
});
}
return pixelResponse;
}