2026-05-18 07:06:21 +07:00
|
|
|
import { Telegraf } from 'telegraf';
|
2026-05-18 07:27:06 +07:00
|
|
|
import logger from './logger';
|
|
|
|
|
import { config } from '../env';
|
2026-05-18 07:06:21 +07:00
|
|
|
|
|
|
|
|
const bot = new Telegraf(config.botToken);
|
|
|
|
|
const TELEGRAM_API_URL = `https://api.telegram.org/bot${config.botToken}/`;
|
|
|
|
|
|
2026-05-18 07:27:06 +07:00
|
|
|
interface ForwardResult {
|
|
|
|
|
telegramFileId: string;
|
|
|
|
|
telegramFileUniqueId: string;
|
|
|
|
|
storageMessageId: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface TelegramFileInfo {
|
|
|
|
|
file_size: number;
|
|
|
|
|
mime_type: string;
|
|
|
|
|
file_path: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const forwardToStorage = async (
|
|
|
|
|
fileChunk: any,
|
|
|
|
|
fileName: string,
|
|
|
|
|
forceDocument = false
|
|
|
|
|
): Promise<ForwardResult> => {
|
2026-05-18 07:06:21 +07:00
|
|
|
try {
|
|
|
|
|
const caption = forceDocument ? `📁 ${fileName}` : fileName;
|
2026-05-18 07:27:06 +07:00
|
|
|
const input: any = forceDocument ? { document: fileChunk, caption } : { photo: [fileChunk], caption };
|
2026-05-18 07:06:21 +07:00
|
|
|
|
2026-05-18 07:27:06 +07:00
|
|
|
const result = await bot.telegram.sendPhoto(config.storageChatId, input);
|
2026-05-18 07:06:21 +07:00
|
|
|
|
|
|
|
|
logger.info('File forwarded to storage', { fileName, message: result.message_id });
|
|
|
|
|
|
|
|
|
|
return {
|
2026-05-18 07:27:06 +07:00
|
|
|
telegramFileId: result.photo?.slice(-1)[0]?.file_id || '',
|
|
|
|
|
telegramFileUniqueId: result.photo?.slice(-1)[0]?.file_unique_id || '',
|
2026-05-18 07:06:21 +07:00
|
|
|
storageMessageId: result.message_id
|
|
|
|
|
};
|
2026-05-18 07:27:06 +07:00
|
|
|
} catch (error: any) {
|
2026-05-18 07:06:21 +07:00
|
|
|
logger.error('Failed to forward file to storage', { fileName, error: error.message });
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-18 07:27:06 +07:00
|
|
|
export const getFileInfo = async (
|
|
|
|
|
telegramFileId: string,
|
|
|
|
|
telegramFileUniqueId: string
|
|
|
|
|
): Promise<TelegramFileInfo> => {
|
2026-05-18 07:06:21 +07:00
|
|
|
try {
|
|
|
|
|
const result = await fetch(`${TELEGRAM_API_URL}getFile`);
|
2026-05-18 07:27:06 +07:00
|
|
|
const data: any = await result.json();
|
2026-05-18 07:06:21 +07:00
|
|
|
|
|
|
|
|
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 })
|
|
|
|
|
});
|
2026-05-18 07:27:06 +07:00
|
|
|
const fileInfo: any = await fileResult.json();
|
2026-05-18 07:06:21 +07:00
|
|
|
|
|
|
|
|
if (!fileInfo.ok) {
|
|
|
|
|
throw new Error(fileInfo.description || 'Telegram info error');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
file_size: fileInfo.result.file_size,
|
|
|
|
|
mime_type: fileInfo.result.mime_type,
|
|
|
|
|
file_path: fileInfo.result.file_path
|
|
|
|
|
};
|
2026-05-18 07:27:06 +07:00
|
|
|
} catch (error: any) {
|
2026-05-18 07:06:21 +07:00
|
|
|
logger.error('Failed to get file info', { error: error.message });
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2026-05-18 07:27:06 +07:00
|
|
|
export const getBot = (): Telegraf => bot;
|