sanitizeContent function
Future<String>
sanitizeContent(
- String content, {
- required PartialTextChannel channel,
- SanitizerAction action = SanitizerAction.sanitize,
- Map<
SanitizerTarget, SanitizerAction> ? actionOverrides,
Find SanitizerTargets in content
and sanitize them according to action
.
channel
must be provided as the channel to which the sanitized content will be sent. It is used to resolve user, role and channel IDs to their names.
actionOverrides
can be provided to change the action taken for each SanitizerTarget type.
Implementation
Future<String> sanitizeContent(
String content, {
required PartialTextChannel channel,
SanitizerAction action = SanitizerAction.sanitize,
Map<SanitizerTarget, SanitizerAction>? actionOverrides,
}) async {
final client = channel.manager.client;
final guild = await switch (await channel.get()) {
GuildChannel(:final guild) => guild.get(),
_ => null,
};
RegExp patternForTarget(SanitizerTarget target) => switch (target) {
SanitizerTarget.users => userMentionRegex,
SanitizerTarget.roles => roleMentionRegex,
SanitizerTarget.everyone => everyoneMentionRegex,
SanitizerTarget.channels => channelMentionRegex,
SanitizerTarget.emojis => guildEmojiRegex,
SanitizerTarget.commands => commandMentionRegex,
};
Future<String> name(RegExpMatch match, SanitizerTarget target) async => switch (target) {
SanitizerTarget.everyone => match.group(1)!,
SanitizerTarget.channels => switch (await client.channels[Snowflake.parse(match.group(1)!)].getOrNull()) {
GuildChannel(:final name) || GroupDmChannel(:final name) => name,
DmChannel(:final recipient) => recipient.globalName ?? recipient.username,
_ => 'Unknown Channel',
},
SanitizerTarget.roles => switch (await guild?.roles[Snowflake.parse(match.group(1)!)].getOrNull()) {
Role(:final name) => name,
_ => 'Unknown Role',
},
SanitizerTarget.users => switch (await guild?.members[Snowflake.parse(match.group(1)!)].getOrNull()) {
Member(:final nick?) => nick,
Member(:final user?) => user.globalName ?? user.username,
_ => switch (await client.users[Snowflake.parse(match.group(1)!)].getOrNull()) {
User(:final username, :final globalName) => globalName ?? username,
_ => 'Unknown User',
},
},
SanitizerTarget.emojis => match.group(2)!,
SanitizerTarget.commands => match.namedGroup('commandName')!,
};
String prefix(SanitizerTarget target) => switch (target) {
SanitizerTarget.users || SanitizerTarget.roles => '@',
SanitizerTarget.everyone => '@$_whitespaceCharacter',
SanitizerTarget.channels => '#',
SanitizerTarget.emojis => ':',
SanitizerTarget.commands => '/',
};
String suffix(SanitizerTarget target) => switch (target) {
SanitizerTarget.emojis => ':',
_ => '',
};
Future<String> resolve(RegExpMatch match, SanitizerTarget target, SanitizerAction action) async => switch (action) {
SanitizerAction.ignore => match.group(0)!,
SanitizerAction.remove => '',
SanitizerAction.nameNoPrefix => await name(match, target),
SanitizerAction.name => '${prefix(target)}${await name(match, target)}${suffix(target)}',
SanitizerAction.sanitize => switch (target) {
SanitizerTarget.users => '<@$_whitespaceCharacter${match.group(1)!}>',
SanitizerTarget.roles => '<@&$_whitespaceCharacter${match.group(1)!}>',
SanitizerTarget.everyone => '@$_whitespaceCharacter${match.group(1)!}',
SanitizerTarget.channels => '<#$_whitespaceCharacter${match.group(1)!}>',
SanitizerTarget.emojis => '<$_whitespaceCharacter${match.group(1) ?? ''}\\:${match.group(2)}\\:${match.group(3)}>',
SanitizerTarget.commands => '</$_whitespaceCharacter${match.namedGroup('commandName')}:${match.group(2)}>',
},
};
String result = content;
for (final target in SanitizerTarget.values) {
final targetAction = actionOverrides?[target] ?? action;
final pattern = patternForTarget(target);
int shift = 0;
for (final match in pattern.allMatches(result)) {
final sanitized = await resolve(match, target, targetAction);
result = result.replaceRange(match.start - shift, match.end - shift, sanitized);
shift += (match.end - match.start) - sanitized.length;
}
}
return result;
}