Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for silently filtered words #42

Merged
merged 7 commits into from
Jun 5, 2024
8 changes: 5 additions & 3 deletions cogs/commands/misc/canister.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from utils import GIRContext, canister_search_package, cfg, transform_context
from utils.fetchers import canister_fetch_repos
from utils.framework import gatekeeper, whisper_in_general, find_triggered_filters, find_triggered_raid_phrases
from utils.framework.filter import has_only_silent_filtered_words
from utils.views import TweakDropdown, default_repos, repo_autocomplete


Expand All @@ -22,7 +23,6 @@ async def on_message(self, message):
author = message.guild.get_member(message.author.id)
if author is None:
return

if not gatekeeper.has(message.guild, author, 5) and message.channel.id == cfg.channels.general:
return

Expand All @@ -31,8 +31,10 @@ async def on_message(self, message):
if not pattern.match(message.content):
return

if await find_triggered_filters(message.content, message.author) or await find_triggered_raid_phrases(message.content, message.author):
return
if filter_words := await find_triggered_filters(message.content, message.author) or await find_triggered_raid_phrases(message.content, message.author):
# if any of the triggered filtered words are not silently filtered, don't show results
if not has_only_silent_filtered_words(filter_words):
return

matches = pattern.findall(message.content)
if not matches:
Expand Down
6 changes: 4 additions & 2 deletions cogs/commands/misc/memes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
find_triggered_filters,
find_triggered_raid_phrases, gatekeeper,
memed_and_up, mempro_and_up, mod_and_up, whisper)
from utils.framework.filter import has_only_silent_filtered_words
from utils.views import GenericDescriptionModal, Menu, memes_autocomplete


Expand Down Expand Up @@ -463,8 +464,9 @@ async def aitext(self, ctx: GIRContext, prompt: str):
data = await resp.json()
text = data.get("choices")[0].get("text")
text = discord.utils.escape_markdown(text)
if await find_triggered_filters(text, ctx.author) or await find_triggered_raid_phrases(text, ctx.author):
text = "A filter was triggered by this response. Please try a different prompt."
if filter_words := await find_triggered_filters(text, ctx.author) or await find_triggered_raid_phrases(text, ctx.author):
if not has_only_silent_filtered_words(filter_words):
text = "A filter was triggered by this response. Please try a different prompt."

embed = discord.Embed(color=discord.Color.random())
prompt_formatted = discord.utils.escape_markdown(prompt)
Expand Down
27 changes: 27 additions & 0 deletions cogs/commands/mod/filter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from typing import List
import discord
from discord import app_commands
from data.model import FilterWord
Expand Down Expand Up @@ -30,6 +31,12 @@ def format_filter_page(_, entries, current_page, all_pages):
embed = discord.Embed(
title=f'Filtered words', color=discord.Color.blurple())
for word in entries:
if word.silent_filter:
embed.add_field(
name=word.word, value=f"🤫 silent filtered"
)
continue

notify_flag = ""
piracy_flag = ""
flags_check = ""
Expand Down Expand Up @@ -107,6 +114,26 @@ async def _list(self, ctx: GIRContext):
menu = Menu(ctx, filters, per_page=12,
page_formatter=format_filter_page, whisper=False)
await menu.start()

@mod_and_up()
@app_commands.guilds(cfg.guild_id)
@app_commands.command(description="Silently filter a word (ping mods without removing message)")
@app_commands.describe(word="The word to mark as silently filtered")
@app_commands.autocomplete(word=filterwords_autocomplete)
@transform_context
async def silent_filter(self, ctx: GIRContext, word: str):
word = word.lower()

words: List[FilterWord] = await guild_service.get_filtered_words()
words = list(filter(lambda w: w.word.lower() == word.lower(), words))

if len(words) > 0:
words[0].silent_filter = not words[0].silent_filter
await guild_service.update_filtered_word(words[0])

await ctx.send_success("Marked as a silently filtered word!" if words[0].silent_filter else "Removed as a silently filtered word!")
else:
await ctx.send_warning("You must filter that word before it can be marked as silently filtered.", delete_after=5)

@mod_and_up()
@app_commands.guilds(cfg.guild_id)
Expand Down
3 changes: 2 additions & 1 deletion cogs/monitors/misc/songs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from utils import cfg
from utils.framework import find_triggered_filters, gatekeeper
from utils.framework.filter import has_only_silent_filtered_words
from utils.logging import logger
from datetime import timezone

Expand Down Expand Up @@ -111,7 +112,7 @@ async def generate_view(self, message: discord.Message, link: str):
triggered_words = await find_triggered_filters(
title, message.author)

if triggered_words:
if triggered_words and not has_only_silent_filtered_words(triggered_words):
title = "<:fr:959135064657109012>"

view = discord.ui.View()
Expand Down
15 changes: 12 additions & 3 deletions cogs/monitors/mod/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from discord.ext import commands
from utils import cfg, logger, scam_cache
from utils.framework import gatekeeper, find_triggered_filters
from utils.framework.filter import has_only_silent_filtered_words
from utils.mod import mute
from utils.views import manual_report, report

Expand Down Expand Up @@ -102,6 +103,9 @@ async def nick_filter(self, member):
if not triggered_words:
return

if has_only_silent_filtered_words(triggered_words):
return

await member.edit(nick="change name pls")
embed = discord.Embed(title="Nickname changed",
color=discord.Color.orange())
Expand All @@ -117,21 +121,26 @@ async def bad_word_filter(self, message) -> bool:
if not triggered_words:
return

dev_role = message.guild.get_role(cfg.roles.developer)

triggered = False
for word in triggered_words:
if word.piracy:
# ignore if it's a dev saying piracy in #development
if message.channel.id == cfg.roles.developer in message.author.roles:
continue

if word.notify:
if word.silent_filter:
# don't delete the word if it's silently filtered,
# just notify the mods
await report(self.bot, message, word.word)
return
elif word.notify:
await self.delete(message)
await self.ratelimit(message)
await self.do_filter_notify(message, word)

if not word.piracy:
await report(self.bot, message, word.word)

return

triggered = True
Expand Down
33 changes: 33 additions & 0 deletions config.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"channels": {
"applenews": 123,
"booster_emoji": 123,
"emoji_logs": 123,
"private_logs": 123,
"public_logs": 123,
"bot_commands": 123,
"jailbreak": 123,
"general": 123,
"development": 123,
"genius_bar": 123,
"reports": 123,
"rules": 123,
"common_issues": 123,
"sub_news": 123
},
"roles": {
"administrator": 123,
"moderator": 123,
"sub_mod": 123,
"genius": 123,
"developer": 123,
"birthday": 123,
"member_ultra": 123,
"member_one": 123,
"member_edition": 123,
"member_pro": 123,
"member_plus": 123,
"sub_news": 123,
"aaron_role": 123
}
}
2 changes: 1 addition & 1 deletion data/model/filterword.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import mongoengine

class FilterWord(mongoengine.EmbeddedDocument):
# _id = mongoengine.ObjectIdField(required=True, default=mongoengine.ObjectId., unique=True, primary_key=True)
notify = mongoengine.BooleanField(required=True)
silent_filter = mongoengine.BooleanField(default=False)
bypass = mongoengine.IntField(required=True)
word = mongoengine.StringField(required=True)
false_positive = mongoengine.BooleanField(default=False)
Expand Down
7 changes: 7 additions & 0 deletions utils/framework/filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ async def find_triggered_filters(input, member: discord.Member) -> List[FilterWo
words_found.append(word)
return words_found

def has_only_silent_filtered_words(triggered_filter_words: List[FilterWord]):
"""
We don't want to trigger the filter if the words are silently filtered
return True if all triggered filtered words are silently filtered
"""
return all(filter_word.silent_filter for filter_word in triggered_filter_words)


async def find_triggered_raid_phrases(input, member):
symbols = (u"абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ",
Expand Down