kaneo (minimalist kanban) fork to experiment adding a tangled integration
github.com/usekaneo/kaneo
1type DiscordEmbedField = {
2 name: string;
3 value: string;
4 inline?: boolean;
5};
6
7type DiscordEmbed = {
8 title?: string;
9 description?: string;
10 url?: string;
11 color?: number;
12 fields?: DiscordEmbedField[];
13 footer?: {
14 text: string;
15 };
16};
17
18type DiscordMessage = {
19 content?: string;
20 embeds?: DiscordEmbed[];
21};
22
23const DISCORD_TIMEOUT_MS = 10_000;
24
25export async function postToDiscord(
26 webhookUrl: string,
27 message: DiscordMessage,
28): Promise<void> {
29 const controller = new AbortController();
30 const timeoutId = setTimeout(() => controller.abort(), DISCORD_TIMEOUT_MS);
31
32 try {
33 const response = await fetch(webhookUrl, {
34 method: "POST",
35 headers: {
36 "Content-Type": "application/json",
37 },
38 body: JSON.stringify(message),
39 signal: controller.signal,
40 });
41
42 if (!response.ok) {
43 const errorText = await response.text();
44 throw new Error(
45 `Discord webhook request failed (${response.status}): ${errorText}`,
46 );
47 }
48 } catch (error) {
49 if (error instanceof Error && error.name === "AbortError") {
50 throw new Error(
51 `Discord webhook request timed out after ${DISCORD_TIMEOUT_MS}ms`,
52 );
53 }
54
55 throw error;
56 } finally {
57 clearTimeout(timeoutId);
58 }
59}