diff --git a/TELEGRAM_MESSAGING.md b/TELEGRAM_MESSAGING.md
index cedcc58..457c95c 100644
--- a/TELEGRAM_MESSAGING.md
+++ b/TELEGRAM_MESSAGING.md
@@ -129,12 +129,34 @@ python send_telegram_example.py 123456789 "Привет! Это тестовое
Система обрабатывает следующие типы ошибок:
+### HTTP ошибки:
1. **401 Unauthorized** - Неверный или отсутствующий API токен
-2. **403 Forbidden** - Пользователь заблокировал бота или не начал с ним диалог
-3. **400 Bad Request** - Неверный ID пользователя или отсутствующие данные
-4. **429 Too Many Requests** - Превышен лимит отправки сообщений
-5. **Пустое сообщение** - Не указан текст сообщения
-6. **Неверный формат ID** - user_id не является числом
+2. **400 Bad Request** - Неверный ID пользователя или отсутствующие данные
+3. **500 Internal Server Error** - Внутренняя ошибка сервера
+
+### Коды ошибок API:
+- `INVALID_TOKEN` - Неверный токен аутентификации
+- `NO_DATA` - Отсутствуют данные в запросе
+- `NO_USER_ID` - Не указан ID пользователя
+- `NO_MESSAGE` - Не указан текст сообщения
+- `INVALID_USER_ID` - user_id не является числом
+- `TELEGRAM_ERROR` - Ошибка Telegram API
+- `INTERNAL_ERROR` - Внутренняя ошибка сервера
+
+### Ошибки Telegram API:
+1. **403 Forbidden** - Пользователь заблокировал бота или не начал с ним диалог
+2. **400 Bad Request** - Неверный ID пользователя
+3. **429 Too Many Requests** - Превышен лимит отправки сообщений
+4. **404 Not Found** - Пользователь не найден
+
+### Диагностика в веб-интерфейсе
+
+Веб-интерфейс предоставляет подробную диагностику ошибок:
+- **Время ответа** сервера
+- **HTTP статус** код
+- **Код ошибки** API
+- **Конкретные предложения** по решению проблемы
+- **Автоматическое скрытие** уведомлений
Все ошибки логируются в файл логов с указанием типа ошибки и ID пользователя.
diff --git a/templates/index.html b/templates/index.html
index 44beb49..dd1682c 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -2125,13 +2125,13 @@
// Проверяем, что оба поля заполнены
if (!userId || !message) {
- alert('Пожалуйста, заполните оба поля: ID пользователя и сообщение');
+ showTelegramError('Пожалуйста, заполните оба поля: ID пользователя и сообщение', 'VALIDATION_ERROR');
return;
}
// Проверяем, что user_id является числом
if (isNaN(userId)) {
- alert('ID пользователя должен быть числом');
+ showTelegramError('ID пользователя должен быть числом', 'VALIDATION_ERROR');
return;
}
@@ -2141,6 +2141,11 @@
sendBtn.innerHTML = ' Отправка...';
sendBtn.disabled = true;
+ // Скрываем предыдущие ошибки
+ hideTelegramError();
+
+ const startTime = Date.now();
+
try {
const response = await fetch(`http://localhost:${BOT_PORT}/send_message`, {
method: 'POST',
@@ -2154,19 +2159,63 @@
})
});
- const result = await response.json();
+ const responseTime = Date.now() - startTime;
- if (result.success) {
- alert('Сообщение отправлено успешно!');
- // Очищаем поля
- document.getElementById('telegram-user-id').value = '';
- document.getElementById('telegram-message').value = '';
+ if (response.ok) {
+ const result = await response.json();
+
+ if (result.success) {
+ showTelegramSuccess('Сообщение отправлено успешно!', responseTime);
+ // Очищаем поля
+ document.getElementById('telegram-user-id').value = '';
+ document.getElementById('telegram-message').value = '';
+ } else {
+ const errorCode = result.error_code || 'UNKNOWN_ERROR';
+ showTelegramError(`Ошибка отправки сообщения: ${result.error}`, 'API_ERROR', {
+ status: response.status,
+ responseTime: responseTime,
+ userId: userId,
+ errorCode: errorCode
+ });
+ }
} else {
- alert('Ошибка отправки сообщения: ' + result.error);
+ // Обрабатываем HTTP ошибки
+ let errorText = '';
+ try {
+ const errorResult = await response.json();
+ errorText = errorResult.error || 'Неизвестная ошибка';
+ } catch (e) {
+ errorText = `HTTP ${response.status}: ${response.statusText}`;
+ }
+
+ showTelegramError(`Ошибка сервера: ${errorText}`, 'HTTP_ERROR', {
+ status: response.status,
+ statusText: response.statusText,
+ responseTime: responseTime,
+ userId: userId
+ });
}
} catch (error) {
+ const responseTime = Date.now() - startTime;
console.error('Ошибка при отправке сообщения:', error);
- alert('Произошла ошибка при отправке сообщения. Проверьте консоль для подробностей.');
+
+ let errorType = 'NETWORK_ERROR';
+ let errorMessage = 'Ошибка сети при отправке сообщения';
+
+ if (error.name === 'TypeError' && error.message.includes('fetch')) {
+ errorMessage = 'Не удается подключиться к серверу бота. Проверьте, что бот запущен.';
+ errorType = 'CONNECTION_ERROR';
+ } else if (error.name === 'AbortError') {
+ errorMessage = 'Запрос был прерван по таймауту';
+ errorType = 'TIMEOUT_ERROR';
+ }
+
+ showTelegramError(errorMessage, errorType, {
+ errorName: error.name,
+ errorMessage: error.message,
+ responseTime: responseTime,
+ userId: userId
+ });
} finally {
// Восстанавливаем кнопку
sendBtn.innerHTML = originalText;
@@ -2174,6 +2223,146 @@
}
}
+ // Функция для показа успешного результата
+ function showTelegramSuccess(message, responseTime) {
+ const alertDiv = document.createElement('div');
+ alertDiv.className = 'alert alert-success alert-dismissible fade show position-fixed';
+ alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 300px;';
+ alertDiv.innerHTML = `
+
+
+
+ Успех!
+ ${message}
+ Время ответа: ${responseTime}мс
+
+
+
+ `;
+ document.body.appendChild(alertDiv);
+
+ // Автоматически скрываем через 5 секунд
+ setTimeout(() => {
+ if (alertDiv.parentNode) {
+ alertDiv.remove();
+ }
+ }, 5000);
+ }
+
+ // Функция для показа ошибки с подробной диагностикой
+ function showTelegramError(message, errorType, details = {}) {
+ const alertDiv = document.createElement('div');
+ alertDiv.className = 'alert alert-danger alert-dismissible fade show position-fixed';
+ alertDiv.style.cssText = 'top: 20px; right: 20px; z-index: 9999; min-width: 400px; max-width: 600px;';
+
+ let diagnosticInfo = '';
+ let suggestions = '';
+
+ // Генерируем диагностическую информацию в зависимости от типа ошибки
+ switch (errorType) {
+ case 'VALIDATION_ERROR':
+ suggestions = 'Решение: Проверьте правильность введенных данных';
+ break;
+
+ case 'API_ERROR':
+ diagnosticInfo = `
+
+
+ Диагностика:
+ • Статус: ${details.status || 'N/A'}
+ • Время ответа: ${details.responseTime || 'N/A'}мс
+ • ID пользователя: ${details.userId || 'N/A'}
+ • Код ошибки: ${details.errorCode || 'N/A'}
+
+
+ `;
+
+ // Специфичные предложения в зависимости от кода ошибки
+ switch (details.errorCode) {
+ case 'INVALID_TOKEN':
+ suggestions = 'Решение: Проблема с аутентификацией. Проверьте настройки токена в системе.';
+ break;
+ case 'NO_DATA':
+ case 'NO_USER_ID':
+ case 'NO_MESSAGE':
+ case 'INVALID_USER_ID':
+ suggestions = 'Решение: Проверьте правильность заполнения полей формы.';
+ break;
+ case 'TELEGRAM_ERROR':
+ suggestions = 'Возможные причины:
• Пользователь заблокировал бота
• Неверный ID пользователя
• Пользователь не начал диалог с ботом
• Превышен лимит отправки сообщений';
+ break;
+ case 'INTERNAL_ERROR':
+ suggestions = 'Решение: Внутренняя ошибка сервера. Проверьте логи бота или обратитесь к администратору.';
+ break;
+ default:
+ suggestions = 'Возможные причины:
• Пользователь заблокировал бота
• Неверный ID пользователя
• Пользователь не начал диалог с ботом';
+ }
+ break;
+
+ case 'HTTP_ERROR':
+ diagnosticInfo = `
+
+
+ Диагностика:
+ • HTTP статус: ${details.status || 'N/A'} ${details.statusText || ''}
+ • Время ответа: ${details.responseTime || 'N/A'}мс
+ • ID пользователя: ${details.userId || 'N/A'}
+
+
+ `;
+ if (details.status === 401) {
+ suggestions = 'Решение: Проблема с аутентификацией. Проверьте настройки токена.';
+ } else if (details.status === 500) {
+ suggestions = 'Решение: Внутренняя ошибка сервера. Проверьте логи бота.';
+ } else {
+ suggestions = 'Решение: Проверьте статус сервера и настройки подключения.';
+ }
+ break;
+
+ case 'CONNECTION_ERROR':
+ suggestions = 'Решение:
• Проверьте, что бот запущен на порту ' + BOT_PORT + '
• Проверьте сетевые настройки
• Убедитесь, что сервер доступен';
+ break;
+
+ case 'TIMEOUT_ERROR':
+ suggestions = 'Решение: Попробуйте еще раз или проверьте стабильность соединения';
+ break;
+
+ case 'NETWORK_ERROR':
+ suggestions = 'Решение: Проверьте интернет-соединение и доступность сервера';
+ break;
+ }
+
+ alertDiv.innerHTML = `
+
+
+
+
Ошибка отправки сообщения
+ ${message}
+ ${diagnosticInfo}
+
+ ${suggestions}
+
+
+
+
+ `;
+
+ document.body.appendChild(alertDiv);
+
+ // Автоматически скрываем через 10 секунд для ошибок
+ setTimeout(() => {
+ if (alertDiv.parentNode) {
+ alertDiv.remove();
+ }
+ }, 10000);
+ }
+
+ // Функция для скрытия ошибок
+ function hideTelegramError() {
+ const existingAlerts = document.querySelectorAll('.alert.position-fixed');
+ existingAlerts.forEach(alert => alert.remove());
+ }
+
// Добавляем обработчик события для кнопки отправки
document.getElementById('send-telegram-btn').addEventListener('click', sendTelegramMessage);
diff --git a/tg_mainbot.py b/tg_mainbot.py
index 053f7c5..2769c1f 100644
--- a/tg_mainbot.py
+++ b/tg_mainbot.py
@@ -762,13 +762,15 @@ def send_direct_message(user_id, message_text):
# Определяем тип ошибки для более информативного ответа
if e.error_code == 403:
- return False, "Пользователь заблокировал бота или не начал с ним диалог"
+ return False, f"Пользователь {user_id} заблокировал бота или не начал с ним диалог. Попросите пользователя отправить команду /start боту."
elif e.error_code == 400:
- return False, "Неверный ID пользователя"
+ return False, f"Неверный ID пользователя: {user_id}. Проверьте правильность ID."
elif e.error_code == 429:
- return False, "Превышен лимит отправки сообщений"
+ return False, f"Превышен лимит отправки сообщений для пользователя {user_id}. Попробуйте позже."
+ elif e.error_code == 404:
+ return False, f"Пользователь {user_id} не найден. Проверьте правильность ID."
else:
- return False, f"Ошибка Telegram: {e.description}"
+ return False, f"Ошибка Telegram API (код {e.error_code}): {e.description}"
except Exception as e:
error_msg = f"Неожиданная ошибка при отправке сообщения: {e}"
@@ -1285,42 +1287,42 @@ def send_message_api():
if api_token != WEBHOOK_SECRET:
logger.warning("Неверный API токен!")
log_event("security", "system", message="Попытка доступа к API с неверным токеном")
- return {"success": False, "error": "Unauthorized"}, 401
+ return {"success": False, "error": "Unauthorized", "error_code": "INVALID_TOKEN"}, 401
try:
data = request.get_json()
if not data:
- return {"success": False, "error": "Отсутствуют данные"}, 400
+ return {"success": False, "error": "Отсутствуют данные", "error_code": "NO_DATA"}, 400
user_id = data.get('user_id')
message_text = data.get('message')
if not user_id:
- return {"success": False, "error": "Не указан user_id"}, 400
+ return {"success": False, "error": "Не указан user_id", "error_code": "NO_USER_ID"}, 400
if not message_text:
- return {"success": False, "error": "Не указан текст сообщения"}, 400
+ return {"success": False, "error": "Не указан текст сообщения", "error_code": "NO_MESSAGE"}, 400
# Проверяем, что user_id является числом
try:
user_id = int(user_id)
except (ValueError, TypeError):
- return {"success": False, "error": "user_id должен быть числом"}, 400
+ return {"success": False, "error": "user_id должен быть числом", "error_code": "INVALID_USER_ID"}, 400
# Отправляем сообщение
success, result_message = send_direct_message(user_id, message_text)
if success:
- return {"success": True, "message": result_message}, 200
+ return {"success": True, "message": result_message, "user_id": user_id}, 200
else:
- return {"success": False, "error": result_message}, 400
+ return {"success": False, "error": result_message, "user_id": user_id, "error_code": "TELEGRAM_ERROR"}, 400
except Exception as e:
error_msg = f"Ошибка в API отправки сообщений: {e}"
logger.error(error_msg)
log_event("error", "system", message=error_msg)
- return {"success": False, "error": "Внутренняя ошибка сервера"}, 500
+ return {"success": False, "error": "Внутренняя ошибка сервера", "error_code": "INTERNAL_ERROR"}, 500
if __name__ == '__main__':
# Логируем запуск бота