export interface TelegramFileResult { file_id: string; file_unique_id: string; file_path?: string; file_size?: number; } export interface TelegramUpdate { update_id: number; message?: { message_id: number; from: { id: number; first_name: string; username?: string; }; chat: { id: number; type: string; }; text?: string; photo?: Array<{ file_id: string; file_unique_id: string; file_size: number; width: number; height: number; }>; document?: { file_id: string; file_unique_id: string; file_name?: string; mime_type?: string; file_size: number; }; animation?: { file_id: string; file_unique_id: string; file_size: number; mime_type?: string; }; reply_to_message?: { message_id: number; photo?: Array<{ file_id: string; file_unique_id: string; file_size: number; width: number; height: number; }>; document?: { file_id: string; file_unique_id: string; file_name?: string; mime_type?: string; file_size: number; }; animation?: { file_id: string; file_unique_id: string; file_size: number; mime_type?: string; }; }; }; } export async function uploadToTelegram(file: Blob, fileName: string, caption?: string, mediaType: 'photo' | 'animation' | 'video' = 'photo'): Promise { const token = process.env.TELEGRAM_BOT_TOKEN; const chatId = process.env.TELEGRAM_CHAT_ID; if (!token || !chatId) { throw new Error('Telegram credentials not configured'); } const formData = new FormData(); formData.append('chat_id', chatId); let method = 'sendPhoto'; let fieldName = 'photo'; if (mediaType === 'animation') { method = 'sendAnimation'; fieldName = 'animation'; } else if (mediaType === 'video') { method = 'sendVideo'; fieldName = 'video'; } formData.append(fieldName, file, fileName); if (caption) { formData.append('caption', caption); formData.append('parse_mode', 'HTML'); } const response = await fetch(`https://api.telegram.org/bot${token}/${method}`, { method: 'POST', body: formData, }); const data = await response.json(); if (!data.ok) { throw new Error(`Telegram API error: ${data.description}`); } let fileId = ''; let fileUniqueId = ''; if (mediaType === 'animation') { // For animations, it's a single object in 'animation' or 'document' field const fileInfo = data.result.animation || data.result.document; fileId = fileInfo.file_id; fileUniqueId = fileInfo.file_unique_id; } else if (mediaType === 'video') { const fileInfo = data.result.video || data.result.document; fileId = fileInfo.file_id; fileUniqueId = fileInfo.file_unique_id; } else { // For photos, it's an array of sizes const photos = data.result.photo; const largestPhoto = photos[photos.length - 1]; fileId = largestPhoto.file_id; fileUniqueId = largestPhoto.file_unique_id; } return { file_id: fileId, file_unique_id: fileUniqueId, }; } export async function getTelegramFileUrl(fileId: string): Promise { const token = process.env.TELEGRAM_BOT_TOKEN; if (!token) { throw new Error('Telegram token not configured'); } const response = await fetch(`https://api.telegram.org/bot${token}/getFile?file_id=${fileId}`); const data = await response.json(); if (!data.ok) { throw new Error(`Telegram API error: ${data.description}`); } const filePath = data.result.file_path; return `https://api.telegram.org/file/bot${token}/${filePath}`; } /** * Download file from Telegram by file_id */ export async function downloadTelegramFile(fileId: string): Promise { const fileUrl = await getTelegramFileUrl(fileId); const response = await fetch(fileUrl); if (!response.ok) { throw new Error(`Failed to download file from Telegram: ${response.statusText}`); } return response.blob(); } export async function sendMessage(chatId: number | string, text: string, parseMode: 'HTML' | 'Markdown' = 'HTML', replyMarkup?: any): Promise { const token = process.env.TELEGRAM_BOT_TOKEN; if (!token) return; await fetch(`https://api.telegram.org/bot${token}/sendMessage`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ chat_id: chatId, text, parse_mode: parseMode, disable_web_page_preview: false, reply_markup: replyMarkup }), }); } export async function sendMediaToChannel(fileId: string, caption: string, mediaType: 'photo' | 'animation' | 'video' = 'photo'): Promise { const token = process.env.TELEGRAM_BOT_TOKEN; const chatId = process.env.TELEGRAM_CHAT_ID; if (!token || !chatId) return; let method = 'sendPhoto'; if (mediaType === 'animation') method = 'sendAnimation'; if (mediaType === 'video') method = 'sendVideo'; const body: any = { chat_id: chatId, caption, parse_mode: 'HTML' }; if (mediaType === 'animation') { body.animation = fileId; } else if (mediaType === 'video') { body.video = fileId; } else { body.photo = fileId; } await fetch(`https://api.telegram.org/bot${token}/${method}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), }); } export async function sendLog(text: string): Promise { const logChannelId = process.env.TELEGRAM_LOG_CHANNEL_ID; if (!logChannelId) return; await sendMessage(logChannelId, text, 'HTML'); }