0

Initiates a direct external upload

by
Published Oct 17, 2025

Direct external uploads bypass the usual method of creating uploads via the POST /uploads route, and upload directly to an external provider, which by default is S3.

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
/**
8
 * Initiates a direct external upload
9
 * Direct external uploads bypass the usual method of creating uploads
10
via the POST /uploads route, and upload directly to an external provider,
11
which by default is S3.
12
 */
13
export async function main(
14
  auth: Discourse,
15
  body: {
16
    type:
17
      | "avatar"
18
      | "profile_background"
19
      | "card_background"
20
      | "custom_emoji"
21
      | "composer";
22
    file_name: string;
23
    file_size: number;
24
    metadata?: { "sha1-checksum"?: string };
25
  },
26
) {
27
  const url = new URL(
28
    `https://${auth.defaultHost}/uploads/generate-presigned-put.json`,
29
  );
30

31
  const response = await fetch(url, {
32
    method: "POST",
33
    headers: {
34
      "Content-Type": "application/json",
35
      "API-KEY": auth.apiKey,
36
      "API-USERNAME": auth.apiUsername,
37
    },
38
    body: JSON.stringify(body),
39
  });
40
  if (!response.ok) {
41
    const text = await response.text();
42
    throw new Error(`${response.status} ${text}`);
43
  }
44
  return await response.json();
45
}
46