add support for multiple webhook endpoints
All checks were successful
deploy / build-and-deploy (push) Successful in 17s

This commit is contained in:
2025-10-13 21:26:09 +02:00
parent 83d67dcba6
commit 8ffdcb7696
3 changed files with 45 additions and 19 deletions

View File

@@ -91,8 +91,8 @@ const information = [
<div>
<h2 class="text-3xl text-black dark:text-white mb-8">Über uns</h2>
<p>
Wir sind ein kleines <a class="link" href="admins">Team</a> von Minecraft-Enthusiasten, das bereits im 8. Jahr in
Folge Minecraft CraftAttack organisiert. Jahr für Jahr arbeiten wir daran, das Spielerlebnis zu verbessern und
Wir sind ein kleines <a class="link" href="admins">Team</a> von Minecraft-Enthusiasten, das bereits im 8. Jahr
in Folge Minecraft CraftAttack organisiert. Jahr für Jahr arbeiten wir daran, das Spielerlebnis zu verbessern und
steigeren die Teilnehmerzahl.
</p>
<p>

View File

@@ -1,5 +1,6 @@
import { sleepSeconds } from './sleep.ts';
import { WEBHOOK_ENDPOINT } from 'astro:env/server';
import { logger } from '@util/log.ts';
export enum WebhookAction {
Signup = 'signup',
@@ -27,22 +28,46 @@ export type WebhookActionType<T extends WebhookAction> = {
}[T];
export async function sendWebhook<T extends WebhookAction>(action: T, data: WebhookActionType<T>) {
if (!WEBHOOK_ENDPOINT || !/^https?:\/\/.+$/.test(WEBHOOK_ENDPOINT)) return;
while (true) {
try {
const response = await fetch(WEBHOOK_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-webhook-action': action
},
body: JSON.stringify(data)
});
if (response.status === 200) return;
} catch (_) {}
await sleepSeconds(60);
if (!WEBHOOK_ENDPOINT) return;
else if (!/^(https?:\/\/[^\s,]+)(?:,(https?:\/\/[^\s,]+))*$/.test(WEBHOOK_ENDPOINT)) {
logger.warn('webhook endpoint is invalid');
return;
}
const webhookFutures = [];
for (const webhook in WEBHOOK_ENDPOINT.split(',')) {
webhookFutures.push(
(async () => {
let retries = 0;
while (retries < 3) {
try {
const response = await fetch(webhook, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-webhook-action': action
},
body: JSON.stringify(data)
});
if (response.status === 200) return;
} catch (e) {
logger.warn(
{
retry: retries + 1,
error: e
},
'error while sending webhook'
);
}
retries++;
await sleepSeconds(60);
}
})()
);
}
await Promise.all(webhookFutures);
}