all repos — stealth-developers @ ee215b29818f3508540cbb868b5699e6645acc44

apps/api/scripts/upload-asset.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
import config from "@stealth-developers/config";
import fs from "fs";
import path from "path";

const args = process.argv.slice(2);
const filepath = args[0];
const assetKey = args[1];

const APP_ID = config.discord.app_id;
const BOT_TOKEN = config.discord.token;
const FILE_PATH = filepath;
const ASSET_KEY = assetKey;

const MIME_TYPES = {
	".png": "image/png",
	".jpg": "image/jpeg",
	".jpeg": "image/jpeg",
} as const;

async function uploadApplicationAsset() {
	if (!FILE_PATH || !ASSET_KEY) {
		console.error("usage: command <path> <assetKey>");
		process.exit(1);
	}

	const stats = fs.statSync(FILE_PATH);
	const fileSize = stats.size;
	const fileName = path.basename(FILE_PATH);
	const fileExt = path.extname(FILE_PATH);
	const fileMimeType = MIME_TYPES[fileExt as keyof typeof MIME_TYPES];

	if (!fileMimeType) throw new Error("Unsupported file type");

	const initResponse = await fetch(
		`https://discord.com/api/v10/applications/${APP_ID}/assets/upload`,
		{
			method: "POST",
			headers: {
				Authorization: `Bot ${BOT_TOKEN}`,
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				filename: fileName,
				file_size: fileSize,
			}),
		},
	);

	if (!initResponse.ok) {
		const errorText = await initResponse.text();
		throw new Error(`Step 1 Failed: ${initResponse.status} - ${errorText}`);
	}

	const uploadMetadata = (await initResponse.json()) as {
		upload_url: string;
		upload_filename: string;
	};
	const { upload_url, upload_filename } = uploadMetadata;

	const fileStream = fs.createReadStream(FILE_PATH);

	const uploadResponse = await fetch(upload_url, {
		method: "PUT",
		headers: {
			"Content-Length": fileSize.toString(),
			"Content-Type": fileMimeType,
		},
		body: fileStream,
	});

	if (!uploadResponse.ok) {
		const errorText = await uploadResponse.text();
		throw new Error(`Step 2 Failed: ${uploadResponse.status} - ${errorText}`);
	}

	console.log("uploaded file to GCS.");

	const registerResponse = await fetch(
		`https://discord.com/api/v10/applications/${APP_ID}/assets`,
		{
			method: "POST",
			headers: {
				Authorization: `Bot ${BOT_TOKEN}`,
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				key: ASSET_KEY,
				upload_filename: upload_filename,
				visibility: "public",
			}),
		},
	);

	if (!registerResponse.ok) {
		const errorText = await registerResponse.text();
		throw new Error(
			`failed to register application asset: ${registerResponse.status} - ${errorText}`,
		);
	}

	const finalisedAsset = await registerResponse.json();
	console.log("registered application asset:", finalisedAsset);
}

uploadApplicationAsset().catch(console.error);