Skip to content

Commit df685d5

Browse files
Techbot121Meta Construct
authored andcommitted
add separate webhook handler for chatsounds
1 parent 9857b77 commit df685d5

File tree

1 file changed

+131
-14
lines changed

1 file changed

+131
-14
lines changed

app/services/discord/modules/webhook-handler.ts

Lines changed: 131 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,19 @@ import { Webhooks, createNodeMiddleware } from "@octokit/webhooks";
44
import { clamp } from "@/utils.js";
55
import axios from "axios";
66
import webhookConfig from "@/config/webhooks.json" with { type: "json" };
7+
import { EmitterWebhookEvent } from "@octokit/webhooks/types";
78

89
const COLOR_MOD = 75;
910
const COLOR_BASE = 50;
1011

12+
function GetColorFromChanges(added: number, removed: number, modified: number) {
13+
return (
14+
clamp(COLOR_BASE + COLOR_MOD * removed, COLOR_BASE, 255) * 65536 +
15+
clamp(COLOR_BASE + COLOR_MOD * added, COLOR_BASE, 255) * 256 +
16+
clamp(COLOR_BASE + COLOR_MOD * modified, COLOR_BASE, 255)
17+
);
18+
}
19+
1120
const DIFF_SIZE = 2048;
1221
const MAX_FIELDS = 10;
1322
const MAX_COMMITS = 5;
@@ -22,6 +31,11 @@ const BaseEmbed = <Discord.WebhookMessageCreateOptions>{
2231
allowedMentions: { parse: ["users"] },
2332
};
2433

34+
const DefaultSeparator = {
35+
type: Discord.ComponentType.Separator,
36+
divider: true,
37+
} as Discord.SeparatorComponent;
38+
2539
const GetGithubChanges = (
2640
repoPath: string,
2741
sha: string,
@@ -249,8 +263,7 @@ export default async (bot: DiscordBot): Promise<void> => {
249263
}
250264
});
251265

252-
GitHub.on("push", async event => {
253-
if (!webhook) return;
266+
async function DefaultHandler(event: EmitterWebhookEvent<"push">) {
254267
const payload = event.payload;
255268
const repo = payload.repository;
256269
const serverOverride = REPO_SERVER_MAP.get(repo.name);
@@ -279,7 +292,7 @@ export default async (bot: DiscordBot): Promise<void> => {
279292
color: 0xffd700,
280293
timestamp: new Date().toISOString(),
281294
footer: {
282-
text: `by ${payload.sender?.name ?? payload.sender?.login ?? "unkown"}`,
295+
text: `by ${payload.sender?.name ?? payload.sender?.login ?? "unknown"}`,
283296
},
284297
};
285298

@@ -295,13 +308,6 @@ export default async (bot: DiscordBot): Promise<void> => {
295308
commit.modified
296309
);
297310

298-
const color =
299-
clamp(COLOR_BASE + COLOR_MOD * (commit.removed?.length ?? 0), COLOR_BASE, 255) *
300-
65536 +
301-
clamp(COLOR_BASE + COLOR_MOD * (commit.added?.length ?? 0), COLOR_BASE, 255) *
302-
256 +
303-
clamp(COLOR_BASE + COLOR_MOD * (commit.modified?.length ?? 0), COLOR_BASE, 255);
304-
305311
if (MinimalPushUsers.includes(commit.author.username ?? commit.author.name)) {
306312
embeds.push({
307313
title:
@@ -317,7 +323,11 @@ export default async (bot: DiscordBot): Promise<void> => {
317323
url: repo.html_url,
318324
icon_url: repo.owner?.avatar_url,
319325
},
320-
color,
326+
color: GetColorFromChanges(
327+
commit.added?.length ?? 0,
328+
commit.removed?.length ?? 0,
329+
commit.modified?.length ?? 0
330+
),
321331
url: commit.url,
322332
fields,
323333
timestamp: commit.timestamp,
@@ -389,7 +399,11 @@ export default async (bot: DiscordBot): Promise<void> => {
389399
url: repo.html_url,
390400
icon_url: repo.owner?.avatar_url,
391401
},
392-
color,
402+
color: GetColorFromChanges(
403+
commit.added?.length ?? 0,
404+
commit.removed?.length ?? 0,
405+
commit.modified?.length ?? 0
406+
),
393407
url: commit.url,
394408
fields,
395409
timestamp: commit.timestamp,
@@ -447,7 +461,6 @@ export default async (bot: DiscordBot): Promise<void> => {
447461
embeds: chunk,
448462
components: i === embeds.length - 1 && includesLua ? [components] : undefined,
449463
});
450-
chatWebhook?.send({ ...messagePayload, embeds: chunk });
451464
}
452465
} else {
453466
webhook
@@ -456,7 +469,111 @@ export default async (bot: DiscordBot): Promise<void> => {
456469
components: includesLua ? [components] : undefined,
457470
})
458471
.catch(console.error);
459-
chatWebhook?.send(messagePayload);
472+
}
473+
}
474+
475+
function GroupSoundFilesByFolder(paths: string[]) {
476+
// behold my newest creation that no one will get on their first read
477+
// example path "sound/chatsounds/autoadd/{foldername}/{soundname}"
478+
return paths.reduce((map, path) => {
479+
const [mainFolder, , , folderName, soundName] = path.split("/");
480+
if (mainFolder !== "sound" || !folderName || !soundName) return map;
481+
map.set(folderName, [
482+
...(map.get(folderName) ?? []),
483+
soundName.replace(/\.[^/.]+$/, ""),
484+
]);
485+
return map;
486+
}, new Map<string, string[]>());
487+
}
488+
489+
async function ChatsoundsHandler(event: EmitterWebhookEvent<"push">) {
490+
const payload = event.payload;
491+
const commits = payload.commits;
492+
493+
if (payload.head_commit && isRemoteMergeCommit(payload.head_commit.message))
494+
commits.splice(0, commits.length, payload.head_commit);
495+
496+
const container = new Discord.ContainerBuilder();
497+
498+
for (const commit of commits) {
499+
container.setAccentColor(
500+
GetColorFromChanges(
501+
commit.added?.length ?? 0,
502+
commit.removed?.length ?? 0,
503+
commit.modified?.length ?? 0
504+
)
505+
);
506+
507+
container.addTextDisplayComponents({
508+
type: Discord.ComponentType.TextDisplay,
509+
content: `# [Chatsound Update](${commit.url})`,
510+
});
511+
512+
container.addSeparatorComponents(DefaultSeparator);
513+
514+
const addedSounds = GroupSoundFilesByFolder(commit.added ?? []);
515+
const removedSounds = GroupSoundFilesByFolder(commit.removed ?? []);
516+
const modifiedSounds = GroupSoundFilesByFolder(commit.modified ?? []);
517+
518+
const formatSounds = ([folderName, sounds]: [string, string[]]) =>
519+
`[${folderName}](${payload.repository.html_url}/tree/master/sound/chatsounds/autoadd/${folderName}) -> ${[...new Set(sounds)].map(s => `\`${s}\``).join(", ")}`;
520+
521+
// maybe there is a better way instead of if-chaining this but whatever
522+
if (commit.added && addedSounds.size > 0) {
523+
container.addTextDisplayComponents({
524+
type: Discord.ComponentType.TextDisplay,
525+
content: `### Added ${commit.added.length} new sound${commit.added.length > 1 ? "s" : ""}:\n${Array.from(
526+
addedSounds
527+
)
528+
.map(formatSounds)
529+
.join("\n\n")}`,
530+
});
531+
532+
container.addSeparatorComponents(DefaultSeparator);
533+
}
534+
if (commit.removed && removedSounds.size > 0) {
535+
container.addTextDisplayComponents({
536+
type: Discord.ComponentType.TextDisplay,
537+
content: `### Removed ${commit.removed.length} sound${commit.removed.length > 1 ? "s" : ""}:\n${Array.from(
538+
removedSounds
539+
)
540+
.map(formatSounds)
541+
.join("\n\n")}`,
542+
});
543+
544+
container.addSeparatorComponents(DefaultSeparator);
545+
}
546+
if (commit.modified && modifiedSounds.size > 0) {
547+
container.addTextDisplayComponents({
548+
type: Discord.ComponentType.TextDisplay,
549+
content: `### Changed ${commit.modified.length} sound${commit.modified.length > 1 ? "s" : ""}:\n${Array.from(
550+
modifiedSounds
551+
)
552+
.map(formatSounds)
553+
.join("\n\n")}`,
554+
});
555+
556+
container.addSeparatorComponents(DefaultSeparator);
557+
}
558+
container.addTextDisplayComponents({
559+
type: Discord.ComponentType.TextDisplay,
560+
content: `-# added by ${commit.author.username ?? commit.author.name} via \`${commit.message.split("\n\n")[0]}\`, approved by ${payload.pusher.username ?? payload.pusher.name}`,
561+
});
562+
}
563+
webhook.send({ components: [container], flags: Discord.MessageFlags.IsComponentsV2 });
564+
chatWebhook.send({ components: [container], flags: Discord.MessageFlags.IsComponentsV2 });
565+
}
566+
567+
GitHub.on("push", async event => {
568+
if (!webhook) return;
569+
switch (event.payload.repository.name) {
570+
case "garrysmod-chatsounds":
571+
ChatsoundsHandler(event);
572+
break;
573+
574+
default:
575+
DefaultHandler(event);
576+
break;
460577
}
461578
});
462579

0 commit comments

Comments
 (0)