- Add `custom_bot_manager.py` for core bot lifecycle management. - Introduce new API endpoints for custom bot status, start, stop, restart, and log retrieval. - Extend `UserSettings` and `GlobalSettings` models with custom bot configuration options (token, enabled, prefix, status). - Create a dedicated "Custom Bot" page in the dashboard (`custom-bot.html`) with associated JavaScript to configure settings and control the bot. - Integrate custom bot initialization into the application startup.
276 lines
8.0 KiB
JavaScript
276 lines
8.0 KiB
JavaScript
/**
|
|
* Custom Bot Management
|
|
* This module handles the custom bot functionality in the dashboard.
|
|
*/
|
|
|
|
// Status constants
|
|
const BOT_STATUS = {
|
|
NOT_CREATED: 'not_created',
|
|
RUNNING: 'running',
|
|
STOPPED: 'stopped',
|
|
ERROR: 'error'
|
|
};
|
|
|
|
// DOM elements
|
|
let botTokenInput;
|
|
let botPrefixInput;
|
|
let botStatusTypeSelect;
|
|
let botStatusTextInput;
|
|
let saveBotConfigButton;
|
|
let startBotButton;
|
|
let stopBotButton;
|
|
let statusDot;
|
|
let statusText;
|
|
let botError;
|
|
|
|
/**
|
|
* Initialize the custom bot functionality
|
|
*/
|
|
function initCustomBot() {
|
|
// Get DOM elements
|
|
botTokenInput = document.getElementById('bot-token-input');
|
|
botPrefixInput = document.getElementById('bot-prefix-input');
|
|
botStatusTypeSelect = document.getElementById('bot-status-type-select');
|
|
botStatusTextInput = document.getElementById('bot-status-text-input');
|
|
saveBotConfigButton = document.getElementById('save-bot-config-button');
|
|
startBotButton = document.getElementById('start-bot-button');
|
|
stopBotButton = document.getElementById('stop-bot-button');
|
|
statusDot = document.getElementById('status-dot');
|
|
statusText = document.getElementById('status-text');
|
|
botError = document.getElementById('bot-error');
|
|
|
|
// Add event listeners
|
|
if (saveBotConfigButton) {
|
|
saveBotConfigButton.addEventListener('click', saveCustomBotConfig);
|
|
}
|
|
|
|
if (startBotButton) {
|
|
startBotButton.addEventListener('click', startCustomBot);
|
|
}
|
|
|
|
if (stopBotButton) {
|
|
stopBotButton.addEventListener('click', stopCustomBot);
|
|
}
|
|
|
|
// Load custom bot settings
|
|
loadCustomBotSettings();
|
|
|
|
// Check bot status periodically
|
|
checkBotStatus();
|
|
setInterval(checkBotStatus, 10000); // Check every 10 seconds
|
|
}
|
|
|
|
/**
|
|
* Load custom bot settings from the server
|
|
*/
|
|
async function loadCustomBotSettings() {
|
|
try {
|
|
const response = await API.get('/dashboard/api/settings');
|
|
|
|
// Fill in the form fields
|
|
if (botTokenInput && response.custom_bot_token) {
|
|
botTokenInput.value = response.custom_bot_token;
|
|
}
|
|
|
|
if (botPrefixInput) {
|
|
botPrefixInput.value = response.custom_bot_prefix || '!';
|
|
}
|
|
|
|
if (botStatusTypeSelect) {
|
|
botStatusTypeSelect.value = response.custom_bot_status_type || 'listening';
|
|
}
|
|
|
|
if (botStatusTextInput) {
|
|
botStatusTextInput.value = response.custom_bot_status_text || '!help';
|
|
}
|
|
} catch (error) {
|
|
console.error('Error loading custom bot settings:', error);
|
|
Toast.error('Failed to load custom bot settings');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save custom bot configuration
|
|
*/
|
|
async function saveCustomBotConfig() {
|
|
try {
|
|
// Validate inputs
|
|
if (!botTokenInput.value) {
|
|
Toast.error('Bot token is required');
|
|
return;
|
|
}
|
|
|
|
if (!botPrefixInput.value) {
|
|
Toast.error('Command prefix is required');
|
|
return;
|
|
}
|
|
|
|
if (!botStatusTextInput.value) {
|
|
Toast.error('Status text is required');
|
|
return;
|
|
}
|
|
|
|
// Get current settings first
|
|
const currentSettings = await API.get('/dashboard/api/settings');
|
|
|
|
// Prepare the settings object with updated bot settings
|
|
const settings = {
|
|
...currentSettings,
|
|
custom_bot_token: botTokenInput.value,
|
|
custom_bot_prefix: botPrefixInput.value,
|
|
custom_bot_status_type: botStatusTypeSelect.value,
|
|
custom_bot_status_text: botStatusTextInput.value
|
|
};
|
|
|
|
// Save the settings
|
|
await API.put('/dashboard/api/settings', settings);
|
|
|
|
Toast.success('Custom bot configuration saved successfully');
|
|
|
|
// Check bot status after saving
|
|
checkBotStatus();
|
|
} catch (error) {
|
|
console.error('Error saving custom bot configuration:', error);
|
|
Toast.error('Failed to save custom bot configuration');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Start the custom bot
|
|
*/
|
|
async function startCustomBot() {
|
|
try {
|
|
startBotButton.disabled = true;
|
|
startBotButton.textContent = 'Starting...';
|
|
|
|
await API.post('/dashboard/api/custom-bot/start');
|
|
|
|
Toast.success('Custom bot started successfully');
|
|
|
|
// Check bot status after starting
|
|
checkBotStatus();
|
|
} catch (error) {
|
|
console.error('Error starting custom bot:', error);
|
|
Toast.error('Failed to start custom bot: ' + (error.response?.data?.detail || error.message));
|
|
|
|
// Re-enable the button
|
|
startBotButton.disabled = false;
|
|
startBotButton.textContent = 'Start Bot';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stop the custom bot
|
|
*/
|
|
async function stopCustomBot() {
|
|
try {
|
|
stopBotButton.disabled = true;
|
|
stopBotButton.textContent = 'Stopping...';
|
|
|
|
await API.post('/dashboard/api/custom-bot/stop');
|
|
|
|
Toast.success('Custom bot stopped successfully');
|
|
|
|
// Check bot status after stopping
|
|
checkBotStatus();
|
|
} catch (error) {
|
|
console.error('Error stopping custom bot:', error);
|
|
Toast.error('Failed to stop custom bot: ' + (error.response?.data?.detail || error.message));
|
|
|
|
// Re-enable the button
|
|
stopBotButton.disabled = false;
|
|
stopBotButton.textContent = 'Stop Bot';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check the status of the custom bot
|
|
*/
|
|
async function checkBotStatus() {
|
|
try {
|
|
const response = await API.get('/dashboard/api/custom-bot/status');
|
|
|
|
// Update the status indicator
|
|
updateStatusIndicator(response);
|
|
|
|
// Update button states
|
|
updateButtonStates(response);
|
|
|
|
// Show error if any
|
|
if (response.error && botError) {
|
|
botError.textContent = response.error;
|
|
botError.classList.remove('hidden');
|
|
} else if (botError) {
|
|
botError.classList.add('hidden');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking custom bot status:', error);
|
|
|
|
// Set status to unknown
|
|
if (statusDot) {
|
|
statusDot.className = 'w-4 h-4 rounded-full bg-gray-400 mr-2';
|
|
}
|
|
|
|
if (statusText) {
|
|
statusText.textContent = 'Unable to check status';
|
|
}
|
|
|
|
// Disable buttons
|
|
if (startBotButton) {
|
|
startBotButton.disabled = true;
|
|
}
|
|
|
|
if (stopBotButton) {
|
|
stopBotButton.disabled = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update the status indicator based on the bot status
|
|
*/
|
|
function updateStatusIndicator(status) {
|
|
if (!statusDot || !statusText) return;
|
|
|
|
if (status.is_running) {
|
|
statusDot.className = 'w-4 h-4 rounded-full bg-green-500 mr-2';
|
|
statusText.textContent = 'Bot is running';
|
|
} else if (status.status === BOT_STATUS.ERROR) {
|
|
statusDot.className = 'w-4 h-4 rounded-full bg-red-500 mr-2';
|
|
statusText.textContent = 'Bot has an error';
|
|
} else if (status.exists) {
|
|
statusDot.className = 'w-4 h-4 rounded-full bg-yellow-500 mr-2';
|
|
statusText.textContent = 'Bot is stopped';
|
|
} else {
|
|
statusDot.className = 'w-4 h-4 rounded-full bg-gray-400 mr-2';
|
|
statusText.textContent = 'Bot not created yet';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update button states based on the bot status
|
|
*/
|
|
function updateButtonStates(status) {
|
|
if (!startBotButton || !stopBotButton) return;
|
|
|
|
if (status.is_running) {
|
|
startBotButton.disabled = true;
|
|
stopBotButton.disabled = false;
|
|
startBotButton.textContent = 'Bot Running';
|
|
stopBotButton.textContent = 'Stop Bot';
|
|
} else if (status.exists) {
|
|
startBotButton.disabled = false;
|
|
stopBotButton.disabled = true;
|
|
startBotButton.textContent = 'Start Bot';
|
|
stopBotButton.textContent = 'Bot Stopped';
|
|
} else {
|
|
startBotButton.disabled = false;
|
|
stopBotButton.disabled = true;
|
|
startBotButton.textContent = 'Create & Start Bot';
|
|
stopBotButton.textContent = 'Stop Bot';
|
|
}
|
|
}
|
|
|
|
// Export the initialization function
|
|
window.initCustomBot = initCustomBot;
|