This commit is contained in:
Petal Ladenson 2026-01-19 12:29:08 +00:00 committed by GitHub
commit 5fcbd1397f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 182 additions and 29 deletions

View file

@ -106,9 +106,12 @@ public partial class CommandTree
public static Command LogEnable = new Command("serverconfig log blacklist remove", "serverconfig log blacklist remove all|<channel> [channel 2] [channel 3...]", "Enables message logging in certain channels"); public static Command LogEnable = new Command("serverconfig log blacklist remove", "serverconfig log blacklist remove all|<channel> [channel 2] [channel 3...]", "Enables message logging in certain channels");
public static Command LogDisable = new Command("serverconfig log blacklist add", "serverconfig log blacklist add all|<channel> [channel 2] [channel 3...]", "Disables message logging in certain channels"); public static Command LogDisable = new Command("serverconfig log blacklist add", "serverconfig log blacklist add all|<channel> [channel 2] [channel 3...]", "Disables message logging in certain channels");
public static Command LogShow = new Command("serverconfig log blacklist", "serverconfig log blacklist", "Displays the current list of channels where logging is disabled"); public static Command LogShow = new Command("serverconfig log blacklist", "serverconfig log blacklist", "Displays the current list of channels where logging is disabled");
public static Command BlacklistShow = new Command("serverconfig proxy blacklist", "serverconfig proxy blacklist", "Displays the current list of channels where message proxying is disabled"); public static Command ProxyBlacklistShow = new Command("serverconfig proxy blacklist", "serverconfig proxy blacklist", "Displays the current list of channels where message proxying is disabled");
public static Command BlacklistAdd = new Command("serverconfig proxy blacklist add", "serverconfig proxy blacklist add all|<channel> [channel 2] [channel 3...]", "Disables message proxying in certain channels"); public static Command ProxyBlacklistAdd = new Command("serverconfig proxy blacklist add", "serverconfig proxy blacklist add all|<channel> [channel 2] [channel 3...]", "Disables message proxying in certain channels");
public static Command BlacklistRemove = new Command("serverconfig proxy blacklist remove", "serverconfig proxy blacklist remove all|<channel> [channel 2] [channel 3...]", "Enables message proxying in certain channels"); public static Command ProxyBlacklistRemove = new Command("serverconfig proxy blacklist remove", "serverconfig proxy blacklist remove all|<channel> [channel 2] [channel 3...]", "Enables message proxying in certain channels");
public static Command CommandBlacklistShow = new Command("serverconfig command blacklist", "serverconfig command blacklist", "Displays the current list of channels where running text commands is disabled");
public static Command CommandBlacklistAdd = new Command("serverconfig command blacklist add", "serverconfig command blacklist add all|<channel> [channel 2] [channel 3...]", "Disables running text commands in certain channels");
public static Command CommandBlacklistRemove = new Command("serverconfig command blacklist remove", "serverconfig command blacklist remove all|<channel> [channel 2] [channel 3...]", "Enables running text commands in certain channels");
public static Command ServerConfigLogClean = new Command("serverconfig log cleanup", "serverconfig log cleanup [on|off]", "Toggles whether to clean up other bots' log channels"); public static Command ServerConfigLogClean = new Command("serverconfig log cleanup", "serverconfig log cleanup [on|off]", "Toggles whether to clean up other bots' log channels");
public static Command ServerConfigInvalidCommandResponse = new Command("serverconfig invalid command error", "serverconfig invalid command error [on|off]", "Sets whether to show an error message when an unknown command is sent"); public static Command ServerConfigInvalidCommandResponse = new Command("serverconfig invalid command error", "serverconfig invalid command error [on|off]", "Sets whether to show an error message when an unknown command is sent");
public static Command ServerConfigRequireSystemTag = new Command("serverconfig require tag", "serverconfig require tag [on|off]", "Sets whether server users are required to have a system tag on proxied messages"); public static Command ServerConfigRequireSystemTag = new Command("serverconfig require tag", "serverconfig require tag [on|off]", "Sets whether server users are required to have a system tag on proxied messages");
@ -160,7 +163,8 @@ public partial class CommandTree
ServerConfigLogClean, ServerConfigInvalidCommandResponse, ServerConfigRequireSystemTag, ServerConfigLogClean, ServerConfigInvalidCommandResponse, ServerConfigRequireSystemTag,
ServerConfigSuppressNotifications, ServerConfigSuppressNotifications,
LogChannel, LogChannelClear, LogShow, LogDisable, LogEnable, LogChannel, LogChannelClear, LogShow, LogDisable, LogEnable,
BlacklistShow, BlacklistAdd, BlacklistRemove ProxyBlacklistShow, ProxyBlacklistAdd, ProxyBlacklistRemove,
CommandBlacklistShow, CommandBlacklistAdd, CommandBlacklistRemove
}; };
public static Command[] AutoproxyCommands = public static Command[] AutoproxyCommands =
@ -170,5 +174,5 @@ public partial class CommandTree
public static Command[] LogCommands = { LogChannel, LogChannelClear, LogEnable, LogDisable, LogShow }; public static Command[] LogCommands = { LogChannel, LogChannelClear, LogEnable, LogDisable, LogShow };
public static Command[] BlacklistCommands = { BlacklistAdd, BlacklistRemove, BlacklistShow }; public static Command[] ProxyBlacklistCommands = { ProxyBlacklistAdd, ProxyBlacklistRemove, ProxyBlacklistShow };
} }

View file

@ -69,11 +69,11 @@ public partial class CommandTree
return ctx.Execute<ServerConfig>(ServerConfigLogClean, m => m.SetLogCleanup(ctx), true); return ctx.Execute<ServerConfig>(ServerConfigLogClean, m => m.SetLogCleanup(ctx), true);
if (ctx.Match("blacklist", "bl")) if (ctx.Match("blacklist", "bl"))
if (ctx.Match("enable", "on", "add", "deny")) if (ctx.Match("enable", "on", "add", "deny"))
return ctx.Execute<ServerConfig>(BlacklistAdd, m => m.SetProxyBlacklisted(ctx, true), true); return ctx.Execute<ServerConfig>(ProxyBlacklistAdd, m => m.SetProxyBlacklisted(ctx, true), true);
else if (ctx.Match("disable", "off", "remove", "allow")) else if (ctx.Match("disable", "off", "remove", "allow"))
return ctx.Execute<ServerConfig>(BlacklistRemove, m => m.SetProxyBlacklisted(ctx, false), true); return ctx.Execute<ServerConfig>(ProxyBlacklistRemove, m => m.SetProxyBlacklisted(ctx, false), true);
else if (ctx.Match("list", "show")) else if (ctx.Match("list", "show"))
return ctx.Execute<ServerConfig>(BlacklistShow, m => m.ShowProxyBlacklisted(ctx), true); return ctx.Execute<ServerConfig>(ProxyBlacklistShow, m => m.ShowProxyBlacklisted(ctx), true);
else else
return ctx.Reply($"{Emojis.Warn} Blacklist commands have moved to `{ctx.DefaultPrefix}serverconfig`."); return ctx.Reply($"{Emojis.Warn} Blacklist commands have moved to `{ctx.DefaultPrefix}serverconfig`.");
if (ctx.Match("proxy")) if (ctx.Match("proxy"))
@ -530,7 +530,7 @@ public partial class CommandTree
break; break;
case "blacklist": case "blacklist":
case "bl": case "bl":
await PrintCommandList(ctx, "channel blacklisting", BlacklistCommands); await PrintCommandList(ctx, "channel proxy blacklisting", ProxyBlacklistCommands);
break; break;
case "config": case "config":
case "cfg": case "cfg":
@ -642,6 +642,15 @@ public partial class CommandTree
else else
return ctx.Execute<ServerConfig>(null, m => m.ShowProxyBlacklisted(ctx)); return ctx.Execute<ServerConfig>(null, m => m.ShowProxyBlacklisted(ctx));
} }
if (ctx.MatchMultiple(new[] { "command" }, new[] { "blacklist" }))
{
if (ctx.Match("enable", "on", "add", "deny"))
return ctx.Execute<ServerConfig>(null, m => m.SetCommandBlacklisted(ctx, true));
else if (ctx.Match("disable", "off", "remove", "allow"))
return ctx.Execute<ServerConfig>(null, m => m.SetCommandBlacklisted(ctx, false));
else
return ctx.Execute<ServerConfig>(null, m => m.ShowCommandBlacklisted(ctx));
}
// todo: maybe add the list of configuration keys here? // todo: maybe add the list of configuration keys here?
return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `{ctx.DefaultPrefix}commands serverconfig` for the list of possible config settings."); return ctx.Reply($"{Emojis.Error} Could not find a setting with that name. Please see `{ctx.DefaultPrefix}commands serverconfig` for the list of possible config settings.");

View file

@ -73,10 +73,17 @@ public class ServerConfig
items.Add(new( items.Add(new(
"proxy blacklist", "proxy blacklist",
"Channels where message proxying is disabled", "Channels where message proxying is disabled",
ChannelListMessage(ctx.GuildConfig!.Blacklist.Length, "proxy blacklist"), ChannelListMessage(ctx.GuildConfig!.ProxyBlacklist.Length, "proxy blacklist"),
ChannelListMessage(0, "proxy blacklist") ChannelListMessage(0, "proxy blacklist")
)); ));
items.Add(new(
"command blacklist",
"Channels where running text commands is disabled",
ChannelListMessage(ctx.GuildConfig!.CommandBlacklist.Length, "command blacklist"),
ChannelListMessage(0, "command blacklist")
));
await ctx.Paginate<PaginatedConfigItem>( await ctx.Paginate<PaginatedConfigItem>(
items.ToAsyncEnumerable(), items.ToAsyncEnumerable(),
items.Count, items.Count,
@ -197,7 +204,7 @@ public class ServerConfig
var blacklist = await ctx.Repository.GetGuild(ctx.Guild.Id); var blacklist = await ctx.Repository.GetGuild(ctx.Guild.Id);
// Resolve all channels from the cache and order by position // Resolve all channels from the cache and order by position
var channels = (await Task.WhenAll(blacklist.Blacklist var channels = (await Task.WhenAll(blacklist.ProxyBlacklist
.Select(id => _cache.TryGetChannel(ctx.Guild.Id, id)))) .Select(id => _cache.TryGetChannel(ctx.Guild.Id, id))))
.Where(c => c != null) .Where(c => c != null)
.OrderBy(c => c.Position) .OrderBy(c => c.Position)
@ -210,7 +217,57 @@ public class ServerConfig
} }
await ctx.Paginate(channels.ToAsyncEnumerable(), channels.Count, 25, await ctx.Paginate(channels.ToAsyncEnumerable(), channels.Count, 25,
$"Blacklisted channels for {ctx.Guild.Name}", $"Blacklisted channels for proxying in {ctx.Guild.Name}",
null,
async (eb, l) =>
{
async Task<string> CategoryName(ulong? id) =>
id != null ? (await _cache.GetChannel(ctx.Guild.Id, id.Value)).Name : "(no category)";
ulong? lastCategory = null;
var fieldValue = new StringBuilder();
foreach (var channel in l)
{
if (lastCategory != channel!.ParentId && fieldValue.Length > 0)
{
eb.Field(new Embed.Field(await CategoryName(lastCategory), fieldValue.ToString()));
fieldValue.Clear();
}
else
{
fieldValue.Append("\n");
}
fieldValue.Append(channel.Mention());
lastCategory = channel.ParentId;
}
eb.Field(new Embed.Field(await CategoryName(lastCategory), fieldValue.ToString()));
});
}
public async Task ShowCommandBlacklisted(Context ctx)
{
await ctx.CheckGuildContext().CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server");
var blacklist = await ctx.Repository.GetGuild(ctx.Guild.Id);
// Resolve all channels from the cache and order by position
var channels = (await Task.WhenAll(blacklist.CommandBlacklist
.Select(id => _cache.TryGetChannel(ctx.Guild.Id, id))))
.Where(c => c != null)
.OrderBy(c => c.Position)
.ToList();
if (channels.Count == 0)
{
await ctx.Reply("This server has no channels where running text commands is disabled.");
return;
}
await ctx.Paginate(channels.ToAsyncEnumerable(), channels.Count, 25,
$"Blacklisted channels for running text commands in {ctx.Guild.Name}",
null, null,
async (eb, l) => async (eb, l) =>
{ {
@ -314,16 +371,49 @@ public class ServerConfig
var guild = await ctx.Repository.GetGuild(ctx.Guild.Id); var guild = await ctx.Repository.GetGuild(ctx.Guild.Id);
var blacklist = guild.Blacklist.ToHashSet(); var blacklist = guild.ProxyBlacklist.ToHashSet();
if (shouldAdd) if (shouldAdd)
blacklist.UnionWith(affectedChannels.Select(c => c.Id)); blacklist.UnionWith(affectedChannels.Select(c => c.Id));
else else
blacklist.ExceptWith(affectedChannels.Select(c => c.Id)); blacklist.ExceptWith(affectedChannels.Select(c => c.Id));
await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { Blacklist = blacklist.ToArray() }); await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { ProxyBlacklist = blacklist.ToArray() });
await ctx.Reply( await ctx.Reply(
$"{Emojis.Success} Channels {(shouldAdd ? "added to" : "removed from")} the proxy blacklist."); $"{Emojis.Success} Channel(s) {(shouldAdd ? "added to" : "removed from")} the proxy blacklist.");
}
public async Task SetCommandBlacklisted(Context ctx, bool shouldAdd)
{
await ctx.CheckGuildContext().CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server");
var affectedChannels = new List<Channel>();
if (ctx.Match("all"))
affectedChannels = (await _cache.GetGuildChannels(ctx.Guild.Id))
// All the channel types you can proxy in
.Where(x => DiscordUtils.IsValidGuildChannel(x)).ToList();
else if (!ctx.HasNext()) throw new PKSyntaxError("You must pass one or more #channels.");
else
while (ctx.HasNext())
{
var channelString = ctx.PeekArgument();
var channel = await ctx.MatchChannel();
if (channel == null || channel.GuildId != ctx.Guild.Id) throw Errors.ChannelNotFound(channelString);
affectedChannels.Add(channel);
}
var guild = await ctx.Repository.GetGuild(ctx.Guild.Id);
var blacklist = guild.CommandBlacklist.ToHashSet();
if (shouldAdd)
blacklist.UnionWith(affectedChannels.Select(c => c.Id));
else
blacklist.ExceptWith(affectedChannels.Select(c => c.Id));
await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { CommandBlacklist = blacklist.ToArray() });
await ctx.Reply(
$"{Emojis.Success} Channel(s) {(shouldAdd ? "added to" : "removed from")} the command blacklist.");
} }
public async Task SetLogBlacklisted(Context ctx, bool shouldAdd) public async Task SetLogBlacklisted(Context ctx, bool shouldAdd)

View file

@ -140,7 +140,22 @@ public class MessageCreated: IEventHandler<MessageCreateEvent>
var config = system != null ? await _repo.GetSystemConfig(system.Id) : null; var config = system != null ? await _repo.GetSystemConfig(system.Id) : null;
var guildConfig = guild != null ? await _repo.GetGuild(guild.Id) : null; var guildConfig = guild != null ? await _repo.GetGuild(guild.Id) : null;
await _tree.ExecuteCommand(new Context(_services, shardId, guild, channel, evt, cmdStart, system, config, guildConfig, _config.Prefixes ?? BotConfig.DefaultPrefixes)); var ctx = new Context(_services, shardId, guild, channel, evt, cmdStart, system, config, guildConfig, _config.Prefixes ?? BotConfig.DefaultPrefixes);
// If we're in a guild we need to check if this channel is on the command blacklist
if (guild is not null)
{
// If we're in a thread we want to check the root channel and the thread
var rootChannel = channel.IsThread() ? await _rest.GetChannelOrNull(channel.ParentId!.Value) : channel;
var msgCtx = await _repo.GetMessageContext(evt.Author.Id, guild.Id, rootChannel.Id, channel.Id != rootChannel.Id ? channel.Id : default);
// If the channel is in the command blacklist, then check if author has Manage Server
// If they do, we let the command run regardless
// If they don't a PK Error gets thrown here and caught in the catch
if (msgCtx.InCommandBlacklist)
await ctx.CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server"); ;
}
await _tree.ExecuteCommand(ctx);
} }
catch (PKError) catch (PKError)
{ {

View file

@ -184,7 +184,7 @@ public class ProxyService
throw new ProxyChecksFailedException("This message is the initial message in a forum post, which PluralKit is unable to proxy correctly."); throw new ProxyChecksFailedException("This message is the initial message in a forum post, which PluralKit is unable to proxy correctly.");
// Make sure proxying is enabled here // Make sure proxying is enabled here
if (ctx.InBlacklist) if (ctx.InProxyBlacklist)
throw new ProxyChecksFailedException( throw new ProxyChecksFailedException(
"Proxying was disabled in this channel by a server administrator (via the proxy blacklist)."); "Proxying was disabled in this channel by a server administrator (via the proxy blacklist).");
@ -290,7 +290,7 @@ public class ProxyService
await _repo.GetMessageContext(msg.Sender, msg.Guild!.Value, rootChannel.Id, msg.Channel); await _repo.GetMessageContext(msg.Sender, msg.Guild!.Value, rootChannel.Id, msg.Channel);
// Make sure proxying is enabled here // Make sure proxying is enabled here
if (ctx.InBlacklist) if (ctx.InProxyBlacklist)
throw new ProxyChecksFailedException( throw new ProxyChecksFailedException(
"Proxying was disabled in this channel by a server administrator (via the proxy blacklist)."); "Proxying was disabled in this channel by a server administrator (via the proxy blacklist).");

View file

@ -32,7 +32,8 @@ public class MessageContext
public Instant? LastSwitchTimestamp { get; } public Instant? LastSwitchTimestamp { get; }
public ulong? LogChannel { get; } public ulong? LogChannel { get; }
public bool InBlacklist { get; } public bool InProxyBlacklist { get; }
public bool InCommandBlacklist { get; }
public bool InLogBlacklist { get; } public bool InLogBlacklist { get; }
public bool LogCleanupEnabled { get; } public bool LogCleanupEnabled { get; }
public bool RequireSystemTag { get; } public bool RequireSystemTag { get; }

View file

@ -9,7 +9,7 @@ namespace PluralKit.Core;
internal class DatabaseMigrator internal class DatabaseMigrator
{ {
private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files private const string RootPath = "PluralKit.Core.Database"; // "resource path" root for SQL files
private const int TargetSchemaVersion = 52; private const int TargetSchemaVersion = 55;
private readonly ILogger _logger; private readonly ILogger _logger;
public DatabaseMigrator(ILogger logger) public DatabaseMigrator(ILogger logger)

View file

@ -5,7 +5,8 @@ public class GuildConfig
public ulong Id { get; } public ulong Id { get; }
public ulong? LogChannel { get; } public ulong? LogChannel { get; }
public ulong[] LogBlacklist { get; } public ulong[] LogBlacklist { get; }
public ulong[] Blacklist { get; } public ulong[] ProxyBlacklist { get; }
public ulong[] CommandBlacklist { get; }
public bool LogCleanupEnabled { get; } public bool LogCleanupEnabled { get; }
public bool InvalidCommandResponseEnabled { get; } public bool InvalidCommandResponseEnabled { get; }
public bool RequireSystemTag { get; } public bool RequireSystemTag { get; }

View file

@ -6,7 +6,8 @@ public class GuildPatch: PatchObject
{ {
public Partial<ulong?> LogChannel { get; set; } public Partial<ulong?> LogChannel { get; set; }
public Partial<ulong[]> LogBlacklist { get; set; } public Partial<ulong[]> LogBlacklist { get; set; }
public Partial<ulong[]> Blacklist { get; set; } public Partial<ulong[]> ProxyBlacklist { get; set; }
public Partial<ulong[]> CommandBlacklist { get; set; }
public Partial<bool> LogCleanupEnabled { get; set; } public Partial<bool> LogCleanupEnabled { get; set; }
public Partial<bool> InvalidCommandResponseEnabled { get; set; } public Partial<bool> InvalidCommandResponseEnabled { get; set; }
public Partial<bool> RequireSystemTag { get; set; } public Partial<bool> RequireSystemTag { get; set; }
@ -15,7 +16,8 @@ public class GuildPatch: PatchObject
public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper public override Query Apply(Query q) => q.ApplyPatch(wrapper => wrapper
.With("log_channel", LogChannel) .With("log_channel", LogChannel)
.With("log_blacklist", LogBlacklist) .With("log_blacklist", LogBlacklist)
.With("blacklist", Blacklist) .With("proxy_blacklist", ProxyBlacklist)
.With("command_blacklist", CommandBlacklist)
.With("log_cleanup_enabled", LogCleanupEnabled) .With("log_cleanup_enabled", LogCleanupEnabled)
.With("invalid_command_response_enabled", InvalidCommandResponseEnabled) .With("invalid_command_response_enabled", InvalidCommandResponseEnabled)
.With("require_system_tag", RequireSystemTag) .With("require_system_tag", RequireSystemTag)

View file

@ -23,7 +23,8 @@ create function message_context(account_id bigint, guild_id bigint, channel_id b
last_switch_timestamp timestamp, last_switch_timestamp timestamp,
log_channel bigint, log_channel bigint,
in_blacklist bool, in_proxy_blacklist bool,
in_command_blacklist bool,
in_log_blacklist bool, in_log_blacklist bool,
log_cleanup_enabled bool, log_cleanup_enabled bool,
require_system_tag bool, require_system_tag bool,
@ -62,8 +63,10 @@ as $$
-- servers table -- servers table
servers.log_channel as log_channel, servers.log_channel as log_channel,
((channel_id = any (servers.blacklist)) ((channel_id = any (servers.proxy_blacklist))
or (thread_id = any (servers.blacklist))) as in_blacklist, or (thread_id = any (servers.proxy_blacklist))) as in_proxy_blacklist,
((channel_id = any (servers.command_blacklist))
or (thread_id = any (servers.command_blacklist))) as in_command_blacklist,
((channel_id = any (servers.log_blacklist)) ((channel_id = any (servers.log_blacklist))
or (thread_id = any (servers.log_blacklist))) as in_log_blacklist, or (thread_id = any (servers.log_blacklist))) as in_log_blacklist,
coalesce(servers.log_cleanup_enabled, false) as log_cleanup_enabled, coalesce(servers.log_cleanup_enabled, false) as log_cleanup_enabled,

View file

@ -0,0 +1,6 @@
-- database version 54
-- rename blacklist column to proxy blacklist
alter table servers rename column blacklist to proxy_blacklist;
update info set schema_version = 54;

View file

@ -0,0 +1,6 @@
-- database version 55
-- add command blacklist option for servers
alter table servers add column command_blacklist bigint[] not null default array[]::bigint[];
update info set schema_version = 55;

View file

@ -167,6 +167,9 @@ You can have a space after `pk;`, e.g. `pk;system` and `pk; system` will do the
- `pk;serverconfig proxy blacklist` - Displays the current proxy blacklist - `pk;serverconfig proxy blacklist` - Displays the current proxy blacklist
- `pk;serverconfig proxy blacklist add all|<channel> [channel 2] [channel 3...]` - Adds certain channels to the proxy blacklist - `pk;serverconfig proxy blacklist add all|<channel> [channel 2] [channel 3...]` - Adds certain channels to the proxy blacklist
- `pk;serverconfig proxy blacklist remove all|<channel> [channel 2] [channel 3...]` - Removes certain channels from the proxy blacklist - `pk;serverconfig proxy blacklist remove all|<channel> [channel 2] [channel 3...]` - Removes certain channels from the proxy blacklist
- `pk;serverconfig command blacklist` - Displays the current command blacklist
- `pk;serverconfig command blacklist add all|<channel> [channel 2] [channel 3...]` - Adds certain channels to the command blacklist
- `pk;serverconfig command blacklist remove all|<channel> [channel 2] [channel 3...]` - Removes certain channels from the command blacklist
## Utility ## Utility
- `pk;message <message id|message link|reply>` - Looks up information about a proxied message by its message ID or link. - `pk;message <message id|message link|reply>` - Looks up information about a proxied message by its message ID or link.

View file

@ -1,4 +1,7 @@
# Disabling proxying in a channel # Disabling bot functionality
You can use the blacklist commands to disable proxying or text commands in some channels of your server. [You can also disable PluralKit by taking away its permissions.](/staff/permissions)
## Disabling proxying in a channel
It's possible to block a channel from being used for proxying. To do so, use the `pk;serverconfig proxy blacklist` command. For example: It's possible to block a channel from being used for proxying. To do so, use the `pk;serverconfig proxy blacklist` command. For example:
pk;serverconfig proxy blacklist add #admin-channel #mod-channel #welcome pk;serverconfig proxy blacklist add #admin-channel #mod-channel #welcome
@ -7,3 +10,13 @@ It's possible to block a channel from being used for proxying. To do so, use the
pk;serverconfig proxy blacklist remove all pk;serverconfig proxy blacklist remove all
This requires you to have the *Manage Server* permission on the server. This requires you to have the *Manage Server* permission on the server.
## Disabling commands in a channel
It's possible to block a channel from being used for text commands. To do so, use the `pk;serverconfig command blacklist` command. For example:
pk;serverconfig command blacklist add #admin-channel #mod-channel #welcome
pk;serverconfig command blacklist add all
pk;serverconfig command blacklist remove #general-two
pk;serverconfig command blacklist remove all
This requires you to have the *Manage Server* permission on the server. If you have the *Manage Server* permission on the server you **will not be affected by the command blacklist** and will always be able to run commands.