refactor: standardize raw fetch() calls to use apiCall() wrapper
Convert 47 raw fetch+response.json+error-handling patterns to use the centralized apiCall() utility. The 11 remaining raw fetch() calls are FormData uploads or SSE streaming that require direct fetch access.
This commit is contained in:
@@ -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({
|
||||
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();
|
||||
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();
|
||||
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) {
|
||||
const result = await apiCall(endpoint, 'POST');
|
||||
showNotification(result.message || 'Action triggered successfully');
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to trigger action');
|
||||
}
|
||||
} 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) {
|
||||
const result = await apiCall(endpoint, 'POST');
|
||||
showNotification(result.message || 'Engagement triggered successfully');
|
||||
// Optionally collapse the submenu after successful trigger
|
||||
// toggleEngageSubmenu();
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to trigger engagement');
|
||||
}
|
||||
} 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) {
|
||||
const result = await apiCall(endpoint, 'POST');
|
||||
showNotification(result.message || 'Tweet share triggered successfully');
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to trigger tweet share');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to trigger tweet share:', error);
|
||||
showNotification(error.message || 'Failed to trigger tweet share', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3326,13 +3264,8 @@ 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();
|
||||
|
||||
if (response.ok && result.status === 'ok') {
|
||||
statusDiv.textContent = `✅ ${result.message}`;
|
||||
statusDiv.style.color = 'green';
|
||||
|
||||
@@ -3343,14 +3276,10 @@ async function changeProfilePicture() {
|
||||
}
|
||||
|
||||
showNotification('Profile picture changed successfully!');
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to change profile picture');
|
||||
}
|
||||
} 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();
|
||||
|
||||
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');
|
||||
}
|
||||
} 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,13 +3422,8 @@ 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();
|
||||
|
||||
if (response.ok && result.status === 'ok') {
|
||||
statusDiv.textContent = `✅ ${result.message}`;
|
||||
statusDiv.style.color = 'green';
|
||||
|
||||
@@ -3516,14 +3431,10 @@ async function resetRoleColor() {
|
||||
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');
|
||||
}
|
||||
} 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,19 +3519,10 @@ 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
|
||||
@@ -3638,12 +3531,8 @@ async function sendCustomPrompt() {
|
||||
}
|
||||
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');
|
||||
}
|
||||
} 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) {
|
||||
const result = await apiCall(endpoint, 'POST');
|
||||
showNotification(result.message || 'Bedtime reminder sent successfully');
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to send bedtime reminder');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to send bedtime reminder:', error);
|
||||
showNotification(error.message || 'Failed to send bedtime reminder', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3892,10 +3770,8 @@ 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';
|
||||
|
||||
@@ -3908,9 +3784,6 @@ ${result.comfyui_running ? `• Detected ComfyUI URL: ${result.comfyui_url}` : '
|
||||
<strong>Overall Status:</strong> ${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,15 +3804,8 @@ 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();
|
||||
|
||||
if (response.ok) {
|
||||
const detectionIcon = result.is_image_request ? '✅' : '❌';
|
||||
const detectionText = result.is_image_request ? 'WILL trigger image generation' : 'will NOT trigger image generation';
|
||||
|
||||
@@ -3949,10 +3815,6 @@ ${result.is_image_request ? `<br><strong>Extracted Prompt:</strong> "${result.ex
|
||||
<br><strong>Original Message:</strong> "${result.original_message}"`;
|
||||
|
||||
resultsDiv.style.color = result.is_image_request ? '#4CAF50' : '#ff9800';
|
||||
} else {
|
||||
resultsDiv.innerHTML = `❌ Detection test failed: ${result.message}`;
|
||||
resultsDiv.style.color = 'red';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to test image detection:', error);
|
||||
resultsDiv.innerHTML = `❌ Error: ${error.message}`;
|
||||
@@ -3978,15 +3840,8 @@ 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();
|
||||
|
||||
if (response.ok && result.status === 'ok') {
|
||||
statusDiv.innerHTML = `✅ Image generated successfully!`;
|
||||
statusDiv.style.color = '#4CAF50';
|
||||
|
||||
@@ -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) {
|
||||
const result = await apiCall('/dms/users');
|
||||
displayDMUsers(result.users);
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to load DM users');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load DM users:', error);
|
||||
showNotification(error.message || 'Failed to load DM users', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4306,13 +4150,11 @@ 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);
|
||||
@@ -4322,12 +4164,8 @@ function toggleCustomPrompt() {
|
||||
// Go back to user list
|
||||
loadDMUsers();
|
||||
}
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to load conversations');
|
||||
}
|
||||
} 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) {
|
||||
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
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to export DMs');
|
||||
}
|
||||
} 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) {
|
||||
await apiCall(`/dms/users/${userIdStr}`, 'DELETE');
|
||||
showNotification(`Deleted DM logs for user ${userIdStr}`);
|
||||
loadDMUsers(); // Refresh the list
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to delete DM logs');
|
||||
}
|
||||
} 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) {
|
||||
await apiCall(`/dms/users/${userIdStr}/block`, 'POST');
|
||||
showNotification(`${username} has been blocked from sending DMs`);
|
||||
loadDMUsers(); // Refresh the list
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to block user');
|
||||
}
|
||||
} 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) {
|
||||
await apiCall(`/dms/users/${userIdStr}/unblock`, 'POST');
|
||||
showNotification(`${username} has been unblocked`);
|
||||
loadBlockedUsers(); // Refresh blocked users list
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to unblock user');
|
||||
}
|
||||
} 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) {
|
||||
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);
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to delete conversations');
|
||||
}
|
||||
} 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) {
|
||||
await apiCall(`/dms/users/${userIdStr}/delete-completely`, 'POST');
|
||||
showNotification(`${username} has been completely deleted from the system`);
|
||||
loadDMUsers(); // Refresh the list
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to delete user completely');
|
||||
}
|
||||
} 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) {
|
||||
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);
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to delete message');
|
||||
}
|
||||
} 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)`);
|
||||
}
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to analyze user');
|
||||
}
|
||||
} 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) {
|
||||
await apiCall('/dms/analysis/run', 'POST');
|
||||
showNotification('✅ DM analysis completed! Check bot owner\'s DMs for any reports.');
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to run analysis');
|
||||
}
|
||||
} 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) {
|
||||
const result = await apiCall('/dms/analysis/reports?limit=50');
|
||||
displayAnalysisReports(result.reports);
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to load 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) {
|
||||
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);
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to load blocked users');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load blocked users:', error);
|
||||
showNotification(error.message || 'Failed to load blocked users', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4790,12 +4552,10 @@ 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) {
|
||||
for (const user of (result.users || [])) {
|
||||
try {
|
||||
await exportUserDMs(user.user_id);
|
||||
exportCount++;
|
||||
@@ -4804,12 +4564,8 @@ function toggleCustomPrompt() {
|
||||
}
|
||||
}
|
||||
showNotification(`Exported DMs for ${exportCount} users`);
|
||||
} else {
|
||||
throw new Error(result.message || 'Failed to load DM users for export');
|
||||
}
|
||||
} 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 = '<p style="color: #ff5555;">Server not found or not initialized.</p>';
|
||||
@@ -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 = '<div style="text-align: center; color: #888; padding: 1rem;">Loading facts...</div>';
|
||||
|
||||
try {
|
||||
const res = await fetch('/memory/facts');
|
||||
const data = await res.json();
|
||||
const data = await apiCall('/memory/facts');
|
||||
|
||||
if (!data.success || data.count === 0) {
|
||||
listDiv.innerHTML = '<div style="text-align: center; color: #666; padding: 2rem;">No declarative facts stored yet.</div>';
|
||||
@@ -5670,8 +5418,7 @@ async function loadEpisodicMemories() {
|
||||
listDiv.innerHTML = '<div style="text-align: center; color: #888; padding: 1rem;">Loading memories...</div>';
|
||||
|
||||
try {
|
||||
const res = await fetch('/memory/episodic');
|
||||
const data = await res.json();
|
||||
const data = await apiCall('/memory/episodic');
|
||||
|
||||
if (!data.success || data.count === 0) {
|
||||
listDiv.innerHTML = '<div style="text-align: center; color: #666; padding: 2rem;">No episodic memories stored yet.</div>';
|
||||
@@ -5712,8 +5459,7 @@ async function deleteMemoryPoint(collection, pointId, btnElement) {
|
||||
if (!confirm(`Delete this ${collection} memory point?`)) return;
|
||||
|
||||
try {
|
||||
const res = await fetch(`/memory/point/${collection}/${pointId}`, { method: 'DELETE' });
|
||||
const data = await res.json();
|
||||
const data = await apiCall(`/memory/point/${collection}/${pointId}`, 'DELETE');
|
||||
|
||||
if (data.success) {
|
||||
// Remove the row from the UI
|
||||
@@ -5725,7 +5471,7 @@ async function deleteMemoryPoint(collection, pointId, btnElement) {
|
||||
showNotification('Failed to delete: ' + (data.error || 'Unknown error'), 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
showNotification('Error: ' + err.message, 'error');
|
||||
console.error('Failed to delete memory point:', err);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5780,12 +5526,7 @@ async function executeDeleteAllMemories() {
|
||||
btn.textContent = '⏳ Deleting...';
|
||||
|
||||
try {
|
||||
const res = await fetch('/memory/delete', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ confirmation: input })
|
||||
});
|
||||
const data = await res.json();
|
||||
const data = await apiCall('/memory/delete', 'POST', { confirmation: input });
|
||||
|
||||
if (data.success) {
|
||||
showNotification('All memories have been permanently deleted', 'success');
|
||||
@@ -5795,7 +5536,7 @@ async function executeDeleteAllMemories() {
|
||||
showNotification('Deletion failed: ' + (data.error || 'Unknown error'), 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
showNotification('Error: ' + err.message, 'error');
|
||||
console.error('Failed to delete all memories:', err);
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = '🗑️ Permanently Delete All Memories';
|
||||
@@ -5864,17 +5605,11 @@ async function saveMemoryEdit() {
|
||||
saveBtn.textContent = 'Saving...';
|
||||
|
||||
try {
|
||||
const res = await fetch(`/memory/point/${collection}/${pointId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
const data = await apiCall(`/memory/point/${collection}/${pointId}`, 'PUT', {
|
||||
content: content,
|
||||
metadata: { source: source || 'manual_edit' }
|
||||
})
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
showNotification('Memory updated successfully', 'success');
|
||||
closeEditMemoryModal();
|
||||
@@ -5888,7 +5623,7 @@ async function saveMemoryEdit() {
|
||||
showNotification('Failed to update: ' + (data.error || 'Unknown error'), 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
showNotification('Error: ' + err.message, 'error');
|
||||
console.error('Failed to save memory edit:', err);
|
||||
} finally {
|
||||
saveBtn.disabled = false;
|
||||
saveBtn.textContent = 'Save Changes';
|
||||
@@ -5941,20 +5676,14 @@ async function saveNewMemory() {
|
||||
createBtn.textContent = 'Creating...';
|
||||
|
||||
try {
|
||||
const res = await fetch('/memory/create', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
const data = await apiCall('/memory/create', 'POST', {
|
||||
collection: collection,
|
||||
content: content,
|
||||
user_id: userId || null,
|
||||
source: source || 'manual',
|
||||
metadata: {}
|
||||
})
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.success) {
|
||||
showNotification(`${collection === 'declarative' ? 'Fact' : 'Memory'} created successfully`, 'success');
|
||||
closeCreateMemoryModal();
|
||||
@@ -5969,7 +5698,7 @@ async function saveNewMemory() {
|
||||
showNotification('Failed to create: ' + (data.error || 'Unknown error'), 'error');
|
||||
}
|
||||
} catch (err) {
|
||||
showNotification('Error: ' + err.message, 'error');
|
||||
console.error('Failed to save new memory:', err);
|
||||
} finally {
|
||||
createBtn.disabled = false;
|
||||
createBtn.textContent = 'Create Memory';
|
||||
|
||||
Reference in New Issue
Block a user