Files
sst_site/.history/views/admin/telegram_20251022195740.ejs
2025-10-22 21:22:44 +09:00

570 lines
33 KiB
Plaintext
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.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Telegram Bot - SmartSolTech Admin</title>
<!-- Tailwind CSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- Custom CSS -->
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/css/fixes.css">
</head>
<body class="bg-gray-100">
<!-- Admin Header -->
<header class="bg-white shadow-sm border-b">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-16">
<div class="flex items-center">
<h1 class="text-xl font-semibold text-gray-900">
<i class="fas fa-cogs mr-2"></i>
SmartSolTech Admin
</h1>
</div>
<div class="flex items-center space-x-4">
<span class="text-sm text-gray-600">
Добро пожаловать, <%= user ? user.name : 'Admin' %>!
</span>
<a href="/" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-external-link-alt mr-1"></i>
Посмотреть сайт
</a>
<form action="/admin/logout" method="post" class="inline">
<button type="submit" class="text-red-600 hover:text-red-800">
<i class="fas fa-sign-out-alt mr-1"></i>
Выход
</button>
</form>
</div>
</div>
</div>
</header>
<div class="flex">
<!-- Admin Sidebar -->
<aside class="w-64 bg-white shadow-sm admin-sidebar min-h-screen">
<nav class="mt-5 px-2">
<div class="space-y-1">
<a href="/admin/dashboard" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-50 hover:text-gray-900">
<i class="fas fa-tachometer-alt mr-3"></i>
Панель управления
</a>
<a href="/admin/portfolio" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-50 hover:text-gray-900">
<i class="fas fa-briefcase mr-3"></i>
Портфолио
</a>
<a href="/admin/services" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-50 hover:text-gray-900">
<i class="fas fa-cog mr-3"></i>
Услуги
</a>
<a href="/admin/contacts" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-50 hover:text-gray-900">
<i class="fas fa-envelope mr-3"></i>
Сообщения
</a>
<a href="/admin/media" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-50 hover:text-gray-900">
<i class="fas fa-images mr-3"></i>
Медиа
</a>
<a href="/admin/settings" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-50 hover:text-gray-900">
<i class="fas fa-cogs mr-3"></i>
Настройки
</a>
<a href="/admin/telegram" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md bg-blue-100 text-blue-700">
<i class="fab fa-telegram mr-3"></i>
Telegram Bot
</a>
<a href="/admin/banner-editor" class="group flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-50 hover:text-gray-900">
<i class="fas fa-paint-brush mr-3"></i>
Редактор баннеров
</a>
</div>
</nav>
</aside>
<!-- Main Content -->
<main class="flex-1 p-8">
<div class="space-y-6">
<!-- Header -->
<div class="bg-white shadow rounded-lg p-6">
<div class="flex items-center justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900 flex items-center">
<i class="fab fa-telegram mr-3 text-blue-500"></i>
Telegram Bot
</h1>
<p class="mt-2 text-gray-600">Настройка и управление уведомлениями через Telegram</p>
</div>
<div class="flex items-center space-x-3">
<div class="flex items-center">
<div class="w-3 h-3 rounded-full <%= botConfigured ? 'bg-green-500' : 'bg-red-500' %> mr-2"></div>
<span class="text-sm font-medium <%= botConfigured ? 'text-green-700' : 'text-red-700' %>">
<%= botConfigured ? 'Подключен' : 'Не настроен' %>
</span>
</div>
</div>
</div>
</div>
<!-- Bot Configuration -->
<div class="bg-white shadow rounded-lg p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-6">
<i class="fas fa-cog mr-2 text-blue-500"></i>
Конфигурация бота
</h3>
<form id="bot-config-form" class="space-y-6">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Bot Token -->
<div>
<label for="botToken" class="block text-sm font-medium text-gray-700 mb-2">
Токен бота *
</label>
<div class="relative">
<input type="password" id="botToken" name="botToken"
value="<%= botToken %>"
placeholder="1234567890:ABCDEFGHIJKLMNOPQRSTUVWXYZ"
class="block w-full pr-10 border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<button type="button" onclick="toggleTokenVisibility()"
class="absolute inset-y-0 right-0 pr-3 flex items-center">
<i id="token-eye" class="fas fa-eye text-gray-400"></i>
</button>
</div>
<p class="mt-1 text-sm text-gray-500">
Получите токен от <a href="https://t.me/BotFather" target="_blank" class="text-blue-600 underline">@BotFather</a>
</p>
</div>
<!-- Default Chat ID -->
<div>
<label for="chatId" class="block text-sm font-medium text-gray-700 mb-2">
ID чата по умолчанию
</label>
<input type="text" id="chatId" name="chatId"
value="<%= chatId %>"
placeholder="-1001234567890"
class="block w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<p class="mt-1 text-sm text-gray-500">
Оставьте пустым, если будете выбирать чат из списка
</p>
</div>
</div>
<div class="flex space-x-3">
<button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-save mr-2"></i>
Сохранить настройки
</button>
<button type="button" onclick="getBotInfo()" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-info-circle mr-2"></i>
Получить информацию о боте
</button>
</div>
</form>
<div id="config-result" class="mt-4 hidden"></div>
</div>
<% if (botConfigured) { %>
<!-- Bot Information -->
<div class="bg-white shadow rounded-lg p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-semibold text-gray-900">
<i class="fas fa-robot mr-2 text-green-500"></i>
Информация о боте
</h3>
<button onclick="refreshBotInfo()" class="text-blue-600 hover:text-blue-800 text-sm">
<i class="fas fa-refresh mr-1"></i>
Обновить
</button>
</div>
<div id="bot-info-container">
<% if (botInfo) { %>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div class="bg-gray-50 p-4 rounded-lg">
<div class="text-sm text-gray-600">Имя бота</div>
<div class="text-lg font-semibold text-gray-900">@<%= botInfo.username %></div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="text-sm text-gray-600">Отображаемое имя</div>
<div class="text-lg font-semibold text-gray-900"><%= botInfo.first_name %></div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="text-sm text-gray-600">ID бота</div>
<div class="text-lg font-semibold text-gray-900"><%= botInfo.id %></div>
</div>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="text-sm text-gray-600">Может читать сообщения</div>
<div class="text-lg font-semibold <%= botInfo.can_read_all_group_messages ? 'text-green-600' : 'text-red-600' %>">
<%= botInfo.can_read_all_group_messages ? 'Да' : 'Нет' %>
</div>
</div>
</div>
<% } else { %>
<div class="text-center py-4 text-gray-500">
<i class="fas fa-robot text-4xl text-gray-300 mb-2"></i>
<p>Настройте токен бота для получения информации</p>
</div>
<% } %>
</div>
</div>
<!-- Available Chats -->
<div class="bg-white shadow rounded-lg p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-semibold text-gray-900">
<i class="fas fa-comments mr-2 text-blue-500"></i>
Доступные чаты
</h3>
<button onclick="discoverChats()" class="bg-blue-600 hover:bg-blue-700 text-white px-3 py-1 rounded text-sm transition-colors">
<i class="fas fa-search mr-1"></i>
Найти чаты
</button>
</div>
<div id="available-chats-container">
<% if (availableChats && availableChats.length > 0) { %>
<div class="grid gap-3">
<% availableChats.forEach(chat => { %>
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center space-x-3">
<div class="w-8 h-8 bg-blue-100 rounded-full flex items-center justify-center">
<i class="fas <%= chat.type === 'group' || chat.type === 'supergroup' ? 'fa-users' : 'fa-user' %> text-blue-600 text-sm"></i>
</div>
<div>
<div class="font-medium text-gray-900"><%= chat.title %></div>
<div class="text-sm text-gray-500">
<%= chat.type %> • ID: <%= chat.id %>
<% if (chat.username) { %>• @<%= chat.username %><% } %>
</div>
</div>
</div>
<button onclick="selectChat('<%= chat.id %>', '<%= chat.title %>')"
class="text-blue-600 hover:text-blue-800 text-sm">
Выбрать
</button>
</div>
<% }); %>
</div>
<% } else { %>
<div class="text-center py-8 text-gray-500">
<i class="fas fa-comments text-4xl text-gray-300 mb-4"></i>
<p class="mb-2">Чаты не найдены</p>
<p class="text-sm">Отправьте боту сообщение или добавьте его в группу, затем нажмите "Найти чаты"</p>
</div>
<% } %>
</div>
</div>
<% } %>
<!-- Message Sender -->
<div class="bg-white shadow rounded-lg p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-6">
<i class="fas fa-paper-plane mr-2 text-purple-500"></i>
Отправить сообщение
</h3>
<form id="send-message-form" class="space-y-6">
<!-- Message Content -->
<div>
<label for="messageText" class="block text-sm font-medium text-gray-700 mb-2">
Текст сообщения *
</label>
<textarea id="messageText" name="message" rows="4" required
placeholder="Введите сообщение..."
class="block w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"></textarea>
</div>
<!-- Recipients -->
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
Получатели
</label>
<div id="recipients-container" class="space-y-2">
<% if (availableChats && availableChats.length > 0) { %>
<% availableChats.forEach(chat => { %>
<label class="flex items-center">
<input type="checkbox" name="chatIds" value="<%= chat.id %>"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
<span class="ml-2 text-sm text-gray-900">
<%= chat.title %>
<span class="text-gray-500">(<%= chat.type %>)</span>
</span>
</label>
<% }); %>
<% } else { %>
<div class="text-sm text-gray-500">
<i class="fas fa-info-circle mr-1"></i>
Сообщение будет отправлено в чат по умолчанию
</div>
<% } %>
</div>
</div>
<!-- Message Options -->
<div class="bg-gray-50 p-4 rounded-lg">
<h4 class="text-sm font-medium text-gray-900 mb-3">Настройки сообщения</h4>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<label class="flex items-center">
<input type="checkbox" name="disableWebPagePreview"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
<span class="ml-2 text-sm text-gray-900">Отключить предпросмотр ссылок</span>
</label>
<label class="flex items-center">
<input type="checkbox" name="disableNotification"
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded">
<span class="ml-2 text-sm text-gray-900">Тихое уведомление</span>
</label>
</div>
<div class="mt-4">
<label for="parseMode" class="block text-sm font-medium text-gray-700 mb-1">
Формат текста
</label>
<select name="parseMode" id="parseMode"
class="block w-full border border-gray-300 rounded-md px-3 py-2 text-sm">
<option value="HTML">HTML</option>
<option value="Markdown">Markdown</option>
<option value="">Обычный текст</option>
</select>
</div>
</div>
<!-- Submit Buttons -->
<div class="flex justify-between">
<button type="button" onclick="previewMessage()"
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
<i class="fas fa-eye mr-2"></i>
Предпросмотр
</button>
<div class="space-x-3">
<button type="button" onclick="testConnection()"
class="inline-flex items-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
<i class="fas fa-vial mr-2"></i>
Тест соединения
</button>
<button type="submit" id="sendMessageBtn"
class="inline-flex items-center px-6 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700">
<i class="fas fa-paper-plane mr-2"></i>
Отправить сообщение
</button>
</div>
</div>
</form>
<div id="send-result" class="mt-4 hidden"></div>
</div>
<!-- Bot Status and Controls -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Connection Test -->
<div class="bg-white shadow rounded-lg p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">
<i class="fas fa-plug mr-2 text-green-500"></i>
Проверка подключения
</h3>
<p class="text-gray-600 mb-4">
Отправить тестовое сообщение для проверки работоспособности бота.
</p>
<button id="test-connection" class="w-full bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-vial mr-2"></i>
Тестировать подключение
</button>
<div id="test-result" class="mt-4 hidden"></div>
</div>
<!-- Send Custom Message -->
<div class="bg-white shadow rounded-lg p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">
<i class="fas fa-paper-plane mr-2 text-blue-500"></i>
Отправить сообщение
</h3>
<form id="send-message-form">
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">
Сообщение
</label>
<textarea
id="custom-message"
rows="4"
class="w-full border border-gray-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
placeholder="Введите текст сообщения..."></textarea>
</div>
<button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition-colors">
<i class="fas fa-send mr-2"></i>
Отправить
</button>
</form>
<div id="send-result" class="mt-4 hidden"></div>
</div>
</div>
<!-- Notification Settings -->
<div class="bg-white shadow rounded-lg p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-6">
<i class="fas fa-bell mr-2 text-purple-500"></i>
Настройки уведомлений
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Notification Types -->
<div>
<h4 class="font-medium text-gray-900 mb-4">Типы уведомлений</h4>
<div class="space-y-3">
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center">
<i class="fas fa-envelope mr-3 text-blue-500"></i>
<span class="text-sm text-gray-900">Новые обращения</span>
</div>
<div class="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center">
<i class="fas fa-calculator mr-3 text-green-500"></i>
<span class="text-sm text-gray-900">Расчеты стоимости</span>
</div>
<div class="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center">
<i class="fas fa-briefcase mr-3 text-purple-500"></i>
<span class="text-sm text-gray-900">Новые проекты</span>
</div>
<div class="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center">
<i class="fas fa-cog mr-3 text-orange-500"></i>
<span class="text-sm text-gray-900">Новые услуги</span>
</div>
<div class="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
</div>
</div>
<!-- Bot Information -->
<div>
<h4 class="font-medium text-gray-900 mb-4">Информация о боте</h4>
<div class="space-y-3">
<div class="flex justify-between">
<span class="text-sm text-gray-600">Статус:</span>
<span class="text-sm font-medium text-green-600">Активен</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Токен:</span>
<span class="text-sm font-mono text-gray-800">••••••••••</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Chat ID:</span>
<span class="text-sm font-mono text-gray-800">••••••••••</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Последнее уведомление:</span>
<span class="text-sm text-gray-600">Недавно</span>
</div>
</div>
</div>
</div>
</div>
<!-- Recent Notifications -->
<div class="bg-white shadow rounded-lg p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-6">
<i class="fas fa-history mr-2 text-gray-500"></i>
Недавние уведомления
</h3>
<div class="text-center py-8 text-gray-500">
<i class="fas fa-inbox text-4xl text-gray-300 mb-4"></i>
<p>Уведомления будут отображаться здесь после отправки</p>
</div>
</div>
<% } %>
</div>
</main>
</div>
<!-- JavaScript -->
<script src="/js/main.js"></script>
<script>
<% if (botConfigured) { %>
// Test connection
document.getElementById('test-connection').addEventListener('click', async () => {
const button = document.getElementById('test-connection');
const resultDiv = document.getElementById('test-result');
button.disabled = true;
button.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>Тестирование...';
try {
const response = await fetch('/admin/telegram/test', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
const result = await response.json();
resultDiv.className = 'mt-4 p-3 rounded-lg ' + (result.success ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800');
resultDiv.innerHTML = `<i class="fas ${result.success ? 'fa-check' : 'fa-times'} mr-2"></i>${result.message}`;
resultDiv.classList.remove('hidden');
} catch (error) {
resultDiv.className = 'mt-4 p-3 rounded-lg bg-red-100 text-red-800';
resultDiv.innerHTML = '<i class="fas fa-times mr-2"></i>Ошибка при тестировании подключения';
resultDiv.classList.remove('hidden');
} finally {
button.disabled = false;
button.innerHTML = '<i class="fas fa-vial mr-2"></i>Тестировать подключение';
}
});
// Send custom message
document.getElementById('send-message-form').addEventListener('submit', async (e) => {
e.preventDefault();
const messageInput = document.getElementById('custom-message');
const resultDiv = document.getElementById('send-result');
const message = messageInput.value.trim();
if (!message) {
resultDiv.className = 'mt-4 p-3 rounded-lg bg-red-100 text-red-800';
resultDiv.innerHTML = '<i class="fas fa-times mr-2"></i>Введите сообщение';
resultDiv.classList.remove('hidden');
return;
}
try {
const response = await fetch('/admin/telegram/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ message })
});
const result = await response.json();
resultDiv.className = 'mt-4 p-3 rounded-lg ' + (result.success ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800');
resultDiv.innerHTML = `<i class="fas ${result.success ? 'fa-check' : 'fa-times'} mr-2"></i>${result.message}`;
resultDiv.classList.remove('hidden');
if (result.success) {
messageInput.value = '';
}
} catch (error) {
resultDiv.className = 'mt-4 p-3 rounded-lg bg-red-100 text-red-800';
resultDiv.innerHTML = '<i class="fas fa-times mr-2"></i>Ошибка при отправке сообщения';
resultDiv.classList.remove('hidden');
}
});
<% } %>
</script>
</body>
</html>