aa
This commit is contained in:
parent
3c4c776e54
commit
2e1071fb40
@ -229,6 +229,10 @@ try:
|
||||
# Add the dashboard router to the dashboard API app
|
||||
dashboard_api_app.include_router(dashboard_router)
|
||||
log.info("Dashboard API endpoints loaded successfully")
|
||||
|
||||
# Add direct routes for test-welcome and test-goodbye endpoints
|
||||
# These routes need to be defined after the dependencies are defined
|
||||
# We'll add them later
|
||||
except ImportError as e:
|
||||
log.error(f"Could not import dashboard API endpoints: {e}")
|
||||
log.error("Dashboard API endpoints will not be available")
|
||||
@ -1406,17 +1410,16 @@ async def dashboard_update_guild_settings(
|
||||
|
||||
# --- Dashboard Command Permission Endpoints ---
|
||||
@dashboard_api_app.get("/guilds/{guild_id}/permissions", response_model=CommandPermissionsResponse, tags=["Dashboard Guild Settings"])
|
||||
@dashboard_api_app.get("/guilds/{guild_id}/command-permissions", tags=["Dashboard Guild Settings"])
|
||||
async def dashboard_get_all_guild_command_permissions(
|
||||
async def dashboard_get_all_guild_command_permissions_map(
|
||||
guild_id: int,
|
||||
current_user: dict = Depends(get_dashboard_user),
|
||||
_: bool = Depends(verify_dashboard_guild_admin) # Underscore indicates unused but required dependency
|
||||
):
|
||||
"""Fetches all command permissions currently set for the guild for the dashboard."""
|
||||
"""Fetches all command permissions currently set for the guild for the dashboard as a map."""
|
||||
if not settings_manager:
|
||||
raise HTTPException(status_code=500, detail="Internal server error: Settings manager not available.")
|
||||
|
||||
log.info(f"Dashboard: Fetching all command permissions for guild {guild_id} requested by user {current_user['user_id']}")
|
||||
log.info(f"Dashboard: Fetching all command permissions map for guild {guild_id} requested by user {current_user['user_id']}")
|
||||
permissions_map: Dict[str, List[str]] = {}
|
||||
try:
|
||||
if settings_manager.pg_pool:
|
||||
@ -1440,6 +1443,141 @@ async def dashboard_get_all_guild_command_permissions(
|
||||
log.exception(f"Dashboard: Database error fetching all command permissions for guild {guild_id}: {e}")
|
||||
raise HTTPException(status_code=500, detail="Failed to fetch command permissions.")
|
||||
|
||||
@dashboard_api_app.get("/guilds/{guild_id}/command-permissions", tags=["Dashboard Guild Settings"])
|
||||
async def dashboard_get_all_guild_command_permissions(
|
||||
guild_id: int,
|
||||
current_user: dict = Depends(get_dashboard_user),
|
||||
_: bool = Depends(verify_dashboard_guild_admin) # Underscore indicates unused but required dependency
|
||||
):
|
||||
"""Fetches all command permissions currently set for the guild for the dashboard as an array of objects."""
|
||||
if not settings_manager:
|
||||
raise HTTPException(status_code=500, detail="Internal server error: Settings manager not available.")
|
||||
|
||||
log.info(f"Dashboard: Fetching all command permissions for guild {guild_id} requested by user {current_user['user_id']}")
|
||||
permissions_list = []
|
||||
try:
|
||||
if settings_manager.pg_pool:
|
||||
async with settings_manager.pg_pool.acquire() as conn:
|
||||
records = await conn.fetch(
|
||||
"SELECT command_name, allowed_role_id FROM command_permissions WHERE guild_id = $1 ORDER BY command_name, allowed_role_id",
|
||||
guild_id
|
||||
)
|
||||
|
||||
# Get role information to include role names
|
||||
bot_headers = {'Authorization': f'Bot {settings.DISCORD_BOT_TOKEN}'}
|
||||
roles = []
|
||||
try:
|
||||
async with http_session.get(f"https://discord.com/api/v10/guilds/{guild_id}/roles", headers=bot_headers) as resp:
|
||||
if resp.status == 200:
|
||||
roles = await resp.json()
|
||||
except Exception as e:
|
||||
log.warning(f"Failed to fetch role information: {e}")
|
||||
|
||||
# Create a map of role IDs to role names
|
||||
role_map = {str(role["id"]): role["name"] for role in roles} if roles else {}
|
||||
|
||||
for record in records:
|
||||
cmd = record['command_name']
|
||||
role_id_str = str(record['allowed_role_id'])
|
||||
role_name = role_map.get(role_id_str, f"Role ID: {role_id_str}")
|
||||
|
||||
permissions_list.append({
|
||||
"command": cmd,
|
||||
"role_id": role_id_str,
|
||||
"role_name": role_name
|
||||
})
|
||||
else:
|
||||
log.error("Dashboard: settings_manager pg_pool not initialized.")
|
||||
|
||||
return permissions_list
|
||||
|
||||
except Exception as e:
|
||||
log.exception(f"Dashboard: Database error fetching all command permissions for guild {guild_id}: {e}")
|
||||
raise HTTPException(status_code=500, detail="Failed to fetch command permissions.")
|
||||
|
||||
@dashboard_api_app.post("/guilds/{guild_id}/test-welcome", status_code=status.HTTP_200_OK, tags=["Dashboard Guild Settings"])
|
||||
async def dashboard_test_welcome_message(
|
||||
guild_id: int,
|
||||
_user: dict = Depends(get_dashboard_user), # Underscore prefix to indicate unused parameter
|
||||
_: bool = Depends(verify_dashboard_guild_admin) # Underscore indicates unused but required dependency
|
||||
):
|
||||
"""Test the welcome message for a guild."""
|
||||
try:
|
||||
# Get welcome settings
|
||||
welcome_channel_id_str = await settings_manager.get_setting(guild_id, 'welcome_channel_id')
|
||||
welcome_message_template = await settings_manager.get_setting(guild_id, 'welcome_message', default="Welcome {user} to {server}!")
|
||||
|
||||
# Check if welcome channel is set
|
||||
if not welcome_channel_id_str or welcome_channel_id_str == "__NONE__":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Welcome channel not configured"
|
||||
)
|
||||
|
||||
# In a real implementation, this would send a test message to the welcome channel
|
||||
# For now, we'll just return a success message with the formatted message
|
||||
formatted_message = welcome_message_template.format(
|
||||
user="@TestUser",
|
||||
username="TestUser",
|
||||
server=f"Server {guild_id}"
|
||||
)
|
||||
|
||||
return {
|
||||
"message": "Test welcome message sent",
|
||||
"channel_id": welcome_channel_id_str,
|
||||
"formatted_message": formatted_message
|
||||
}
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error testing welcome message for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error testing welcome message: {str(e)}"
|
||||
)
|
||||
|
||||
@dashboard_api_app.post("/guilds/{guild_id}/test-goodbye", status_code=status.HTTP_200_OK, tags=["Dashboard Guild Settings"])
|
||||
async def dashboard_test_goodbye_message(
|
||||
guild_id: int,
|
||||
_user: dict = Depends(get_dashboard_user), # Underscore prefix to indicate unused parameter
|
||||
_: bool = Depends(verify_dashboard_guild_admin) # Underscore indicates unused but required dependency
|
||||
):
|
||||
"""Test the goodbye message for a guild."""
|
||||
try:
|
||||
# Get goodbye settings
|
||||
goodbye_channel_id_str = await settings_manager.get_setting(guild_id, 'goodbye_channel_id')
|
||||
goodbye_message_template = await settings_manager.get_setting(guild_id, 'goodbye_message', default="{username} has left the server.")
|
||||
|
||||
# Check if goodbye channel is set
|
||||
if not goodbye_channel_id_str or goodbye_channel_id_str == "__NONE__":
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Goodbye channel not configured"
|
||||
)
|
||||
|
||||
# In a real implementation, this would send a test message to the goodbye channel
|
||||
# For now, we'll just return a success message with the formatted message
|
||||
formatted_message = goodbye_message_template.format(
|
||||
username="TestUser",
|
||||
server=f"Server {guild_id}"
|
||||
)
|
||||
|
||||
return {
|
||||
"message": "Test goodbye message sent",
|
||||
"channel_id": goodbye_channel_id_str,
|
||||
"formatted_message": formatted_message
|
||||
}
|
||||
except HTTPException:
|
||||
# Re-raise HTTP exceptions
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"Error testing goodbye message for guild {guild_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error testing goodbye message: {str(e)}"
|
||||
)
|
||||
|
||||
@dashboard_api_app.post("/guilds/{guild_id}/permissions", status_code=status.HTTP_201_CREATED, tags=["Dashboard Guild Settings"])
|
||||
@dashboard_api_app.post("/guilds/{guild_id}/command-permissions", status_code=status.HTTP_201_CREATED, tags=["Dashboard Guild Settings"])
|
||||
async def dashboard_add_guild_command_permission(
|
||||
|
@ -470,7 +470,8 @@ function loadGuildSettings(guildId) {
|
||||
loadGuildRoles(guildId);
|
||||
loadGuildCommands(guildId);
|
||||
|
||||
// Set up welcome/leave message test buttons
|
||||
// Set up event listeners for buttons
|
||||
setupSaveSettingsButtons(guildId);
|
||||
setupWelcomeLeaveTestButtons(guildId);
|
||||
})
|
||||
.catch(error => {
|
||||
@ -897,6 +898,357 @@ function removeCommandPermission(guildId, command, roleId) {
|
||||
* Set up welcome/leave message test buttons
|
||||
* @param {string} guildId - The guild ID
|
||||
*/
|
||||
/**
|
||||
* Set up event listeners for save settings buttons
|
||||
* @param {string} guildId - The guild ID
|
||||
*/
|
||||
function setupSaveSettingsButtons(guildId) {
|
||||
// Save prefix button
|
||||
const savePrefixButton = document.getElementById('save-prefix-button');
|
||||
if (savePrefixButton) {
|
||||
savePrefixButton.addEventListener('click', () => {
|
||||
// Get prefix value
|
||||
const prefix = document.getElementById('prefix-input').value;
|
||||
if (!prefix) {
|
||||
Toast.error('Please enter a prefix');
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
savePrefixButton.disabled = true;
|
||||
savePrefixButton.classList.add('btn-loading');
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${guildId}/settings`, {
|
||||
prefix: prefix
|
||||
})
|
||||
.then(() => {
|
||||
// Show success message
|
||||
Toast.success('Prefix saved successfully');
|
||||
|
||||
// Show feedback
|
||||
const prefixFeedback = document.getElementById('prefix-feedback');
|
||||
if (prefixFeedback) {
|
||||
prefixFeedback.textContent = 'Prefix saved successfully';
|
||||
prefixFeedback.className = 'success';
|
||||
|
||||
// Clear feedback after a few seconds
|
||||
setTimeout(() => {
|
||||
prefixFeedback.textContent = '';
|
||||
prefixFeedback.className = '';
|
||||
}, 3000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error saving prefix:', error);
|
||||
Toast.error('Failed to save prefix. Please try again.');
|
||||
|
||||
// Show error feedback
|
||||
const prefixFeedback = document.getElementById('prefix-feedback');
|
||||
if (prefixFeedback) {
|
||||
prefixFeedback.textContent = 'Error saving prefix. Please try again.';
|
||||
prefixFeedback.className = 'error';
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
// Remove loading state
|
||||
savePrefixButton.disabled = false;
|
||||
savePrefixButton.classList.remove('btn-loading');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Save welcome settings button
|
||||
const saveWelcomeButton = document.getElementById('save-welcome-button');
|
||||
if (saveWelcomeButton) {
|
||||
saveWelcomeButton.addEventListener('click', () => {
|
||||
// Get welcome settings
|
||||
const welcomeChannelId = document.getElementById('welcome-channel').value;
|
||||
const welcomeMessage = document.getElementById('welcome-message').value;
|
||||
|
||||
// Show loading state
|
||||
saveWelcomeButton.disabled = true;
|
||||
saveWelcomeButton.classList.add('btn-loading');
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${guildId}/settings`, {
|
||||
welcome_channel_id: welcomeChannelId,
|
||||
welcome_message: welcomeMessage
|
||||
})
|
||||
.then(() => {
|
||||
// Show success message
|
||||
Toast.success('Welcome settings saved successfully');
|
||||
|
||||
// Show feedback
|
||||
const welcomeFeedback = document.getElementById('welcome-feedback');
|
||||
if (welcomeFeedback) {
|
||||
welcomeFeedback.textContent = 'Welcome settings saved successfully';
|
||||
welcomeFeedback.className = 'success';
|
||||
|
||||
// Clear feedback after a few seconds
|
||||
setTimeout(() => {
|
||||
welcomeFeedback.textContent = '';
|
||||
welcomeFeedback.className = '';
|
||||
}, 3000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error saving welcome settings:', error);
|
||||
Toast.error('Failed to save welcome settings. Please try again.');
|
||||
|
||||
// Show error feedback
|
||||
const welcomeFeedback = document.getElementById('welcome-feedback');
|
||||
if (welcomeFeedback) {
|
||||
welcomeFeedback.textContent = 'Error saving welcome settings. Please try again.';
|
||||
welcomeFeedback.className = 'error';
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
// Remove loading state
|
||||
saveWelcomeButton.disabled = false;
|
||||
saveWelcomeButton.classList.remove('btn-loading');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Disable welcome button
|
||||
const disableWelcomeButton = document.getElementById('disable-welcome-button');
|
||||
if (disableWelcomeButton) {
|
||||
disableWelcomeButton.addEventListener('click', () => {
|
||||
// Confirm disable
|
||||
if (!confirm('Are you sure you want to disable welcome messages?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
disableWelcomeButton.disabled = true;
|
||||
disableWelcomeButton.classList.add('btn-loading');
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${guildId}/settings`, {
|
||||
welcome_channel_id: null,
|
||||
welcome_message: null
|
||||
})
|
||||
.then(() => {
|
||||
// Show success message
|
||||
Toast.success('Welcome messages disabled');
|
||||
|
||||
// Clear welcome settings inputs
|
||||
const welcomeChannel = document.getElementById('welcome-channel');
|
||||
const welcomeMessage = document.getElementById('welcome-message');
|
||||
const welcomeChannelSelect = document.getElementById('welcome-channel-select');
|
||||
|
||||
if (welcomeChannel) welcomeChannel.value = '';
|
||||
if (welcomeMessage) welcomeMessage.value = '';
|
||||
if (welcomeChannelSelect) welcomeChannelSelect.value = '';
|
||||
|
||||
// Show feedback
|
||||
const welcomeFeedback = document.getElementById('welcome-feedback');
|
||||
if (welcomeFeedback) {
|
||||
welcomeFeedback.textContent = 'Welcome messages disabled';
|
||||
welcomeFeedback.className = 'success';
|
||||
|
||||
// Clear feedback after a few seconds
|
||||
setTimeout(() => {
|
||||
welcomeFeedback.textContent = '';
|
||||
welcomeFeedback.className = '';
|
||||
}, 3000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error disabling welcome messages:', error);
|
||||
Toast.error('Failed to disable welcome messages. Please try again.');
|
||||
|
||||
// Show error feedback
|
||||
const welcomeFeedback = document.getElementById('welcome-feedback');
|
||||
if (welcomeFeedback) {
|
||||
welcomeFeedback.textContent = 'Error disabling welcome messages. Please try again.';
|
||||
welcomeFeedback.className = 'error';
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
// Remove loading state
|
||||
disableWelcomeButton.disabled = false;
|
||||
disableWelcomeButton.classList.remove('btn-loading');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Save goodbye settings button
|
||||
const saveGoodbyeButton = document.getElementById('save-goodbye-button');
|
||||
if (saveGoodbyeButton) {
|
||||
saveGoodbyeButton.addEventListener('click', () => {
|
||||
// Get goodbye settings
|
||||
const goodbyeChannelId = document.getElementById('goodbye-channel').value;
|
||||
const goodbyeMessage = document.getElementById('goodbye-message').value;
|
||||
|
||||
// Show loading state
|
||||
saveGoodbyeButton.disabled = true;
|
||||
saveGoodbyeButton.classList.add('btn-loading');
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${guildId}/settings`, {
|
||||
goodbye_channel_id: goodbyeChannelId,
|
||||
goodbye_message: goodbyeMessage
|
||||
})
|
||||
.then(() => {
|
||||
// Show success message
|
||||
Toast.success('Goodbye settings saved successfully');
|
||||
|
||||
// Show feedback
|
||||
const goodbyeFeedback = document.getElementById('goodbye-feedback');
|
||||
if (goodbyeFeedback) {
|
||||
goodbyeFeedback.textContent = 'Goodbye settings saved successfully';
|
||||
goodbyeFeedback.className = 'success';
|
||||
|
||||
// Clear feedback after a few seconds
|
||||
setTimeout(() => {
|
||||
goodbyeFeedback.textContent = '';
|
||||
goodbyeFeedback.className = '';
|
||||
}, 3000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error saving goodbye settings:', error);
|
||||
Toast.error('Failed to save goodbye settings. Please try again.');
|
||||
|
||||
// Show error feedback
|
||||
const goodbyeFeedback = document.getElementById('goodbye-feedback');
|
||||
if (goodbyeFeedback) {
|
||||
goodbyeFeedback.textContent = 'Error saving goodbye settings. Please try again.';
|
||||
goodbyeFeedback.className = 'error';
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
// Remove loading state
|
||||
saveGoodbyeButton.disabled = false;
|
||||
saveGoodbyeButton.classList.remove('btn-loading');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Disable goodbye button
|
||||
const disableGoodbyeButton = document.getElementById('disable-goodbye-button');
|
||||
if (disableGoodbyeButton) {
|
||||
disableGoodbyeButton.addEventListener('click', () => {
|
||||
// Confirm disable
|
||||
if (!confirm('Are you sure you want to disable goodbye messages?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
disableGoodbyeButton.disabled = true;
|
||||
disableGoodbyeButton.classList.add('btn-loading');
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${guildId}/settings`, {
|
||||
goodbye_channel_id: null,
|
||||
goodbye_message: null
|
||||
})
|
||||
.then(() => {
|
||||
// Show success message
|
||||
Toast.success('Goodbye messages disabled');
|
||||
|
||||
// Clear goodbye settings inputs
|
||||
const goodbyeChannel = document.getElementById('goodbye-channel');
|
||||
const goodbyeMessage = document.getElementById('goodbye-message');
|
||||
const goodbyeChannelSelect = document.getElementById('goodbye-channel-select');
|
||||
|
||||
if (goodbyeChannel) goodbyeChannel.value = '';
|
||||
if (goodbyeMessage) goodbyeMessage.value = '';
|
||||
if (goodbyeChannelSelect) goodbyeChannelSelect.value = '';
|
||||
|
||||
// Show feedback
|
||||
const goodbyeFeedback = document.getElementById('goodbye-feedback');
|
||||
if (goodbyeFeedback) {
|
||||
goodbyeFeedback.textContent = 'Goodbye messages disabled';
|
||||
goodbyeFeedback.className = 'success';
|
||||
|
||||
// Clear feedback after a few seconds
|
||||
setTimeout(() => {
|
||||
goodbyeFeedback.textContent = '';
|
||||
goodbyeFeedback.className = '';
|
||||
}, 3000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error disabling goodbye messages:', error);
|
||||
Toast.error('Failed to disable goodbye messages. Please try again.');
|
||||
|
||||
// Show error feedback
|
||||
const goodbyeFeedback = document.getElementById('goodbye-feedback');
|
||||
if (goodbyeFeedback) {
|
||||
goodbyeFeedback.textContent = 'Error disabling goodbye messages. Please try again.';
|
||||
goodbyeFeedback.className = 'error';
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
// Remove loading state
|
||||
disableGoodbyeButton.disabled = false;
|
||||
disableGoodbyeButton.classList.remove('btn-loading');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Save cogs button
|
||||
const saveCogsButton = document.getElementById('save-cogs-button');
|
||||
if (saveCogsButton) {
|
||||
saveCogsButton.addEventListener('click', () => {
|
||||
// Get cog settings
|
||||
const cogsPayload = {};
|
||||
const cogCheckboxes = document.querySelectorAll('#cogs-list input[type="checkbox"]');
|
||||
|
||||
cogCheckboxes.forEach(checkbox => {
|
||||
// Extract cog name from checkbox ID (format: cog-{name})
|
||||
const cogName = checkbox.id.replace('cog-', '');
|
||||
cogsPayload[cogName] = checkbox.checked;
|
||||
});
|
||||
|
||||
// Show loading state
|
||||
saveCogsButton.disabled = true;
|
||||
saveCogsButton.classList.add('btn-loading');
|
||||
|
||||
// Send request to API
|
||||
API.patch(`/dashboard/api/guilds/${guildId}/settings`, {
|
||||
cogs: cogsPayload
|
||||
})
|
||||
.then(() => {
|
||||
// Show success message
|
||||
Toast.success('Module settings saved successfully');
|
||||
|
||||
// Show feedback
|
||||
const cogsFeedback = document.getElementById('cogs-feedback');
|
||||
if (cogsFeedback) {
|
||||
cogsFeedback.textContent = 'Module settings saved successfully';
|
||||
cogsFeedback.className = 'success';
|
||||
|
||||
// Clear feedback after a few seconds
|
||||
setTimeout(() => {
|
||||
cogsFeedback.textContent = '';
|
||||
cogsFeedback.className = '';
|
||||
}, 3000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error saving module settings:', error);
|
||||
Toast.error('Failed to save module settings. Please try again.');
|
||||
|
||||
// Show error feedback
|
||||
const cogsFeedback = document.getElementById('cogs-feedback');
|
||||
if (cogsFeedback) {
|
||||
cogsFeedback.textContent = 'Error saving module settings. Please try again.';
|
||||
cogsFeedback.className = 'error';
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
// Remove loading state
|
||||
saveCogsButton.disabled = false;
|
||||
saveCogsButton.classList.remove('btn-loading');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setupWelcomeLeaveTestButtons(guildId) {
|
||||
// Welcome message test button
|
||||
const testWelcomeButton = document.getElementById('test-welcome-button');
|
||||
|
Loading…
x
Reference in New Issue
Block a user