Files
umbrix/lib/core/telegram/telegram_logger.dart
2026-01-15 12:28:40 +03:00

117 lines
3.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:hiddify/core/telegram_config.dart';
import 'package:hiddify/utils/utils.dart';
/// Сервис для анонимной отправки логов в Telegram
class TelegramLogger with InfraLogger {
static const int maxLogSize = 4096; // Telegram ограничение на текст сообщения
static const int maxFileSize = 50 * 1024 * 1024; // 50MB максимум для файла
final Dio _dio = Dio(
BaseOptions(
connectTimeout: const Duration(seconds: 10),
receiveTimeout: const Duration(seconds: 10),
),
);
/// Отправить логи как текстовое сообщение (для коротких логов)
Future<bool> sendLogsAsText(String logs, {String? deviceInfo}) async {
if (!TelegramConfig.isConfigured) {
loggy.warning('Telegram not configured');
return false;
}
try {
final message = _formatMessage(logs, deviceInfo);
final response = await _dio.post(
'https://api.telegram.org/bot${TelegramConfig.botToken}/sendMessage',
data: {
'chat_id': TelegramConfig.chatId,
'text': message,
'parse_mode': 'HTML',
},
);
return response.statusCode == 200;
} catch (e) {
loggy.error('Failed to send logs to Telegram', e);
return false;
}
}
/// Отправить файл логов (для больших логов)
Future<bool> sendLogsAsFile(File logFile, {String? deviceInfo}) async {
if (!TelegramConfig.isConfigured) {
loggy.warning('Telegram not configured');
return false;
}
try {
// Проверка размера файла
final fileSize = await logFile.length();
if (fileSize > maxFileSize) {
loggy.warning('Log file too large: $fileSize bytes');
return false;
}
final fileName = logFile.path.split('/').last;
final caption = deviceInfo != null ? '📱 Device: $deviceInfo\n📅 ${DateTime.now().toIso8601String()}' : '📅 ${DateTime.now().toIso8601String()}';
final formData = FormData.fromMap({
'chat_id': TelegramConfig.chatId,
'document': await MultipartFile.fromFile(
logFile.path,
filename: fileName,
),
'caption': caption,
});
final response = await _dio.post(
'https://api.telegram.org/bot${TelegramConfig.botToken}/sendDocument',
data: formData,
);
return response.statusCode == 200;
} catch (e) {
loggy.error('Failed to send log file to Telegram', e);
return false;
}
}
String _formatMessage(String logs, String? deviceInfo) {
final header = deviceInfo != null ? '📱 <b>Umbrix Logs</b>\nDevice: $deviceInfo\n' : '📱 <b>Umbrix Logs</b>\n';
final timestamp = '📅 ${DateTime.now().toIso8601String()}\n';
const separator = '━━━━━━━━━━━━━━━━\n';
// Обрезаем логи если они слишком длинные
var logContent = logs;
final maxContentSize = maxLogSize - header.length - timestamp.length - separator.length - 50;
if (logContent.length > maxContentSize) {
logContent = '${logContent.substring(0, maxContentSize)}\n\n... (truncated)';
}
return '$header$timestamp$separator$logContent';
}
/// Получить информацию об устройстве для логов (анонимно)
static String getAnonymousDeviceInfo() {
// Только общая информация без идентификаторов
if (Platform.isAndroid) {
return 'Android ${Platform.operatingSystemVersion}';
} else if (Platform.isIOS) {
return 'iOS ${Platform.operatingSystemVersion}';
} else if (Platform.isWindows) {
return 'Windows';
} else if (Platform.isMacOS) {
return 'macOS';
} else if (Platform.isLinux) {
return 'Linux';
}
return 'Unknown OS';
}
}