2022-09-03 18:11:04 +00:00
|
|
|
import config from "./config.ts";
|
2022-09-06 01:56:57 +00:00
|
|
|
import { requestLog, sleep } from "./util.ts";
|
2022-09-03 18:11:04 +00:00
|
|
|
|
|
|
|
export async function sendWebhook(
|
|
|
|
id: string,
|
|
|
|
token: string,
|
2022-09-06 01:56:57 +00:00
|
|
|
headers: Headers,
|
2023-07-10 19:13:11 +00:00
|
|
|
data: Record<string, any>,
|
2022-09-06 02:16:06 +00:00
|
|
|
): Promise<[Response, Record<string, string>]> {
|
2022-09-06 01:56:57 +00:00
|
|
|
const reqLog = requestLog(headers);
|
2022-09-03 18:11:04 +00:00
|
|
|
const url = `https://discord.com/api/webhooks/${id}/${token}/github?wait=1`;
|
2023-07-10 19:13:11 +00:00
|
|
|
const body = JSON.stringify(data);
|
2022-09-03 18:11:04 +00:00
|
|
|
|
|
|
|
let res: Response;
|
|
|
|
let retries = 0;
|
|
|
|
do {
|
|
|
|
const req = new Request(url, {
|
|
|
|
method: "POST",
|
|
|
|
headers: headers,
|
|
|
|
body: body,
|
|
|
|
});
|
|
|
|
|
2022-09-06 01:56:57 +00:00
|
|
|
reqLog.info(`sending webhook request to ${url}`);
|
2022-09-03 18:11:04 +00:00
|
|
|
res = await fetch(req);
|
|
|
|
|
|
|
|
// return response if everything's fine
|
|
|
|
if (res.status !== 429) break;
|
|
|
|
|
|
|
|
const reset = res.headers.get("retry-after");
|
|
|
|
// should always exist, even for cf bans, but checking anyway
|
|
|
|
if (reset === null) break;
|
|
|
|
|
2022-09-04 14:28:52 +00:00
|
|
|
// parse retry delay
|
|
|
|
let resetms = parseFloat(reset);
|
|
|
|
if (!res.headers.has("via")) {
|
|
|
|
// if there's no `via` header, this is likely a cf ban, which uses seconds instead of milliseconds
|
|
|
|
resetms *= 1000;
|
|
|
|
}
|
|
|
|
|
2022-09-03 18:11:04 +00:00
|
|
|
// if we'd wait longer than the configured limit, just return the 429
|
2022-09-04 13:08:35 +00:00
|
|
|
if (resetms > config.maxWebhookRetryMs) {
|
2024-02-01 16:30:36 +00:00
|
|
|
reqLog.warn(
|
2022-09-04 13:08:35 +00:00
|
|
|
`ratelimited for ${resetms}ms (> ${config.maxWebhookRetryMs}ms), not retrying`,
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
2022-09-03 18:11:04 +00:00
|
|
|
|
2022-09-04 13:00:53 +00:00
|
|
|
// maybe wait and retry
|
2022-09-04 13:08:35 +00:00
|
|
|
if (retries >= config.maxWebhookRetries) {
|
2024-02-01 16:30:36 +00:00
|
|
|
reqLog.warn(`reached maximum number of retries (${retries})`);
|
2022-09-04 13:08:35 +00:00
|
|
|
break;
|
|
|
|
}
|
2022-09-03 18:11:04 +00:00
|
|
|
retries++;
|
2024-02-01 16:30:36 +00:00
|
|
|
reqLog.warn(`retrying after ${resetms}ms (retry ${retries})`);
|
2022-09-04 13:00:53 +00:00
|
|
|
await sleep(resetms);
|
|
|
|
} while (true);
|
2022-09-04 13:34:19 +00:00
|
|
|
|
2022-09-06 02:16:06 +00:00
|
|
|
// set metadata
|
|
|
|
const meta: Record<string, string> = {};
|
2022-09-04 13:34:19 +00:00
|
|
|
if (retries) meta["retries"] = retries.toString();
|
|
|
|
|
2022-09-06 02:16:06 +00:00
|
|
|
return [res, meta];
|
2022-09-04 13:34:19 +00:00
|
|
|
}
|