From 2075f50a8091115f1b26d87d1dab36838583a899 Mon Sep 17 00:00:00 2001 From: oddyamill <43600905+oddyamill@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:48:35 +0700 Subject: [PATCH] feat dynamic max file size --- package-lock.json | 8 ++++---- package.json | 2 +- src/command.ts | 2 +- src/constants.ts | 2 -- src/interaction.ts | 4 +++- src/utils/resolveMaxFileSize.ts | 18 ++++++++++++++++++ src/utils/resolveMedia.ts | 26 +++++++++++++------------- 7 files changed, 40 insertions(+), 22 deletions(-) create mode 100644 src/utils/resolveMaxFileSize.ts diff --git a/package-lock.json b/package-lock.json index 3681b99..06be476 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.0", "dependencies": { "@oddyamill/discord-workers": "^1.1.5", - "discord-api-types": "^0.37.98" + "discord-api-types": "^0.37.101" }, "devDependencies": { "@cloudflare/workers-types": "^4.20240117.0", @@ -744,9 +744,9 @@ "license": "MIT" }, "node_modules/discord-api-types": { - "version": "0.37.98", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.98.tgz", - "integrity": "sha512-xsH4UwmnCQl4KjAf01/p9ck9s+/vDqzHbUxPOBzo8fcVUa/hQG6qInD7Cr44KAuCM+xCxGJFSAUx450pBrX0+g==", + "version": "0.37.101", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.101.tgz", + "integrity": "sha512-2wizd94t7G3A8U5Phr3AiuL4gSvhqistDwWnlk1VLTit8BI1jWUncFqFQNdPbHqS3661+Nx/iEyIwtVjPuBP3w==", "license": "MIT" }, "node_modules/esbuild": { diff --git a/package.json b/package.json index 0c2e149..959aa6b 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,6 @@ }, "dependencies": { "@oddyamill/discord-workers": "^1.1.5", - "discord-api-types": "^0.37.98" + "discord-api-types": "^0.37.101" } } diff --git a/src/command.ts b/src/command.ts index 4506fb5..84a2cf5 100644 --- a/src/command.ts +++ b/src/command.ts @@ -37,7 +37,7 @@ export const command = async (interaction: Interaction, t: Translator, env: Env, return editResponse(interaction, { content: t(error) }) } - const media = await resolveMedia(data, response, env) + const media = await resolveMedia(data, response, interaction, env) if (media === null) { return editResponse(interaction, { content: t('video_not_supported') }) diff --git a/src/constants.ts b/src/constants.ts index 7b8b69e..08e2b7c 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,8 +2,6 @@ export const TIKTOK_ENDPOINT = 'https://tiktok.com/@/video/' export const TIKTOK_USER_ENDPOINT = 'https://tiktok.com/@' -export const MAX_FILE_LENGTH = 25 * 1024 * 1024 - // https://stackoverflow.com/questions/74077377/regular-expression-to-match-any-tiktok-video-id-and-url#comment130792938_74077377 export const TIKTOK_URL_REGEXP = /https:\/\/(?:m|www|vm|vt)?\.?tiktok\.com\/((?:.*\b(?:(?:usr|v|embed|user|video|photo)\/|\?shareId=|&item_id=)(\d+))|\w+)/ diff --git a/src/interaction.ts b/src/interaction.ts index 1b230c1..40c0187 100644 --- a/src/interaction.ts +++ b/src/interaction.ts @@ -1,8 +1,10 @@ import { APIChatInputApplicationCommandInteraction, APIMessageApplicationCommandInteraction, + APIPartialGuild, } from 'discord-api-types/v10' -export type Interaction = +export type Interaction = { guild: APIPartialGuild | null } & ( | APIChatInputApplicationCommandInteraction | APIMessageApplicationCommandInteraction +) diff --git a/src/utils/resolveMaxFileSize.ts b/src/utils/resolveMaxFileSize.ts new file mode 100644 index 0000000..a91f5a9 --- /dev/null +++ b/src/utils/resolveMaxFileSize.ts @@ -0,0 +1,18 @@ +import { GuildFeature } from 'discord-api-types/v10' +import { Interaction } from '../interaction' + +export const resolveMaxFileSize = (interaction: Interaction) => { + const features = interaction.guild?.features ?? [] + + switch (true) { + case features?.includes(GuildFeature.AnimatedBanner): + return 100 * 1024 * 1024 + + // wtf?? + case features?.includes('SEVEN_DAY_THREAD_ARCHIVE' as GuildFeature): + return 50 * 1024 * 1024 + + default: + return 25 * 1024 * 1024 + } +} diff --git a/src/utils/resolveMedia.ts b/src/utils/resolveMedia.ts index 2f2d48d..2896cd8 100644 --- a/src/utils/resolveMedia.ts +++ b/src/utils/resolveMedia.ts @@ -1,18 +1,16 @@ import { ItemStruct } from '../tiktok' -import { - TIKTOK_HEADERS, - MAX_FILE_LENGTH, - IMAGE_WORKER_CACHE_TTL, -} from '../constants' +import { TIKTOK_HEADERS, IMAGE_WORKER_CACHE_TTL } from '../constants' import { resolveCookie } from './resolveCookie' import { Env } from '../env' +import { Interaction } from '../interaction' +import { resolveMaxFileSize } from './resolveMaxFileSize' export interface Media { stream: Response format: string } -export const resolveMedia = async (tiktok: ItemStruct, response: Response, env: Env): Promise => { +export const resolveMedia = async (tiktok: ItemStruct, response: Response, interaction: Interaction, env: Env): Promise => { const init: RequestInit = { headers: { Cookie: resolveCookie(response), @@ -20,18 +18,20 @@ export const resolveMedia = async (tiktok: ItemStruct, response: Response, env: }, } + const maxFileSize = resolveMaxFileSize(interaction) + if (tiktok.imagePost !== undefined) { - return resolveImage(tiktok, init, env) + return resolveImage(tiktok, init, maxFileSize, env) } if (tiktok.video.bitrateInfo !== undefined) { - return resolveVideo(tiktok, init) + return resolveVideo(tiktok, init, maxFileSize) } return null } -const resolveImage = async (tiktok: ItemStruct, init: RequestInit, env: Env): Promise => { +const resolveImage = async (tiktok: ItemStruct, init: RequestInit, maxFileSize: number, env: Env): Promise => { const { imagePost } = tiktok if (imagePost!.images.length > 1 && env.IMAGE_WORKER_ENDPOINT !== undefined) { @@ -48,7 +48,7 @@ const resolveImage = async (tiktok: ItemStruct, init: RequestInit, env: Env): Pr if ( stream.ok && - +stream.headers.get('content-length')! <= MAX_FILE_LENGTH + +stream.headers.get('content-length')! <= maxFileSize ) { return { stream, @@ -65,9 +65,9 @@ const resolveImage = async (tiktok: ItemStruct, init: RequestInit, env: Env): Pr } } -const resolveVideo = async (tiktok: ItemStruct, init: RequestInit): Promise => { +const resolveVideo = async (tiktok: ItemStruct, init: RequestInit, maxFileSize: number): Promise => { for (const bitrateInfo of tiktok.video.bitrateInfo!) { - if (bitrateInfo.DataSize > MAX_FILE_LENGTH) { + if (bitrateInfo.DataSize > maxFileSize) { continue } @@ -78,7 +78,7 @@ const resolveVideo = async (tiktok: ItemStruct, init: RequestInit): Promise MAX_FILE_LENGTH) { + if (+stream.headers.get('content-length')! > maxFileSize) { await stream.body?.cancel() continue }