-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.ts
127 lines (109 loc) · 3.34 KB
/
app.ts
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { WebhookClient } from "discord.js";
import Fastify from "fastify";
import { verify } from "jsonwebtoken";
const fastify = Fastify({ logger: true });
interface NetlifyEventBody {
id: string;
site_id: string;
build_id: string;
state: NetlifyStates;
name: string;
url: string;
ssl_url: string;
admin_url: string;
deploy_url: string;
deploy_ssl_url: string;
error_message?: string;
branch: string;
}
enum Colors {
GREEN = 0x238823,
YELLOW = 0xffbf00,
RED = 0xd2222d,
BLUE = 0x008ce4,
}
// enum to reference netlify states consistently
enum NetlifyStates {
BUILDING = "building",
READY = "ready",
ERROR = "error",
}
// maps a build state to messaging above
// the embedded message
enum ContentMapping {
"building" = "There is a new deploy in process for",
"ready" = "Successful deploy of",
"error" = "Deploy did not complete for",
}
// maps a build state to a color for the sidebar
// styling of the embedded message
enum ColorMapping {
"building" = Colors.YELLOW,
"ready" = Colors.GREEN,
"error" = Colors.RED,
}
// maps a build state to some verbiage
enum TitleMapping {
"building" = "Visit the build log",
"ready" = "Visit the changes live",
"error" = "Visit the build log",
}
// utility function to get value from enum
// avoiding runtime errors
const getValueByKey = (enumerated: any, key: string): string | undefined => {
return enumerated[key] ?? undefined;
};
const generateMessage = (body: NetlifyEventBody) => {
const buildLogUrl = `${body.admin_url}/deploys/${body.id}`;
const buildLogDescription = `Or check out the [build log](${buildLogUrl})`;
return {
content: `${getValueByKey(ContentMapping, body.state)} *${body.name}*`,
embeds: [
{
color: Number(getValueByKey(ColorMapping, body.state)) || undefined,
title: body.state === NetlifyStates.READY ? `Visit ${body.name} [${body.branch} branch] changes live here` : getValueByKey(TitleMapping, body.state),
url:
body.state === NetlifyStates.READY
? body.deploy_ssl_url
: buildLogUrl,
description:
body.state === NetlifyStates.READY ? buildLogDescription : "",
timestamp: new Date().toISOString(),
footer: {
text: `Deploy URL: ${body.deploy_ssl_url}`,
},
},
],
};
};
// Declare a route
fastify.get("/healthz", async (request, reply) => {
reply.code(200).send({ message: "Breathing..." });
});
fastify.post("/netlify-hook", async (request, reply) => {
try {
verify(
request.headers["x-webhook-signature"]?.toString() ?? "",
process.env.WEBHOOK_SECRET || "",
{ algorithms: ["HS256"] }
);
} catch (error) {
console.log(error);
fastify.Sentry.captureMessage("Unable to verify secret key");
reply.code(200).send({ err: "Unable to verify secret key" });
}
try {
const webhookClient = new WebhookClient({
url: fastify.config.DISCORD_WEBHOOK_URL,
});
const { content, embeds } = generateMessage(
JSON.parse(JSON.stringify(request.body as NetlifyEventBody))
);
webhookClient.send({ content, embeds });
reply.code(200).send({ message: "Success" });
} catch (error) {
fastify.Sentry.captureMessage("Unable to send via discord webhook client");
reply.code(200).send({ err: "Unable to send via discord webhook client" });
}
});
export default fastify;