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

@@ -152,6 +152,7 @@
## Webhook
> Die env variable `WEBHOOK_ENDPOINT` muss gesetzt und eine valide HTTP URL sein.
> Es können auch mehrere Endpoints gesetzt sein, dafür müssen die URLs mit einem komma getrennt sein.
Bei bestimmten Aktionen wird an den Webhook Endpoint ein Webhook gesendet.
Die Art des Webhooks wird dabei durch den `x-webhook-action` HTTP Header angegeben und hat einen festgelegten JSON Body.

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,11 +28,21 @@ 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;
if (!WEBHOOK_ENDPOINT) return;
else if (!/^(https?:\/\/[^\s,]+)(?:,(https?:\/\/[^\s,]+))*$/.test(WEBHOOK_ENDPOINT)) {
logger.warn('webhook endpoint is invalid');
return;
}
while (true) {
const webhookFutures = [];
for (const webhook in WEBHOOK_ENDPOINT.split(',')) {
webhookFutures.push(
(async () => {
let retries = 0;
while (retries < 3) {
try {
const response = await fetch(WEBHOOK_ENDPOINT, {
const response = await fetch(webhook, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -41,8 +52,22 @@ export async function sendWebhook<T extends WebhookAction>(action: T, data: Webh
});
if (response.status === 200) return;
} catch (_) {}
} catch (e) {
logger.warn(
{
retry: retries + 1,
error: e
},
'error while sending webhook'
);
}
retries++;
await sleepSeconds(60);
}
})()
);
}
await Promise.all(webhookFutures);
}