feat: add file_hash column and related index to files table; refactor Telegram API utilities for improved file handling

This commit is contained in:
MythEclipse
2026-05-21 22:55:42 +07:00
parent 52340ee77d
commit 10c968cf01
5 changed files with 24 additions and 95 deletions
+1 -1
View File
@@ -2,6 +2,7 @@ import { findFileByPublicId } from '../db/files';
import { formatCreatedAt, getErrorMessage } from '../utils/file';
import logger from '../utils/logger';
import { checkRateLimit } from '../utils/rateLimit';
import { getBot } from '../utils/telegram';
type RequestWithParams = Request & {
params?: {
@@ -25,7 +26,6 @@ export const handleFileRedirect = async (req: RequestWithParams): Promise<Respon
return Response.json({ error: 'File not found' }, { status: 404 });
}
const { getBot } = await import('../utils/telegram');
const bot = getBot();
const fileInfo = await bot.telegram.getFile(file.telegramFileId);
+3 -10
View File
@@ -14,18 +14,13 @@ import {
getFileType,
} from '../utils/file';
import logger from '../utils/logger';
import { forwardToStorage, getBot } from '../utils/telegram';
import { forwardToStorage } from '../utils/telegram';
type UploadedFile = NewFile & {
createdAt: Date;
updatedAt: Date;
};
type TelegramFileLookup = {
mime_type?: string;
file_size?: number;
};
interface JsonUploadPayload {
file?: unknown;
fileName?: string;
@@ -57,8 +52,6 @@ const performUpload = async (
await Bun.write(tempPath, fileBuffer);
const fileStream = createReadStream(tempPath);
const result = await forwardToStorage(fileStream, fileName, getFileType(mimeType, fileName));
const bot = getBot();
const fileInfo = (await bot.telegram.getFile(result.telegramFileId)) as TelegramFileLookup;
return {
publicId: nanoid(),
@@ -67,8 +60,8 @@ const performUpload = async (
storageChatId: config.storageChatId,
storageMessageId: result.storageMessageId,
fileName,
mimeType: fileInfo.mime_type || mimeType || 'application/octet-stream',
sizeBytes: fileInfo.file_size || fileBuffer.byteLength,
mimeType: mimeType || 'application/octet-stream',
sizeBytes: fileBuffer.byteLength,
fileType: getFileType(mimeType, fileName),
uploaderId: 0,
fileHash: computeHash(fileBuffer),
+10 -38
View File
@@ -6,7 +6,6 @@ import { enqueueUpload } from './telegramQueue';
const botTokens = Array.from(new Set([config.botToken, ...config.additionalBotTokens]));
const bots = botTokens.map((token) => new Telegraf(token));
const TELEGRAM_API_URL = `https://api.telegram.org/bot${config.botToken}/`;
let currentBotIndex = 0;
@@ -69,20 +68,6 @@ interface TelegramFileInfo {
file_path: string;
}
interface TelegramGetFileResponse {
ok: boolean;
description?: string;
result: {
file_id: string;
};
}
interface TelegramGetInfoResponse {
ok: boolean;
description?: string;
result: TelegramFileInfo;
}
interface UploadedTelegramFile {
file_id?: string;
file_unique_id?: string;
@@ -256,32 +241,17 @@ export const forwardMediaGroupToStorage = async (
export const getFileInfo = async (
telegramFileId: string,
telegramFileUniqueId: string,
): Promise<TelegramFileInfo> => {
try {
const result = await fetch(`${TELEGRAM_API_URL}getFile`);
const data = (await result.json()) as TelegramGetFileResponse;
if (!data.ok) {
throw new Error(data.description || 'Telegram API error');
}
const fileId = data.result.file_id === telegramFileId ? telegramFileId : telegramFileUniqueId;
const fileResult = await fetch(`${TELEGRAM_API_URL}getInfo`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ file_id: fileId }),
});
const fileInfo = (await fileResult.json()) as TelegramGetInfoResponse;
if (!fileInfo.ok) {
throw new Error(fileInfo.description || 'Telegram info error');
}
const result = await executeWithBotRetry((activeBot) =>
activeBot.telegram.getFile(telegramFileId),
);
const fileData = result as unknown as TelegramFileInfo;
return {
file_size: fileInfo.result.file_size,
mime_type: fileInfo.result.mime_type,
file_path: fileInfo.result.file_path,
file_size: fileData.file_size || 0,
mime_type: fileData.mime_type || 'application/octet-stream',
file_path: fileData.file_path || '',
};
} catch (error: unknown) {
logger.error('Failed to get file info', {
@@ -291,4 +261,6 @@ export const getFileInfo = async (
}
};
export const getBot = (): Telegraf => bots[0];
export const getBot = (): Telegraf => bots[currentBotIndex];
export const getCurrentBotIndex = (): number => currentBotIndex;