// Telegram Bot для отправки изображений в ЛС const axios = require('axios'); const FormData = require('form-data'); const config = require('./config'); if (!config.telegramBotToken) { console.warn('⚠️ TELEGRAM_BOT_TOKEN не установлен! Функция отправки фото в Telegram недоступна.'); } const TELEGRAM_API = config.telegramBotToken ? `https://api.telegram.org/bot${config.telegramBotToken}` : null; // Получить оригинальный URL из прокси URL function getOriginalUrl(proxyUrl) { if (!proxyUrl || !proxyUrl.startsWith('/api/search/proxy/')) { return proxyUrl; } try { // Извлекаем encodedUrl из прокси URL const encodedUrl = proxyUrl.replace('/api/search/proxy/', ''); // Декодируем base64 const originalUrl = Buffer.from(encodedUrl, 'base64').toString('utf-8'); return originalUrl; } catch (error) { console.error('Ошибка декодирования прокси URL:', error); return proxyUrl; } } // Отправить одно фото пользователю async function sendPhotoToUser(userId, photoUrl, caption) { if (!TELEGRAM_API) { throw new Error('TELEGRAM_BOT_TOKEN не установлен'); } try { // Получаем оригинальный URL (если это прокси URL) let finalPhotoUrl = getOriginalUrl(photoUrl); // Если это все еще относительный URL (локальный файл), используем публичный URL if (finalPhotoUrl.startsWith('/')) { const baseUrl = process.env.FRONTEND_URL || process.env.API_URL || 'https://nakama.glpshchn.ru'; finalPhotoUrl = `${baseUrl}${finalPhotoUrl}`; } // Проверяем, является ли URL публично доступным для Telegram // Если это оригинальный URL от e621/gelbooru, используем его напрямую const isPublicUrl = finalPhotoUrl.includes('e621.net') || finalPhotoUrl.includes('gelbooru.com') || finalPhotoUrl.includes('nakama.glpshchn.ru'); if (isPublicUrl) { // Используем публичный URL напрямую const response = await axios.post(`${TELEGRAM_API}/sendPhoto`, { chat_id: userId, photo: finalPhotoUrl, caption: caption || '', parse_mode: 'HTML' }); return response.data; } else { // Если URL не публичный, скачиваем изображение и отправляем как файл const imageResponse = await axios.get(finalPhotoUrl, { responseType: 'stream', timeout: 30000 }); const form = new FormData(); form.append('chat_id', userId); form.append('photo', imageResponse.data, { filename: 'image.jpg', contentType: imageResponse.headers['content-type'] || 'image/jpeg' }); if (caption) { form.append('caption', caption); } form.append('parse_mode', 'HTML'); const response = await axios.post(`${TELEGRAM_API}/sendPhoto`, form, { headers: form.getHeaders() }); return response.data; } } catch (error) { console.error('Ошибка отправки фото:', error.response?.data || error.message); throw error; } } // Отправить несколько фото группой (до 10 штук) async function sendPhotosToUser(userId, photos) { if (!TELEGRAM_API) { throw new Error('TELEGRAM_BOT_TOKEN не установлен'); } try { // Telegram поддерживает до 10 фото в одной группе const batches = []; for (let i = 0; i < photos.length; i += 10) { batches.push(photos.slice(i, i + 10)); } const results = []; for (const batch of batches) { const media = []; for (let index = 0; index < batch.length; index++) { const photo = batch[index]; // Получаем оригинальный URL (если это прокси URL) let photoUrl = getOriginalUrl(photo.url); // Если это относительный URL, преобразуем в полный if (photoUrl.startsWith('/')) { const baseUrl = process.env.FRONTEND_URL || process.env.API_URL || 'https://nakama.glpshchn.ru'; photoUrl = `${baseUrl}${photoUrl}`; } // Проверяем, является ли URL публично доступным const isPublicUrl = photoUrl.includes('e621.net') || photoUrl.includes('gelbooru.com') || photoUrl.includes('nakama.glpshchn.ru'); if (isPublicUrl) { // Используем публичный URL напрямую media.push({ type: 'photo', media: photoUrl, caption: index === 0 ? `Из NakamaSpace\n${batch.length} фото` : undefined, parse_mode: 'HTML' }); } else { // Для непубличных URL нужно скачать изображение // Но в sendMediaGroup нельзя смешивать URL и файлы // Поэтому используем URL как есть (Telegram попробует загрузить) media.push({ type: 'photo', media: photoUrl, caption: index === 0 ? `Из NakamaSpace\n${batch.length} фото` : undefined, parse_mode: 'HTML' }); } } const response = await axios.post(`${TELEGRAM_API}/sendMediaGroup`, { chat_id: userId, media: media }); results.push(response.data); } return results; } catch (error) { console.error('Ошибка отправки фото группой:', error.response?.data || error.message); throw error; } } // Обработать данные от Web App async function handleWebAppData(userId, dataString) { try { const data = JSON.parse(dataString); if (data.action === 'send_image') { const caption = `Из NakamaSpace\n\n${data.caption || ''}`; await sendPhotoToUser(userId, data.url, caption); return { success: true, message: 'Изображение отправлено!' }; } return { success: false, message: 'Неизвестное действие' }; } catch (error) { console.error('Ошибка обработки данных:', error); return { success: false, message: error.message }; } } module.exports = { sendPhotoToUser, sendPhotosToUser, handleWebAppData };