add support for multiple webhook endpoints
All checks were successful
deploy / build-and-deploy (push) Successful in 17s
All checks were successful
deploy / build-and-deploy (push) Successful in 17s
This commit is contained in:
@@ -152,6 +152,7 @@
|
|||||||
## Webhook
|
## Webhook
|
||||||
|
|
||||||
> Die env variable `WEBHOOK_ENDPOINT` muss gesetzt und eine valide HTTP URL sein.
|
> 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.
|
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.
|
Die Art des Webhooks wird dabei durch den `x-webhook-action` HTTP Header angegeben und hat einen festgelegten JSON Body.
|
||||||
|
|||||||
@@ -91,8 +91,8 @@ const information = [
|
|||||||
<div>
|
<div>
|
||||||
<h2 class="text-3xl text-black dark:text-white mb-8">Über uns</h2>
|
<h2 class="text-3xl text-black dark:text-white mb-8">Über uns</h2>
|
||||||
<p>
|
<p>
|
||||||
Wir sind ein kleines <a class="link" href="admins">Team</a> von Minecraft-Enthusiasten, das bereits im 8. Jahr in
|
Wir sind ein kleines <a class="link" href="admins">Team</a> von Minecraft-Enthusiasten, das bereits im 8. Jahr
|
||||||
Folge Minecraft CraftAttack organisiert. Jahr für Jahr arbeiten wir daran, das Spielerlebnis zu verbessern und
|
in Folge Minecraft CraftAttack organisiert. Jahr für Jahr arbeiten wir daran, das Spielerlebnis zu verbessern und
|
||||||
steigeren die Teilnehmerzahl.
|
steigeren die Teilnehmerzahl.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { sleepSeconds } from './sleep.ts';
|
import { sleepSeconds } from './sleep.ts';
|
||||||
import { WEBHOOK_ENDPOINT } from 'astro:env/server';
|
import { WEBHOOK_ENDPOINT } from 'astro:env/server';
|
||||||
|
import { logger } from '@util/log.ts';
|
||||||
|
|
||||||
export enum WebhookAction {
|
export enum WebhookAction {
|
||||||
Signup = 'signup',
|
Signup = 'signup',
|
||||||
@@ -27,22 +28,46 @@ export type WebhookActionType<T extends WebhookAction> = {
|
|||||||
}[T];
|
}[T];
|
||||||
|
|
||||||
export async function sendWebhook<T extends WebhookAction>(action: T, data: WebhookActionType<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)) {
|
||||||
while (true) {
|
logger.warn('webhook endpoint is invalid');
|
||||||
try {
|
return;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user