0

Creates an upload

by
Published Oct 17, 2025
Script discourse Verified

The script

Submitted by hugo697 Bun
Verified 235 days ago
1
//native
2
type Discourse = {
3
  apiKey: string;
4
  defaultHost: string;
5
  apiUsername: string;
6
};
7
type Base64 = string;
8
/**
9
 * Creates an upload
10
 *
11
 */
12
export async function main(
13
  auth: Discourse,
14
  body: {
15
    type:
16
      | "avatar"
17
      | "profile_background"
18
      | "card_background"
19
      | "custom_emoji"
20
      | "composer";
21
    user_id?: number;
22
    synchronous?: false | true;
23
    file?: {
24
      base64: Base64;
25
      type:
26
        | "image/png"
27
        | "image/jpeg"
28
        | "image/gif"
29
        | "application/pdf"
30
        | "appication/json"
31
        | "text/csv"
32
        | "text/plain"
33
        | "audio/mpeg"
34
        | "audio/wav"
35
        | "video/mp4";
36
      name: string;
37
    };
38
  },
39
) {
40
  const url = new URL(`https://${auth.defaultHost}/uploads.json`);
41

42
  const formData = new FormData();
43
  for (const [k, v] of Object.entries(body)) {
44
    if (v !== undefined) {
45
      if (["file"].includes(k)) {
46
        const { base64, type, name } = v as {
47
          base64: Base64;
48
          type: string;
49
          name: string;
50
        };
51
        formData.append(
52
          k,
53
          new Blob([Uint8Array.from(atob(base64), (m) => m.codePointAt(0)!)], {
54
            type,
55
          }),
56
          name,
57
        );
58
      } else {
59
        formData.append(k, String(v));
60
      }
61
    }
62
  }
63
  const response = await fetch(url, {
64
    method: "POST",
65
    headers: {
66
      "API-KEY": auth.apiKey,
67
      "API-USERNAME": auth.apiUsername,
68
    },
69
    body: formData,
70
  });
71
  if (!response.ok) {
72
    const text = await response.text();
73
    throw new Error(`${response.status} ${text}`);
74
  }
75
  return await response.json();
76
}
77