Фильтр слов удаляет сообщение с картинкой discord.py
Недавно я написал фильтр слов, которые удаляет сообщения, в которых есть слова из массива "banword". Сам код свою задачу выполняет довольно хорошо. Но при двухдневном тесте выявилась проблема: если к сообщению приложить картинку, то бот заблокирует это сообщение. Как исправить? Вот код:
@bot.event
async def on_message(message):
text = message.content
intext = text.split(" ")
words = len(intext)
banwords = ["всякие", "нехорошие", "и", "матные", "слова"]
banwordslist = len(banwords)
checked = 0
wordcheck = 0
banword = 0
ban = 0
while checked != words:
if banword != banwordslist:
bw = banwords[banword]
ww = intext[wordcheck]
if bw.lower() in ww.lower():
ban = ban + 1
banword = banword + 1
if bw.lower() not in ww.lower():
banword = banword + 1
else:
banword = 0
wordcheck = wordcheck + 1
checked = checked + 1
if ban >= 1:
user = message.author.id()
await message.delete()
await message.channel.send("<@{0}> , не лучшее место для мата.".format(user))
Ответы (1 шт):
В коде есть пара моментов, которые стоит исправить:
user = message.author.id(), здесь вы пытаетесь получитьidпользователя, вызывая его атрибут как функцию. Ноid- это не функция, это Attribute, переменная, если проще. Поэтому правильно будет получатьidвот так: (Иначе вы получите ошибку)
user = message.author.id
await message.delete()удаление сообщения лучше обернуть в конструкцию исключения ошибки. Так как, если кто-то напишет боту в личные сообщения, бот не сможет удалить сообщение из-за отсутствия прав и вы получите ошибку.
try:
await message.delete()
except:
pass
- Ну и просто подмечу: Упоминание не обязательно форматировать таким сложным способом
'<@{0}>'.format(message.author.id), можно просто использовать встроенный атрибут объектаuser-mention
await message.channel.send(f'{message.author.mention}, не лучшее место для мата.')
Далее, хотелось бы добавить, что у вас какой-то очень замороченный код :)
Такой фильтр можно написать гораздо проще, и, как мне кажется, он будет работать стабильнее.
@bot.event
async def on_message(message):
if message.author == bot.user: return # если сообщение от бота - игнорируем
banwords = ["всякие", "нехорошие", "и", "матные", "слова"]
for word in banwords:
if word in message.content.lower():
try:
await message.delete()
except:
pass
await message.channel.send(f'{message.author.mention}, не лучшее место для мата')
break
При получении сообщения, если оно не от бота, проверяем в цикле наличие каждого слова в тексте сообщения. Если хоть одно слово попадается, то цикл прерывается (break) и выполняется удаление сообщения с отправкой текста "не лучшее место для мата"
Если вам нужно подсчитать кол-во запрещенных слов в тексте - можно использовать встроенную функцию строки count(). Например, можно подсчитать количество единиц в строке:
text = '1112233133456'
count = text.count('1') # 4
Что же насчет отправки картинок - ни в вашем коде, ни в моем, я не нашел никаких проблем с блокировкой изображений. Даже пробовал называть их словами из списка - ничего не происходит.