diff --git a/bot/static/index.html b/bot/static/index.html
index 0dd15e1..a49eae6 100644
--- a/bot/static/index.html
+++ b/bot/static/index.html
@@ -2023,8 +2023,7 @@ async function apiCall(endpoint, method = 'GET', data = null) {
async function loadServers() {
try {
console.log('🎭 Loading servers...');
- const response = await fetch('/servers');
- const data = await response.json();
+ const data = await apiCall('/servers');
console.log('🎭 Servers response:', data);
if (data.servers) {
@@ -2124,10 +2123,9 @@ function displayServers() {
async function loadProfilePictureMetadata() {
try {
- const response = await fetch('/profile-picture/metadata');
- const result = await response.json();
+ const result = await apiCall('/profile-picture/metadata');
- if (response.ok && result.status === 'ok' && result.metadata) {
+ if (result.status === 'ok' && result.metadata) {
const metadataDiv = document.getElementById('pfp-metadata');
const metadataContent = document.getElementById('pfp-metadata-content');
@@ -2182,14 +2180,12 @@ async function populateServerDropdowns() {
async function refreshFigurineSubscribers() {
try {
console.log('🔄 Figurines: Fetching subscribers...');
- const res = await fetch('/figurines/subscribers');
- const data = await res.json();
+ const data = await apiCall('/figurines/subscribers');
console.log('📋 Figurines: Received subscribers:', data);
displayFigurineSubscribers(data.subscribers || []);
showNotification('Subscribers refreshed');
} catch (e) {
console.error('❌ Figurines: Failed to fetch subscribers:', e);
- showNotification('Failed to load subscribers', 'error');
}
}
@@ -2238,8 +2234,7 @@ async function addFigurineSubscriber() {
async function removeFigurineSubscriber(uid) {
try {
console.log(`🗑️ Figurines: Removing subscriber ${uid}...`);
- const res = await fetch(`/figurines/subscribers/${uid}`, { method: 'DELETE' });
- const data = await res.json();
+ const data = await apiCall(`/figurines/subscribers/${uid}`, 'DELETE');
console.log('🗑️ Figurines: Remove subscriber response:', data);
if (data.status === 'ok') {
showNotification('Subscriber removed');
@@ -2249,7 +2244,6 @@ async function removeFigurineSubscriber(uid) {
}
} catch (e) {
console.error('❌ Figurines: Failed to remove subscriber:', e);
- showNotification('Failed to remove subscriber', 'error');
}
}
@@ -2425,8 +2419,7 @@ async function repairConfig() {
async function populateMoodDropdowns() {
try {
console.log('🎭 Loading available moods...');
- const response = await fetch('/moods/available');
- const data = await response.json();
+ const data = await apiCall('/moods/available');
console.log('🎭 Available moods response:', data);
if (data.moods) {
@@ -2597,25 +2590,13 @@ async function updateBedtimeRange(guildId) {
}
// Send the update request
- const response = await fetch(`/servers/${guildIdStr}/bedtime-range`, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- bedtime_hour: startHour,
- bedtime_minute: startMinute,
- bedtime_hour_end: endHour,
- bedtime_minute_end: endMinute
- })
+ await apiCall(`/servers/${guildIdStr}/bedtime-range`, 'POST', {
+ bedtime_hour: startHour,
+ bedtime_minute: startMinute,
+ bedtime_hour_end: endHour,
+ bedtime_minute_end: endMinute
});
- if (!response.ok) {
- const errorData = await response.json().catch(() => ({}));
- throw new Error(errorData.message || `HTTP ${response.status}`);
- }
-
- const result = await response.json();
showNotification(`Bedtime range updated: ${startTime} - ${endTime}`);
// Reload servers to show updated configuration
@@ -2623,7 +2604,6 @@ async function updateBedtimeRange(guildId) {
} catch (error) {
console.error('Failed to update bedtime range:', error);
- showNotification(error.message || 'Failed to update bedtime range', 'error');
} finally {
// Restore button state
if (button) {
@@ -2815,12 +2795,9 @@ let selectedGPU = 'nvidia'; // 'nvidia' or 'amd'
async function checkGPUStatus() {
try {
- const response = await fetch('/gpu-status');
- if (response.ok) {
- const data = await response.json();
- selectedGPU = data.gpu || 'nvidia';
- updateGPUUI();
- }
+ const data = await apiCall('/gpu-status');
+ selectedGPU = data.gpu || 'nvidia';
+ updateGPUUI();
} catch (error) {
console.error('Failed to check GPU status:', error);
}
@@ -2868,12 +2845,9 @@ let bipolarMode = false;
async function checkBipolarModeStatus() {
try {
- const response = await fetch('/bipolar-mode');
- if (response.ok) {
- const data = await response.json();
- bipolarMode = data.bipolar_mode;
- updateBipolarModeUI();
- }
+ const data = await apiCall('/bipolar-mode');
+ bipolarMode = data.bipolar_mode;
+ updateBipolarModeUI();
} catch (error) {
console.error('Failed to check bipolar mode status:', error);
}
@@ -3106,10 +3080,7 @@ async function loadScoreboard() {
async function loadActiveArguments() {
try {
- const response = await fetch('/bipolar-mode/arguments');
- if (!response.ok) return;
-
- const data = await response.json();
+ const data = await apiCall('/bipolar-mode/arguments');
const container = document.getElementById('active-arguments');
const list = document.getElementById('active-arguments-list');
@@ -3155,21 +3126,10 @@ async function triggerAutonomous(actionType) {
endpoint += `?guild_id=${selectedServer}`;
}
- const response = await fetch(endpoint, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' }
- });
-
- const result = await response.json();
-
- if (response.ok) {
- showNotification(result.message || 'Action triggered successfully');
- } else {
- throw new Error(result.message || 'Failed to trigger action');
- }
+ const result = await apiCall(endpoint, 'POST');
+ showNotification(result.message || 'Action triggered successfully');
} catch (error) {
console.error('Failed to trigger autonomous action:', error);
- showNotification(error.message || 'Failed to trigger action', 'error');
}
}
@@ -3215,23 +3175,12 @@ async function triggerEngageUser() {
endpoint += `?${params.toString()}`;
}
- const response = await fetch(endpoint, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' }
- });
-
- const result = await response.json();
-
- if (response.ok) {
- showNotification(result.message || 'Engagement triggered successfully');
- // Optionally collapse the submenu after successful trigger
- // toggleEngageSubmenu();
- } else {
- throw new Error(result.message || 'Failed to trigger engagement');
- }
+ const result = await apiCall(endpoint, 'POST');
+ showNotification(result.message || 'Engagement triggered successfully');
+ // Optionally collapse the submenu after successful trigger
+ // toggleEngageSubmenu();
} catch (error) {
console.error('Failed to trigger user engagement:', error);
- showNotification(error.message || 'Failed to trigger engagement', 'error');
}
}
@@ -3287,21 +3236,10 @@ async function triggerShareTweet() {
endpoint += `?${params.toString()}`;
}
- const response = await fetch(endpoint, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' }
- });
-
- const result = await response.json();
-
- if (response.ok) {
- showNotification(result.message || 'Tweet share triggered successfully');
- } else {
- throw new Error(result.message || 'Failed to trigger tweet share');
- }
+ const result = await apiCall(endpoint, 'POST');
+ showNotification(result.message || 'Tweet share triggered successfully');
} catch (error) {
console.error('Failed to trigger tweet share:', error);
- showNotification(error.message || 'Failed to trigger tweet share', 'error');
}
}
@@ -3326,31 +3264,22 @@ async function changeProfilePicture() {
const url = params.toString() ? `${endpoint}?${params.toString()}` : endpoint;
- const response = await fetch(url, {
- method: 'POST'
- });
+ const result = await apiCall(url, 'POST');
- const result = await response.json();
+ statusDiv.textContent = `✅ ${result.message}`;
+ statusDiv.style.color = 'green';
- if (response.ok && result.status === 'ok') {
- statusDiv.textContent = `✅ ${result.message}`;
- statusDiv.style.color = 'green';
-
- // Display metadata if available
- if (result.metadata) {
- metadataContent.textContent = JSON.stringify(result.metadata, null, 2);
- metadataDiv.style.display = 'block';
- }
-
- showNotification('Profile picture changed successfully!');
- } else {
- throw new Error(result.message || 'Failed to change profile picture');
+ // Display metadata if available
+ if (result.metadata) {
+ metadataContent.textContent = JSON.stringify(result.metadata, null, 2);
+ metadataDiv.style.display = 'block';
}
+
+ showNotification('Profile picture changed successfully!');
} catch (error) {
console.error('Failed to change profile picture:', error);
statusDiv.textContent = `❌ Error: ${error.message}`;
statusDiv.style.color = 'red';
- showNotification(error.message || 'Failed to change profile picture', 'error');
}
}
@@ -3431,26 +3360,17 @@ async function restoreFallbackPfp() {
statusDiv.style.color = '#61dafb';
try {
- const response = await fetch('/profile-picture/restore-fallback', {
- method: 'POST'
- });
+ const result = await apiCall('/profile-picture/restore-fallback', 'POST');
- const result = await response.json();
+ statusDiv.textContent = `✅ ${result.message}`;
+ statusDiv.style.color = 'green';
+ metadataDiv.style.display = 'none';
- if (response.ok && result.status === 'ok') {
- statusDiv.textContent = `✅ ${result.message}`;
- statusDiv.style.color = 'green';
- metadataDiv.style.display = 'none';
-
- showNotification('Original avatar restored successfully!');
- } else {
- throw new Error(result.message || 'Failed to restore fallback avatar');
- }
+ showNotification('Original avatar restored successfully!');
} catch (error) {
console.error('Failed to restore fallback avatar:', error);
statusDiv.textContent = `❌ Error: ${error.message}`;
statusDiv.style.color = 'red';
- showNotification(error.message || 'Failed to restore fallback avatar', 'error');
}
}
@@ -3502,28 +3422,19 @@ async function resetRoleColor() {
statusDiv.style.color = '#61dafb';
try {
- const response = await fetch('/role-color/reset-fallback', {
- method: 'POST'
- });
+ const result = await apiCall('/role-color/reset-fallback', 'POST');
- const result = await response.json();
+ statusDiv.textContent = `✅ ${result.message}`;
+ statusDiv.style.color = 'green';
- if (response.ok && result.status === 'ok') {
- statusDiv.textContent = `✅ ${result.message}`;
- statusDiv.style.color = 'green';
-
- // Update the input to show fallback color
- document.getElementById('role-color-hex').value = '#86cecb';
-
- showNotification('Role color reset to fallback #86cecb');
- } else {
- throw new Error(result.message || 'Failed to reset role color');
- }
+ // Update the input to show fallback color
+ document.getElementById('role-color-hex').value = '#86cecb';
+
+ showNotification('Role color reset to fallback #86cecb');
} catch (error) {
console.error('Failed to reset role color:', error);
statusDiv.textContent = `❌ Error: ${error.message}`;
statusDiv.style.color = 'red';
- showNotification(error.message || 'Failed to reset role color', 'error');
}
}
@@ -3588,7 +3499,7 @@ async function sendCustomPrompt() {
}
try {
- let endpoint, requestData, response;
+ let endpoint;
if (targetType === 'dm') {
// DM target
@@ -3597,16 +3508,7 @@ async function sendCustomPrompt() {
showNotification('Please enter a user ID for DM', 'error');
return;
}
-
endpoint = `/dm/${userId}/custom`;
- requestData = { prompt: prompt };
-
- response = await fetch(endpoint, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(requestData)
- });
-
} else {
// Server target
const selectedServer = document.getElementById('custom-prompt-server-select').value;
@@ -3617,33 +3519,20 @@ async function sendCustomPrompt() {
// Don't use parseInt() - Discord IDs are too large for JS integers
endpoint += `?guild_id=${selectedServer}`;
}
-
- requestData = { prompt: prompt };
-
- response = await fetch(endpoint, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(requestData)
- });
}
- const result = await response.json();
+ const result = await apiCall(endpoint, 'POST', { prompt: prompt });
- if (response.ok) {
- showNotification(result.message || 'Custom prompt sent successfully');
- document.getElementById('customPrompt').value = '';
- document.getElementById('customPromptAttachment').value = ''; // Clear file input
- if (targetType === 'dm') {
- document.getElementById('custom-prompt-user-id').value = '';
- }
- document.getElementById('customStatus').textContent = '✅ Custom prompt sent successfully!';
- document.getElementById('customStatus').style.color = 'green';
- } else {
- throw new Error(result.message || 'Failed to send custom prompt');
+ showNotification(result.message || 'Custom prompt sent successfully');
+ document.getElementById('customPrompt').value = '';
+ document.getElementById('customPromptAttachment').value = ''; // Clear file input
+ if (targetType === 'dm') {
+ document.getElementById('custom-prompt-user-id').value = '';
}
+ document.getElementById('customStatus').textContent = '✅ Custom prompt sent successfully!';
+ document.getElementById('customStatus').style.color = 'green';
} catch (error) {
console.error('Failed to send custom prompt:', error);
- showNotification(error.message || 'Failed to send custom prompt', 'error');
document.getElementById('customStatus').textContent = '❌ Failed to send custom prompt';
document.getElementById('customStatus').style.color = 'red';
}
@@ -3689,21 +3578,10 @@ async function sendBedtime() {
console.log('🛏️ Final endpoint:', endpoint);
- const response = await fetch(endpoint, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' }
- });
-
- const result = await response.json();
-
- if (response.ok) {
- showNotification(result.message || 'Bedtime reminder sent successfully');
- } else {
- throw new Error(result.message || 'Failed to send bedtime reminder');
- }
+ const result = await apiCall(endpoint, 'POST');
+ showNotification(result.message || 'Bedtime reminder sent successfully');
} catch (error) {
console.error('Failed to send bedtime reminder:', error);
- showNotification(error.message || 'Failed to send bedtime reminder', 'error');
}
}
@@ -3892,14 +3770,12 @@ async function checkImageSystemStatus() {
const statusDisplay = document.getElementById('image-status-display');
statusDisplay.innerHTML = '🔄 Checking system status...';
- const response = await fetch('/image/status');
- const result = await response.json();
+ const result = await apiCall('/image/status');
- if (response.ok) {
- const workflowStatus = result.workflow_template_exists ? '✅ Found' : '❌ Missing';
- const comfyuiStatus = result.comfyui_running ? '✅ Running' : '❌ Not running';
-
- statusDisplay.innerHTML = `
+ const workflowStatus = result.workflow_template_exists ? '✅ Found' : '❌ Missing';
+ const comfyuiStatus = result.comfyui_running ? '✅ Running' : '❌ Not running';
+
+ statusDisplay.innerHTML = `
System Status:
• Workflow Template (Miku_BasicWorkflow.json): ${workflowStatus}
• ComfyUI Server: ${comfyuiStatus}
@@ -3908,9 +3784,6 @@ ${result.comfyui_running ? `• Detected ComfyUI URL: ${result.comfyui_url}` : '
Overall Status: ${result.ready ? '✅ Ready for image generation' : '⚠️ Setup required'}
${!result.workflow_template_exists ? '⚠️ Place Miku_BasicWorkflow.json in bot directory\n' : ''}${!result.comfyui_running ? '⚠️ Start ComfyUI server on localhost:8188 (bot will auto-detect correct URL)\n' : ''}`;
- } else {
- statusDisplay.innerHTML = `❌ Error checking status: ${result.message}`;
- }
} catch (error) {
console.error('Failed to check image system status:', error);
document.getElementById('image-status-display').innerHTML = `❌ Error: ${error.message}`;
@@ -3931,28 +3804,17 @@ async function testImageDetection() {
resultsDiv.innerHTML = '🔍 Testing detection...';
resultsDiv.style.color = '#4CAF50';
- const response = await fetch('/image/test-detection', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ message: message })
- });
+ const result = await apiCall('/image/test-detection', 'POST', { message: message });
- const result = await response.json();
+ const detectionIcon = result.is_image_request ? '✅' : '❌';
+ const detectionText = result.is_image_request ? 'WILL trigger image generation' : 'will NOT trigger image generation';
- if (response.ok) {
- const detectionIcon = result.is_image_request ? '✅' : '❌';
- const detectionText = result.is_image_request ? 'WILL trigger image generation' : 'will NOT trigger image generation';
-
- resultsDiv.innerHTML = `
+ resultsDiv.innerHTML = `
Detection Result: ${detectionIcon} This message ${detectionText}
${result.is_image_request ? `
Extracted Prompt: "${result.extracted_prompt}"` : ''}
Original Message: "${result.original_message}"`;
-
- resultsDiv.style.color = result.is_image_request ? '#4CAF50' : '#ff9800';
- } else {
- resultsDiv.innerHTML = `❌ Detection test failed: ${result.message}`;
- resultsDiv.style.color = 'red';
- }
+
+ resultsDiv.style.color = result.is_image_request ? '#4CAF50' : '#ff9800';
} catch (error) {
console.error('Failed to test image detection:', error);
resultsDiv.innerHTML = `❌ Error: ${error.message}`;
@@ -3978,20 +3840,13 @@ async function generateManualImage() {
statusDiv.innerHTML = '🎨 Generating image... This may take a few minutes.';
statusDiv.style.color = '#4CAF50';
- const response = await fetch('/image/generate', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ prompt: prompt })
- });
+ const result = await apiCall('/image/generate', 'POST', { prompt: prompt });
- const result = await response.json();
+ statusDiv.innerHTML = `✅ Image generated successfully!`;
+ statusDiv.style.color = '#4CAF50';
- if (response.ok && result.status === 'ok') {
- statusDiv.innerHTML = `✅ Image generated successfully!`;
- statusDiv.style.color = '#4CAF50';
-
- // Display the generated image
- if (result.image_path) {
+ // Display the generated image
+ if (result.image_path) {
const filename = result.image_path.split('/').pop();
const imageUrl = `/image/view/${encodeURIComponent(filename)}`;
@@ -4030,10 +3885,6 @@ async function generateManualImage() {
}
document.getElementById('manual-image-prompt').value = '';
- } else {
- statusDiv.innerHTML = `❌ Failed to generate image: ${result.message || 'Unknown error'}`;
- statusDiv.style.color = 'red';
- }
} catch (error) {
console.error('Failed to generate image:', error);
statusDiv.innerHTML = `❌ Error: ${error.message}`;
@@ -4175,17 +4026,10 @@ function toggleCustomPrompt() {
// DM Logs Functions
async function loadDMUsers() {
try {
- const response = await fetch('/dms/users');
- const result = await response.json();
-
- if (response.ok) {
- displayDMUsers(result.users);
- } else {
- throw new Error(result.message || 'Failed to load DM users');
- }
+ const result = await apiCall('/dms/users');
+ displayDMUsers(result.users);
} catch (error) {
console.error('Failed to load DM users:', error);
- showNotification(error.message || 'Failed to load DM users', 'error');
}
}
@@ -4306,28 +4150,22 @@ function toggleCustomPrompt() {
console.log(`🔍 Original userId: ${userId} (type: ${typeof userId})`);
console.log(`🔍 userIdStr: ${userIdStr} (type: ${typeof userIdStr})`);
- const response = await fetch(`/dms/users/${userIdStr}/conversations?limit=100`);
- const result = await response.json();
+ const result = await apiCall(`/dms/users/${userIdStr}/conversations?limit=100`);
console.log('📡 API Response:', result);
console.log('📡 API URL called:', `/dms/users/${userIdStr}/conversations?limit=100`);
- if (response.ok) {
- if (result.conversations && result.conversations.length > 0) {
- console.log(`✅ Found ${result.conversations.length} conversations`);
- displayUserConversations(userIdStr, result.conversations);
- } else {
- console.log('⚠️ No conversations found in response');
- showNotification('No conversations found for this user', 'info');
- // Go back to user list
- loadDMUsers();
- }
+ if (result.conversations && result.conversations.length > 0) {
+ console.log(`✅ Found ${result.conversations.length} conversations`);
+ displayUserConversations(userIdStr, result.conversations);
} else {
- throw new Error(result.message || 'Failed to load conversations');
+ console.log('⚠️ No conversations found in response');
+ showNotification('No conversations found for this user', 'info');
+ // Go back to user list
+ loadDMUsers();
}
} catch (error) {
console.error('Failed to load user conversations:', error);
- showNotification(error.message || 'Failed to load conversations', 'error');
}
}
@@ -4419,18 +4257,11 @@ function toggleCustomPrompt() {
try {
// Ensure userId is always treated as a string
const userIdStr = String(userId);
- const response = await fetch(`/dms/users/${userIdStr}/export?format=txt`);
- const result = await response.json();
-
- if (response.ok) {
- showNotification(`DM export completed for user ${userIdStr}`);
- // You could trigger a download here if the file is accessible
- } else {
- throw new Error(result.message || 'Failed to export DMs');
- }
+ await apiCall(`/dms/users/${userIdStr}/export?format=txt`);
+ showNotification(`DM export completed for user ${userIdStr}`);
+ // You could trigger a download here if the file is accessible
} catch (error) {
console.error('Failed to export user DMs:', error);
- showNotification(error.message || 'Failed to export DMs', 'error');
}
}
@@ -4443,18 +4274,11 @@ function toggleCustomPrompt() {
}
try {
- const response = await fetch(`/dms/users/${userIdStr}`, { method: 'DELETE' });
- const result = await response.json();
-
- if (response.ok) {
- showNotification(`Deleted DM logs for user ${userIdStr}`);
- loadDMUsers(); // Refresh the list
- } else {
- throw new Error(result.message || 'Failed to delete DM logs');
- }
+ await apiCall(`/dms/users/${userIdStr}`, 'DELETE');
+ showNotification(`Deleted DM logs for user ${userIdStr}`);
+ loadDMUsers(); // Refresh the list
} catch (error) {
console.error('Failed to delete user DMs:', error);
- showNotification(error.message || 'Failed to delete DM logs', 'error');
}
}
@@ -4468,18 +4292,11 @@ function toggleCustomPrompt() {
}
try {
- const response = await fetch(`/dms/users/${userIdStr}/block`, { method: 'POST' });
- const result = await response.json();
-
- if (response.ok) {
- showNotification(`${username} has been blocked from sending DMs`);
- loadDMUsers(); // Refresh the list
- } else {
- throw new Error(result.message || 'Failed to block user');
- }
+ await apiCall(`/dms/users/${userIdStr}/block`, 'POST');
+ showNotification(`${username} has been blocked from sending DMs`);
+ loadDMUsers(); // Refresh the list
} catch (error) {
console.error('Failed to block user:', error);
- showNotification(error.message || 'Failed to block user', 'error');
}
}
@@ -4487,18 +4304,11 @@ function toggleCustomPrompt() {
const userIdStr = String(userId);
try {
- const response = await fetch(`/dms/users/${userIdStr}/unblock`, { method: 'POST' });
- const result = await response.json();
-
- if (response.ok) {
- showNotification(`${username} has been unblocked`);
- loadBlockedUsers(); // Refresh blocked users list
- } else {
- throw new Error(result.message || 'Failed to unblock user');
- }
+ await apiCall(`/dms/users/${userIdStr}/unblock`, 'POST');
+ showNotification(`${username} has been unblocked`);
+ loadBlockedUsers(); // Refresh blocked users list
} catch (error) {
console.error('Failed to unblock user:', error);
- showNotification(error.message || 'Failed to unblock user', 'error');
}
}
@@ -4510,20 +4320,13 @@ function toggleCustomPrompt() {
}
try {
- const response = await fetch(`/dms/users/${userIdStr}/conversations/delete-all`, { method: 'POST' });
- const result = await response.json();
-
- if (response.ok) {
- showNotification(`Bulk deletion queued for ${username} (deleting all Miku messages from Discord and logs)`);
- setTimeout(() => {
- loadDMUsers(); // Refresh after a delay to allow deletion to process
- }, 2000);
- } else {
- throw new Error(result.message || 'Failed to delete conversations');
- }
+ await apiCall(`/dms/users/${userIdStr}/conversations/delete-all`, 'POST');
+ showNotification(`Bulk deletion queued for ${username} (deleting all Miku messages from Discord and logs)`);
+ setTimeout(() => {
+ loadDMUsers(); // Refresh after a delay to allow deletion to process
+ }, 2000);
} catch (error) {
console.error('Failed to delete conversations:', error);
- showNotification(error.message || 'Failed to delete conversations', 'error');
}
}
@@ -4541,18 +4344,11 @@ function toggleCustomPrompt() {
}
try {
- const response = await fetch(`/dms/users/${userIdStr}/delete-completely`, { method: 'POST' });
- const result = await response.json();
-
- if (response.ok) {
- showNotification(`${username} has been completely deleted from the system`);
- loadDMUsers(); // Refresh the list
- } else {
- throw new Error(result.message || 'Failed to delete user completely');
- }
+ await apiCall(`/dms/users/${userIdStr}/delete-completely`, 'POST');
+ showNotification(`${username} has been completely deleted from the system`);
+ loadDMUsers(); // Refresh the list
} catch (error) {
console.error('Failed to delete user completely:', error);
- showNotification(error.message || 'Failed to delete user completely', 'error');
}
}
@@ -4564,20 +4360,13 @@ function toggleCustomPrompt() {
}
try {
- const response = await fetch(`/dms/users/${userIdStr}/conversations/${conversationId}/delete`, { method: 'POST' });
- const result = await response.json();
-
- if (response.ok) {
- showNotification('Miku message deletion queued (deleting from both Discord and logs)');
- setTimeout(() => {
- viewUserConversations(userId); // Refresh after a short delay to allow deletion to process
- }, 1000);
- } else {
- throw new Error(result.message || 'Failed to delete message');
- }
+ await apiCall(`/dms/users/${userIdStr}/conversations/${conversationId}/delete`, 'POST');
+ showNotification('Miku message deletion queued (deleting from both Discord and logs)');
+ setTimeout(() => {
+ viewUserConversations(userId); // Refresh after a short delay to allow deletion to process
+ }, 1000);
} catch (error) {
console.error('Failed to delete conversation:', error);
- showNotification(error.message || 'Failed to delete message', 'error');
}
}
@@ -4591,21 +4380,15 @@ function toggleCustomPrompt() {
try {
showNotification(`Analyzing ${username}'s interactions...`, 'info');
- const response = await fetch(`/dms/users/${userIdStr}/analyze`, { method: 'POST' });
- const result = await response.json();
+ const result = await apiCall(`/dms/users/${userIdStr}/analyze`, 'POST');
- if (response.ok) {
- if (result.reported) {
- showNotification(`✅ Analysis complete! Report sent to bot owner for ${username}`);
- } else {
- showNotification(`📊 Analysis complete for ${username} (not enough messages or already reported today)`);
- }
+ if (result.reported) {
+ showNotification(`✅ Analysis complete! Report sent to bot owner for ${username}`);
} else {
- throw new Error(result.message || 'Failed to analyze user');
+ showNotification(`📊 Analysis complete for ${username} (not enough messages or already reported today)`);
}
} catch (error) {
console.error('Failed to analyze user:', error);
- showNotification(error.message || 'Failed to analyze user', 'error');
}
}
@@ -4617,17 +4400,10 @@ function toggleCustomPrompt() {
try {
showNotification('Starting DM interaction analysis...', 'info');
- const response = await fetch('/dms/analysis/run', { method: 'POST' });
- const result = await response.json();
-
- if (response.ok) {
- showNotification('✅ DM analysis completed! Check bot owner\'s DMs for any reports.');
- } else {
- throw new Error(result.message || 'Failed to run analysis');
- }
+ await apiCall('/dms/analysis/run', 'POST');
+ showNotification('✅ DM analysis completed! Check bot owner\'s DMs for any reports.');
} catch (error) {
console.error('Failed to run DM analysis:', error);
- showNotification(error.message || 'Failed to run DM analysis', 'error');
}
}
@@ -4635,17 +4411,10 @@ function toggleCustomPrompt() {
try {
showNotification('Loading analysis reports...', 'info');
- const response = await fetch('/dms/analysis/reports?limit=50');
- const result = await response.json();
-
- if (response.ok) {
- displayAnalysisReports(result.reports);
- } else {
- throw new Error(result.message || 'Failed to load reports');
- }
+ const result = await apiCall('/dms/analysis/reports?limit=50');
+ displayAnalysisReports(result.reports);
} catch (error) {
console.error('Failed to load reports:', error);
- showNotification(error.message || 'Failed to load reports', 'error');
}
}
@@ -4736,20 +4505,13 @@ function toggleCustomPrompt() {
async function loadBlockedUsers() {
try {
- const response = await fetch('/dms/blocked-users');
- const result = await response.json();
-
- if (response.ok) {
- // Hide DM users list and show blocked users section
- document.getElementById('dm-users-list').style.display = 'none';
- document.getElementById('blocked-users-section').style.display = 'block';
- displayBlockedUsers(result.blocked_users);
- } else {
- throw new Error(result.message || 'Failed to load blocked users');
- }
+ const result = await apiCall('/dms/blocked-users');
+ // Hide DM users list and show blocked users section
+ document.getElementById('dm-users-list').style.display = 'none';
+ document.getElementById('blocked-users-section').style.display = 'block';
+ displayBlockedUsers(result.blocked_users);
} catch (error) {
console.error('Failed to load blocked users:', error);
- showNotification(error.message || 'Failed to load blocked users', 'error');
}
}
@@ -4790,26 +4552,20 @@ function toggleCustomPrompt() {
async function exportAllDMs() {
try {
- const response = await fetch('/dms/users');
- const result = await response.json();
+ const result = await apiCall('/dms/users');
- if (response.ok && result.users) {
- let exportCount = 0;
- for (const user of result.users) {
- try {
- await exportUserDMs(user.user_id);
- exportCount++;
- } catch (e) {
- console.error(`Failed to export DMs for user ${user.user_id}:`, e);
- }
+ let exportCount = 0;
+ for (const user of (result.users || [])) {
+ try {
+ await exportUserDMs(user.user_id);
+ exportCount++;
+ } catch (e) {
+ console.error(`Failed to export DMs for user ${user.user_id}:`, e);
}
- showNotification(`Exported DMs for ${exportCount} users`);
- } else {
- throw new Error(result.message || 'Failed to load DM users for export');
}
+ showNotification(`Exported DMs for ${exportCount} users`);
} catch (error) {
console.error('Failed to export all DMs:', error);
- showNotification(error.message || 'Failed to export all DMs', 'error');
}
}
@@ -4824,8 +4580,7 @@ async function loadAutonomousStats() {
}
try {
- const response = await fetch('/autonomous/stats');
- const data = await response.json();
+ const data = await apiCall('/autonomous/stats');
if (!data.servers || !data.servers[selectedGuildId]) {
document.getElementById('autonomous-stats-display').innerHTML = '
Server not found or not initialized.
'; @@ -4836,7 +4591,6 @@ async function loadAutonomousStats() { displayAutonomousStats(serverData); } catch (error) { console.error('Failed to load autonomous stats:', error); - showNotification('Failed to load autonomous stats', 'error'); } } @@ -5040,8 +4794,7 @@ function toggleChatImageUpload() { // Load voice debug mode setting from server async function loadVoiceDebugMode() { try { - const response = await fetch('/voice/debug-mode'); - const data = await response.json(); + const data = await apiCall('/voice/debug-mode'); const checkbox = document.getElementById('voice-debug-mode'); if (checkbox && data.debug_mode !== undefined) { checkbox.checked = data.debug_mode; @@ -5526,8 +5279,7 @@ function updateVoiceCallHistoryDisplay() { async function refreshMemoryStats() { try { // Fetch Cat status - const statusRes = await fetch('/memory/status'); - const statusData = await statusRes.json(); + const statusData = await apiCall('/memory/status'); const indicator = document.getElementById('cat-status-indicator'); const toggleBtn = document.getElementById('cat-toggle-btn'); @@ -5547,8 +5299,7 @@ async function refreshMemoryStats() { toggleBtn.style.borderColor = statusData.enabled ? '#4a9a4a' : '#9a4a4a'; // Fetch memory stats - const statsRes = await fetch('/memory/stats'); - const statsData = await statsRes.json(); + const statsData = await apiCall('/memory/stats'); if (statsData.success && statsData.collections) { const collections = {}; @@ -5570,8 +5321,7 @@ async function refreshMemoryStats() { async function toggleCatIntegration() { try { - const statusRes = await fetch('/memory/status'); - const statusData = await statusRes.json(); + const statusData = await apiCall('/memory/status'); const newState = !statusData.enabled; const formData = new FormData(); @@ -5599,8 +5349,7 @@ async function triggerConsolidation() { resultDiv.style.display = 'none'; try { - const res = await fetch('/memory/consolidate', { method: 'POST' }); - const data = await res.json(); + const data = await apiCall('/memory/consolidate', 'POST'); if (data.success) { status.textContent = '✅ Consolidation complete!'; @@ -5627,8 +5376,7 @@ async function loadFacts() { listDiv.innerHTML = '