Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@
"log-punish-role-error": "[Ping Protection] Punishment failed: I cannot punish %tag because their role is higher than or equal to my highest role.",
"log-mute-error": "[Ping Protection] Punishment failed: I cannot mute %tag: %e",
"log-kick-error": "[Ping Protection] Punishment failed: I cannot kick %tag: %e",
"log-kick-dm-failed": "[Ping Protection] Failed to send kick DM to user %u: %e",
"log-action-log-failed": "[Ping Protection] Punishment logging failed: %e",
"log-data-deletion": "[Ping Protection] All data for the user with ID %u has been deleted successfully.",
"log-automod-keyword-limit": "[Ping Protection] Automod keywords exceed 1000 characters limit. Keywords were truncated.",
Expand All @@ -744,6 +745,7 @@
"cmd-desc-actions": "View the moderation action history of a user",
"cmd-desc-panel": "Admin: Open the user management panel",
"cmd-desc-group-list": "Lists protected or whitelisted entities",
"cmd-desc-toggle": "Temporarily toggle your ping protection on or off.",
"cmd-desc-list-protected": "List of all the protected users and roles",
"cmd-desc-list-wl": "List of all the whitelisted roles, channels and users",
"embed-history-title": "Ping history of %u",
Expand All @@ -764,13 +766,14 @@
"field-wl-channels": "Whitelisted Channels",
"field-wl-users": "Whitelisted Users",
"list-none": "None are configured.",
"modal-title": "Confirm data deletion for this user",
"fallback-modal-title": "Confirm data deletion",
"modal-label": "Confirm data deletion by typing this phrase:",
"fallback-modal-label": "Confirm by typing this phrase:",
"modal-phrase": "I understand that the data of this user will be deleted and that this action cannot be undone.",
"fallback-modal-phrase": "I confirm the data deletion of this user with risks.",
"modal-failed": "The phrase you entered is incorrect. Data deletion cancelled.",
"list-user-paused": "temporarily paused",
"del-modal-title": "Confirm data deletion",
"del-modal-label": "Confirm by typing this phrase:",
"del-conf-phrase": "I confirm the data deletion for this user.",
"modal-failed": "The phrase you entered is incorrect. Data deletion has been cancelled.",
"del-modal-timeframe-label": "Only delete data older than (Optional)",
"del-modal-timeframe-ph": "E.g. 7d to delete data older than 7 days. (Leave empty to delete all)",
"del-err-invalid-timeframe": "The timeframe you provided is invalid. Use a positive number of days (e.g. 7) or a format like 7d, 2w, or 24h.",
"field-quick-history": "Quick history view (Last %w weeks)",
"field-quick-desc": "Pings history amount: %p\nModeration actions amount: %m",
"history-disabled": "History logging has been disabled by a bot-configurator.\nAre you (one of) the bot-configurators? You can enable history logging in the \"Data Storage\" tab in the 'ping-protection' module ^^",
Expand All @@ -781,15 +784,20 @@
"meme-spider": "🕷️ [Is this you?](<https://i.kym-cdn.com/entries/icons/original/000/023/397/C-658VsXoAo3ovC.jpg>) - You just pinged yourself.",
"meme-rick": "🎵 [Never gonna give you up, never gonna let you down...](<https://www.youtube.com/watch?v=dQw4w9WgXcQ>) You just Rick Rolled yourself. Also congrats you unlocked the secret easter egg that only has a 1% chance of appearing!!1!1!!",
"meme-grind": "Why are you even pinging yourself 5 times in a row? Anyways continue some more to possibly get the secret meme\n-# (good luck grinding, only a 1% chance of getting it and during testing I had it once after 83 pings)",
"label-jump": "Jump to Message",
"label-jump": "Jump to message",
"ping-mention": "Mention",
"ping-reply": "Reply",
"ping-unknown": "Unknown",
"label-type": "Type of ping",
"no-message-link": "This ping was blocked by AutoMod",
"list-entry-text": "%index. **Pinged %target** at %time\n%link",
"list-entry-text": "%index. **Pinged %target** at %time\n%type",
"punish-log-docs-title": "Troubleshooting",
"punish-log-docs-desc": "This issue is documented in the documentation - you can see how to fix this issue [in the documentation](https://docs.scnx.xyz/docs/custom-bot/modules/moderation/ping-protection/#troubleshooting). Please try the steps mentioned there before contacting support as it's very likely the steps mentioned will fix your issue ^^",
"log-fetch-mod-history-failed": "[Ping Protection] Failed to fetch moderation history for user %u: %e",
"log-warning-build-failed": "[Ping Protection] Failed to build the warning message: %e",
"log-warning-reply-failed": "[Ping Protection] Failed to send the warning message as a reply: %e",
"log-warning-send-failed": "[Ping Protection] Failed to send the fallback warning message in channel %c: %e",
"log-warning-delete-failed": "[Ping Protection] Failed to automatically delete the warning message: %e",
"log-automod-channel-fetch-failed": "[Ping Protection] Failed to refresh the guild channel cache while syncing AutoMod: %e",
"log-automod-rule-delete-failed": "[Ping Protection] Failed to delete the native AutoMod rule: %e",
"log-automod-sync-failed": "[Ping Protection] AutoMod sync failed: %e",
Expand Down Expand Up @@ -829,7 +837,16 @@
"view-moderation-history-description": "View this user's moderation history",
"view-ping-history-description": "View this user's ping history",
"log-automod-role-protection-skipped": "[Ping Protection] Skipped adding role-based protected users to the native AutoMod rule because the GuildMembers intent is not granted. Only explicitly configured protected users are included until GuildMembers is enabled.",
"no-reason": "No reason provided"
"no-reason": "No reason provided",
"toggle-disabled-by-admin": "Toggling your ping protection status is currently disabled by a bot administrator. Please contact them if you want to change your protection status.",
"toggle-err-not-protected": ":x: You are not a protected member, so you cannot toggle your protection status :/",
"toggle-err-failed": "An error occurred while updating your protection status. Please try again later or contact the bot's administrator.",
"toggle-succ-disabled": "Your ping protection is now paused until %time (24 hours). Members can mention you without triggering notices. You can reactivate it anytime using `/ping-protection toggle`.",
"toggle-succ-enabled": "Your ping protection has been reactivated. You are now protected from pings.",
"log-check-preference-failed": "[Ping Protection] Failed to find ping preference for user %u: %e",
"log-toggle-preference-failed": "[Ping Protection] Failed to toggle ping preference for user %u: %e",
"toggle-pref-failed": "An error occurred while toggling your ping protection preference. Please try again later or contact the bot's administrator.",
"toggle-not-protected": "You are not a protected member, so you cannot toggle your ping protection preference."
},
"polls": {
"what-have-i-votet": "What have I voted?",
Expand Down
199 changes: 136 additions & 63 deletions modules/ping-protection/commands/ping-protection.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
const {
generateHistoryResponse,
generateActionsResponse,
generateUserPanel
generateUserPanel,
toggleUserProtection,
isProtectionToggledOff
} = require('../ping-protection');
const {localize} = require('../../../src/functions/localize');
const {truncate, safeSetFooter} = require('../../../src/functions/helpers');
const {
truncate,
safeSetFooter,
dateToDiscordTimestamp
} = require('../../../src/functions/helpers');
const {
EmbedBuilder,
MessageFlags
} = require('discord.js');

module.exports.run = async function (interaction) {
const group = interaction.options.getSubcommandGroup(false);
const sub = interaction.options.getSubcommand(false);

if (group) {
return module.exports.subcommands[group][sub](interaction);
}
return module.exports.subcommands[sub](interaction);
};

// Handles subcommands
module.exports.subcommands = {
'user': {
Expand All @@ -40,6 +36,13 @@ module.exports.subcommands = {
});
},
'panel': async function (interaction) {
const isManager = interaction.member?.permissions.has('Administrator') || interaction.member?.permissions.has('ManageGuild');
if (!isManager) {
return interaction.reply({
content: localize('ping-protection', 'no-permission'),
flags: MessageFlags.Ephemeral
})
}
const user = interaction.options.getUser('user');
const payload = await generateUserPanel(interaction.client, user);
await interaction.reply({
Expand All @@ -48,6 +51,45 @@ module.exports.subcommands = {
});
}
},
'toggle': async function (interaction) {
const generalConfig = interaction.client.configurations['ping-protection']?.['configuration'] || {};
if (!generalConfig.allowProtectionToggle) {
return interaction.reply({
content: localize('ping-protection', 'toggle-disabled-by-admin'),
flags: MessageFlags.Ephemeral
});
}

const targetMember = interaction.member || interaction.user;
const result = await toggleUserProtection(interaction.client, targetMember);

if (!result.success) {
if (result.reason === 'not-protected') {
return interaction.reply({
content: localize('ping-protection', 'toggle-err-not-protected'),
flags: MessageFlags.Ephemeral
});
}
return interaction.reply({
content: localize('ping-protection', 'toggle-err-failed'),
flags: MessageFlags.Ephemeral
});
}

if (result.state === 'disabled') {
return interaction.reply({
content: localize('ping-protection', 'toggle-succ-disabled', {
time: dateToDiscordTimestamp(result.disabledUntil, 'R')
}),
flags: MessageFlags.Ephemeral
});
}

return interaction.reply({
content: localize('ping-protection', 'toggle-succ-enabled'),
flags: MessageFlags.Ephemeral
});
},
'list': {
'protected': async function (interaction) {
await listHandler(interaction, 'protected');
Expand All @@ -58,6 +100,7 @@ module.exports.subcommands = {
}
};

// Handles list subcommands
// Handles list subcommands
async function listHandler(interaction, type) {
const config = interaction.client.configurations['ping-protection']['configuration'];
Expand All @@ -72,11 +115,23 @@ async function listHandler(interaction, type) {
embed.setTitle(localize('ping-protection', 'list-protected-title'));
embed.setDescription(localize('ping-protection', 'list-protected-desc'));

const usersList = config.protectedUsers.length > 0
? config.protectedUsers.map(id => `<@${id}>`).join('\n')
: localize('ping-protection', 'list-none');
let usersList = localize('ping-protection', 'list-none');
if (Array.isArray(config.protectedUsers) && config.protectedUsers.length > 0) {
const formattedUsers = await Promise.all(config.protectedUsers.map(async (id) => {
const isOff = config.allowProtectionToggle
? await isProtectionToggledOff(interaction.client, id)
: false;

const rolesList = config.protectedRoles.length > 0
if (isOff) {
return `<@${id}> *(${localize('ping-protection', 'list-user-paused')})*`;
}
return `<@${id}>`;
}));

usersList = formattedUsers.join('\n');
}

const rolesList = Array.isArray(config.protectedRoles) && config.protectedRoles.length > 0
? config.protectedRoles.map(id => `<@&${id}>`).join('\n')
: localize('ping-protection', 'list-none');

Expand All @@ -97,15 +152,15 @@ async function listHandler(interaction, type) {
embed.setTitle(localize('ping-protection', 'list-whitelist-title'));
embed.setDescription(localize('ping-protection', 'list-whitelist-desc'));

const rolesList = config.ignoredRoles.length > 0
const rolesList = Array.isArray(config.ignoredRoles) && config.ignoredRoles.length > 0
? config.ignoredRoles.map(id => `<@&${id}>`).join('\n')
: localize('ping-protection', 'list-none');

const channelsList = config.ignoredChannels.length > 0
const channelsList = Array.isArray(config.ignoredChannels) && config.ignoredChannels.length > 0
? config.ignoredChannels.map(id => `<#${id}>`).join('\n')
: localize('ping-protection', 'list-none');

const usersList = config.ignoredUsers.length > 0
const usersList = Array.isArray(config.ignoredUsers) && config.ignoredUsers.length > 0
? config.ignoredUsers.map(id => `<@${id}>`).join('\n')
: localize('ping-protection', 'list-none');

Expand Down Expand Up @@ -140,48 +195,64 @@ module.exports.config = {
usage: '/ping-protection',
type: 'slash',
defaultPermission: false,
options: [
{
type: 'SUB_COMMAND_GROUP',
name: 'user',
description: localize('ping-protection', 'cmd-desc-group-user'),
options: [
{
type: 'SUB_COMMAND',
name: 'history',
description: localize('ping-protection', 'cmd-desc-history'),
options: [{
type: 'USER',
name: 'user',
description: localize('ping-protection', 'cmd-opt-user'),
required: true
}]
},
{
type: 'SUB_COMMAND',
name: 'actions-history',
description: localize('ping-protection', 'cmd-desc-actions'),
options: [{
type: 'USER',
name: 'user',
description: localize('ping-protection', 'cmd-opt-user'),
required: true
}]
},
{
type: 'SUB_COMMAND',
name: 'panel',
description: localize('ping-protection', 'cmd-desc-panel'),
options: [{
type: 'USER',
name: 'user',
description: localize('ping-protection', 'cmd-opt-user'),
required: true
}]
}
]
},
{
options: function (client) {
const array = [];

const storageConfig = client.configurations['ping-protection']['storage'] || {};
const generalConfig = client.configurations['ping-protection']['configuration'] || {};

if (storageConfig.enablePingHistory) {
array.push({
type: 'SUB_COMMAND_GROUP',
name: 'user',
description: localize('ping-protection', 'cmd-desc-group-user'),
options: [
{
type: 'SUB_COMMAND',
name: 'history',
description: localize('ping-protection', 'cmd-desc-history'),
options: [{
type: 'USER',
name: 'user',
description: localize('ping-protection', 'cmd-opt-user'),
required: true
}]
},
{
type: 'SUB_COMMAND',
name: 'actions-history',
description: localize('ping-protection', 'cmd-desc-actions'),
options: [{
type: 'USER',
name: 'user',
description: localize('ping-protection', 'cmd-opt-user'),
required: true
}]
},
{
type: 'SUB_COMMAND',
name: 'panel',
description: localize('ping-protection', 'cmd-desc-panel'),
options: [{
type: 'USER',
name: 'user',
description: localize('ping-protection', 'cmd-opt-user'),
required: true
}]
}
]
});
}

if (generalConfig.allowProtectionToggle) {
array.push({
type: 'SUB_COMMAND',
name: 'toggle',
description: localize('ping-protection', 'cmd-desc-toggle')
});
}

array.push({
type: 'SUB_COMMAND_GROUP',
name: 'list',
description: localize('ping-protection', 'cmd-desc-group-list'),
Expand All @@ -197,6 +268,8 @@ module.exports.config = {
description: localize('ping-protection', 'cmd-desc-list-wl')
}
]
}
]
});

return array;
}
};
Loading
Loading