176 lines
7.5 KiB
HTML
176 lines
7.5 KiB
HTML
{{define "content"}}
|
||
<div class="card">
|
||
<h3>Twitch</h3>
|
||
<div>
|
||
<p>Статус бота: <span id="twitch-status" class="status">Загрузка...</span></p>
|
||
<p>Имя канала: <span id="twitch-channel"></span></p>
|
||
</div>
|
||
<div style="margin: 10px 0;">
|
||
<button id="auth-user-btn">🔐 Авторизовать стримера</button>
|
||
<button id="auth-bot-btn">🤖 Авторизовать бота</button>
|
||
</div>
|
||
<div id="twitch-tokens-info"></div>
|
||
<div id="token-expiry-info" style="margin-top: 10px; font-size: 0.9em;">
|
||
<p>🕒 Срок действия токенов:</p>
|
||
<p>👤 Стример: <span id="user-expiry">—</span></p>
|
||
<p>🤖 Бот: <span id="bot-expiry">—</span></p>
|
||
</div>
|
||
<!-- Блок для отображения ссылки авторизации БОТА -->
|
||
<div id="auth-link-container" style="margin-top: 15px; display: none;">
|
||
<label>Скопируйте ссылку и откройте её в браузере, где залогинен аккаунт БОТА:</label>
|
||
<div style="display: flex; gap: 10px; margin-top: 5px;">
|
||
<input type="text" id="auth-link" readonly style="flex: 1; padding: 8px; font-family: monospace;">
|
||
<button id="copy-link-btn">📋 Копировать</button>
|
||
</div>
|
||
<p id="auth-wait-message" style="color: #666; margin-top: 10px;">Ожидание подтверждения авторизации...</p>
|
||
</div>
|
||
<div id="notification" style="position: fixed; top: 20px; right: 20px; z-index: 1000; background: #333; color: white; padding: 10px 20px; border-radius: 5px; display: none;"></div>
|
||
</div>
|
||
|
||
<script>
|
||
let pollInterval = null;
|
||
|
||
async function loadSettings() {
|
||
try {
|
||
const statusRes = await fetch('/api/platforms/twitch/status');
|
||
const statusData = await statusRes.json();
|
||
const statusSpan = document.getElementById('twitch-status');
|
||
if (statusData.connected) {
|
||
statusSpan.textContent = 'Подключен';
|
||
statusSpan.className = 'status online';
|
||
} else {
|
||
statusSpan.textContent = 'Отключен';
|
||
statusSpan.className = 'status offline';
|
||
}
|
||
|
||
const authRes = await fetch('/api/platforms/twitch/auth');
|
||
const authData = await authRes.json();
|
||
document.getElementById('twitch-channel').textContent = authData.username || 'не указан';
|
||
const tokensDiv = document.getElementById('twitch-tokens-info');
|
||
if (authData.hasToken) {
|
||
tokensDiv.innerHTML = `<p>🔑 Токен бота: ${authData.maskedToken}</p>`;
|
||
loadTokenExpiry();
|
||
} else {
|
||
tokensDiv.innerHTML = '<p style="color: orange;">⚠️ Токен бота не настроен. Авторизуйте бота.</p>';
|
||
}
|
||
} catch (err) {
|
||
console.error('Ошибка загрузки настроек:', err);
|
||
document.getElementById('twitch-status').textContent = 'Ошибка';
|
||
}
|
||
}
|
||
|
||
async function updateStatus() {
|
||
try {
|
||
const res = await fetch('/api/platforms/twitch/status');
|
||
const data = await res.json();
|
||
const statusSpan = document.getElementById('twitch-status');
|
||
if (data.connected) {
|
||
statusSpan.textContent = 'Подключен';
|
||
statusSpan.className = 'status online';
|
||
} else {
|
||
statusSpan.textContent = 'Отключен';
|
||
statusSpan.className = 'status offline';
|
||
}
|
||
} catch (err) {}
|
||
}
|
||
|
||
async function authStreamer() {
|
||
try {
|
||
const res = await fetch('/api/platforms/twitch/auth/user');
|
||
const data = await res.json();
|
||
if (data.url) {
|
||
window.open(data.url, '_blank', 'width=600,height=700');
|
||
if (pollInterval) clearInterval(pollInterval);
|
||
pollInterval = setInterval(() => checkTokenUpdated('user'), 2000);
|
||
} else {
|
||
alert('Не удалось получить ссылку для авторизации');
|
||
}
|
||
} catch (err) {
|
||
alert('Ошибка: ' + err.message);
|
||
}
|
||
}
|
||
|
||
async function authBot() {
|
||
try {
|
||
const res = await fetch('/api/platforms/twitch/auth/bot');
|
||
const data = await res.json();
|
||
if (data.url) {
|
||
document.getElementById('auth-link').value = data.url;
|
||
document.getElementById('auth-link-container').style.display = 'block';
|
||
if (pollInterval) clearInterval(pollInterval);
|
||
pollInterval = setInterval(() => checkTokenUpdated('bot'), 2000);
|
||
} else {
|
||
alert('Не удалось получить ссылку для авторизации');
|
||
}
|
||
} catch (err) {
|
||
alert('Ошибка: ' + err.message);
|
||
}
|
||
}
|
||
|
||
async function loadTokenExpiry() {
|
||
try {
|
||
const res = await fetch('/api/platforms/twitch/token_expiry');
|
||
const data = await res.json();
|
||
const userSpan = document.getElementById('user-expiry');
|
||
const botSpan = document.getElementById('bot-expiry');
|
||
if (data.user_expiry_days !== null && data.user_expiry_days !== undefined) {
|
||
userSpan.textContent = data.user_expiry_days + ' дн.';
|
||
if (data.user_expiry_days < 1) userSpan.style.color = 'red';
|
||
else if (data.user_expiry_days < 3) userSpan.style.color = 'orange';
|
||
else userSpan.style.color = 'green';
|
||
} else {
|
||
userSpan.textContent = 'не авторизован';
|
||
}
|
||
if (data.bot_expiry_days !== null && data.bot_expiry_days !== undefined) {
|
||
botSpan.textContent = data.bot_expiry_days + ' дн.';
|
||
if (data.bot_expiry_days < 1) botSpan.style.color = 'red';
|
||
else if (data.bot_expiry_days < 3) botSpan.style.color = 'orange';
|
||
else botSpan.style.color = 'green';
|
||
} else {
|
||
botSpan.textContent = 'не авторизован';
|
||
}
|
||
} catch (err) {
|
||
console.error('Ошибка загрузки срока токенов:', err);
|
||
}
|
||
}
|
||
|
||
function showMessage(text, isError = false) {
|
||
const notif = document.getElementById('notification');
|
||
notif.textContent = text;
|
||
notif.style.backgroundColor = isError ? '#d9534f' : '#5cb85c';
|
||
notif.style.display = 'block';
|
||
setTimeout(() => { notif.style.display = 'none'; }, 3000);
|
||
}
|
||
|
||
async function checkTokenUpdated(type) {
|
||
try {
|
||
const res = await fetch(`/api/platforms/twitch/token_check?type=${type}`);
|
||
const data = await res.json();
|
||
if (data.updated) {
|
||
clearInterval(pollInterval);
|
||
pollInterval = null;
|
||
if (type === 'bot') {
|
||
document.getElementById('auth-link-container').style.display = 'none';
|
||
}
|
||
showMessage(`✅ Токен ${type === 'user' ? 'стримера' : 'бота'} сохранён!`, false);
|
||
loadSettings();
|
||
}
|
||
} catch (err) {
|
||
console.error('Ошибка проверки токена:', err);
|
||
}
|
||
}
|
||
|
||
document.getElementById('copy-link-btn').addEventListener('click', () => {
|
||
const linkInput = document.getElementById('auth-link');
|
||
linkInput.select();
|
||
document.execCommand('copy');
|
||
alert('Ссылка скопирована! Откройте её в другом браузере.');
|
||
});
|
||
|
||
document.getElementById('auth-user-btn').onclick = authStreamer;
|
||
document.getElementById('auth-bot-btn').onclick = authBot;
|
||
|
||
loadSettings();
|
||
setInterval(updateStatus, 10000);
|
||
</script>
|
||
{{end}} |