Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
telegram_bot_antispammer
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
telegram_bot_antispammer
Commits
5e7449d1
Commit
5e7449d1
authored
Mar 20, 2025
by
Иванова Мария Кирилловна
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update bot.py
parent
fc202ccf
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
32 additions
and
27 deletions
+32
-27
bot.py
bot.py
+32
-27
No files found.
bot.py
View file @
5e7449d1
...
@@ -31,12 +31,12 @@ SPAM_KEYWORDS = [
...
@@ -31,12 +31,12 @@ SPAM_KEYWORDS = [
"похудеть"
,
"без диет"
,
"без физическая нагрузка"
,
"здоровье навсегда"
,
"природное лекарство"
,
"безопасное лечение"
,
"детокс"
,
"похудеть"
,
"без диет"
,
"без физическая нагрузка"
,
"здоровье навсегда"
,
"природное лекарство"
,
"безопасное лечение"
,
"детокс"
,
# Коммерческий спам
# Коммерческий спам
"скидка"
,
"акция"
,
"мы снова"
,
"спрос"
,
"бонус"
,
"витрина"
,
"бесплатно"
,
"платить"
,
"монетизация"
,
"купить"
,
"покупать"
,
"продать"
,
"продажа"
,
"дешево"
,
"оплата"
,
"скидка"
,
"акция"
,
"мы снова"
,
"спрос"
,
"бонус"
,
"витрина"
,
"бесплатно"
,
"платить"
,
"монетизация"
,
"купить"
,
"покупать"
,
"продать"
,
"продажа"
,
"дешево"
,
"доставка"
,
"магазин"
,
"следить за новости"
,
"реклама"
,
"распродажа"
,
"экономия"
,
"дешевле"
,
"недорого"
,
"доставка"
,
"магазин"
,
"следить за новости"
,
"реклама"
,
"распродажа"
,
"экономия"
,
"дешевле"
,
"недорого"
,
"спецпредложение"
,
"эксклюзивный предложение"
,
"мой тг канал"
,
"уникальное предложение"
,
"только сегодня"
,
"лютая жиза"
,
"мерч"
,
"продукция"
,
"коллекция"
,
"спецпредложение"
,
"эксклюзивный предложение"
,
"мой тг канал"
,
"уникальное предложение"
,
"только сегодня"
,
"лютая жиза"
,
"мерч"
,
"продукция"
,
"коллекция"
,
# Работа
# Работа
"удалённая работа"
,
"человек команда"
,
"удаленный деятельность"
,
"
дистанционный деятельность"
,
"третуется человек"
,
"искать человек"
,
"достойный доход"
,
"удалённая работа"
,
"бакс"
,
"доллар"
,
"нужен человек"
,
"нужен помощник"
,
"вакансии"
,
"удаленка"
,
"условия труда"
,
"писать лс
"
,
"писать в лс"
,
"личное сообщение"
,
"лс"
,
"партнер"
,
"сотрудничество"
,
"прибыль"
,
"бабки"
,
"пасивный заработок"
,
"без вложений"
,
"подробности лс"
,
"удалённая работа"
,
"человек команда"
,
"удаленный деятельность"
,
"
удаленно"
,
"гибкий график"
,
"дистанционный деятельность"
,
"третуется человек"
,
"искать человек"
,
"достойный доход"
,
"удалённая работа"
,
"бакс"
,
"доллар"
,
"нужен человек"
,
"нужен помощник"
,
"вакансии"
,
"удалёнка"
,
"удаленка"
,
"условия труда"
,
"писать лс"
,
"личка
"
,
"писать в лс"
,
"личное сообщение"
,
"лс"
,
"партнер"
,
"сотрудничество"
,
"прибыль"
,
"бабки"
,
"пасивный заработок"
,
"без вложений"
,
"подробности лс"
,
# Мошенничество
# Мошенничество
"лотерея"
,
"быстрый выигрыш"
,
"выигрыш"
,
"приз"
,
"деньги"
,
"халява"
,
"прибыль"
,
"заработок"
,
"зп"
,
"подработка"
,
"легкий заработок"
,
"лотерея"
,
"быстрый выигрыш"
,
"выигрыш"
,
"приз"
,
"деньги"
,
"халява"
,
"прибыль"
,
"заработок"
,
"зп"
,
"подработка"
,
"легкий заработок"
,
...
@@ -67,7 +67,7 @@ SPAM_KEYWORDS = [
...
@@ -67,7 +67,7 @@ SPAM_KEYWORDS = [
"раскрутка аккаунт"
,
"реферальная ссылка"
,
"реферал"
,
"экономия"
,
"раскрутка аккаунт"
,
"реферальная ссылка"
,
"реферал"
,
"экономия"
,
# Политический спам
# Политический спам
"митинг"
,
"партия"
,
"агитация"
,
"голосовать"
,
"выборы"
,
"
кандидат
"
,
"совершеннолетний"
,
"для совершеннолетний"
,
"митинг"
,
"партия"
,
"агитация"
,
"голосовать"
,
"выборы"
,
"
поддержка
"
,
"совершеннолетний"
,
"для совершеннолетний"
,
"голосование"
,
"поддерживать мы"
,
"убийство"
,
"изнасилование"
,
"секс"
,
"для взрослых"
,
"кража"
,
"голосование"
,
"поддерживать мы"
,
"убийство"
,
"изнасилование"
,
"секс"
,
"для взрослых"
,
"кража"
,
# Вредоносные URL
# Вредоносные URL
...
@@ -119,12 +119,13 @@ class TelegramLogHandler(logging.Handler):
...
@@ -119,12 +119,13 @@ class TelegramLogHandler(logging.Handler):
await
self
.
bot
.
send_message
(
self
.
chat_id
,
message
)
await
self
.
bot
.
send_message
(
self
.
chat_id
,
message
)
def
emit
(
self
,
record
):
def
emit
(
self
,
record
):
log_message
=
self
.
format
(
record
)
log_message
=
f
"Chat ID: {main_chat_id}
\n
{self.format(record)}"
loop
=
asyncio
.
get_event_loop
()
loop
=
asyncio
.
get_event_loop
()
loop
.
create_task
(
self
.
send_log
(
log_message
))
loop
.
create_task
(
self
.
send_log
(
log_message
))
#asyncio.create_task(self.send_log(log_message)) # создаем асинхронную задачу
#asyncio.create_task(self.send_log(log_message)) # создаем асинхронную задачу
# Настройка логирования
# Настройка логирования
log_level
=
os
.
getenv
(
'LOG_LEVEL'
,
'DEBUG'
)
.
upper
()
# Считываем уровень логирования из .env (по умолчанию DEBUG)
log_level
=
os
.
getenv
(
'LOG_LEVEL'
,
'DEBUG'
)
.
upper
()
# Считываем уровень логирования из .env (по умолчанию DEBUG)
logging
.
basicConfig
(
level
=
log_level
,
format
=
'
%(asctime)
s -
%(levelname)
s -
%(message)
s'
)
logging
.
basicConfig
(
level
=
log_level
,
format
=
'
%(asctime)
s -
%(levelname)
s -
%(message)
s'
)
...
@@ -201,7 +202,6 @@ def normalize_text_to_infinitive(text):
...
@@ -201,7 +202,6 @@ def normalize_text_to_infinitive(text):
"""
"""
if
not
text
:
# Проверяем, что текст не None или пустой
if
not
text
:
# Проверяем, что текст не None или пустой
logger
.
warning
(
"No text for normalisation"
)
return
[]
return
[]
# Приведение текста к единой форме Unicode (NFKC)
# Приведение текста к единой форме Unicode (NFKC)
...
@@ -241,7 +241,6 @@ def extract_emojis(text):
...
@@ -241,7 +241,6 @@ def extract_emojis(text):
def
is_spam
(
text
):
def
is_spam
(
text
):
if
text
is
None
:
# Проверяем, что текст не None
if
text
is
None
:
# Проверяем, что текст не None
logger
.
warning
(
"No text"
)
return
False
return
False
# Нормализуем текст
# Нормализуем текст
...
@@ -294,20 +293,20 @@ async def welcome_new_user(event: ChatMemberUpdated):
...
@@ -294,20 +293,20 @@ async def welcome_new_user(event: ChatMemberUpdated):
if
event
.
new_chat_member
.
status
==
"member"
and
event
.
old_chat_member
.
status
not
in
[
"member"
,
"administrator"
,
"creator"
]:
if
event
.
new_chat_member
.
status
==
"member"
and
event
.
old_chat_member
.
status
not
in
[
"member"
,
"administrator"
,
"creator"
]:
new_user
=
event
.
new_chat_member
.
user
new_user
=
event
.
new_chat_member
.
user
# Проверка, если имя пользователя содержит арабские символы
# Проверка, если имя пользователя содержит арабские символы
if
is_arabic_name
(
new_user
.
first_name
):
if
is_arabic_name
(
new_user
.
first_name
):
try
:
try
:
# Немедленно удаляем пользователя
# Немедленно удаляем пользователя
await
bot
.
ban_chat_member
(
event
.
chat
.
id
,
new_user
.
id
)
await
bot
.
ban_chat_member
(
event
.
chat
.
id
,
new_user
.
id
)
logger
.
info
(
f
"User {new_user.first_name} ({new_user.id}) banned due to Arabic name."
)
logger
.
info
(
f
"User {new_user.first_name} ({new_user.id}) banned due to Arabic name."
)
return
# Прерываем дальнейшую обработку
return
# Прерываем дальнейшую обработку
except
AiogramError
as
e
:
except
AiogramError
as
e
:
logger
.
error
(
f
"Failed to ban user {new_user.id}. Error: {e}"
)
logger
.
error
(
f
"Failed to ban user {new_user.id}. Error: {e}"
)
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"Error banning user {new_user.id}: {e}"
)
logger
.
error
(
f
"Error banning user {new_user.id}: {e}"
)
return
return
math_problem
,
correct_answer
=
generate_math_problem
()
math_problem
,
correct_answer
=
generate_math_problem
()
try
:
try
:
...
@@ -401,7 +400,7 @@ async def cleanup_messages(user_data):
...
@@ -401,7 +400,7 @@ async def cleanup_messages(user_data):
for
message_id
in
user_data
[
"message_ids"
]:
for
message_id
in
user_data
[
"message_ids"
]:
try
:
try
:
await
bot
.
delete_message
(
chat_id
=
user_data
[
"chat_id"
],
message_id
=
message_id
)
await
bot
.
delete_message
(
chat_id
=
user_data
[
"chat_id"
],
message_id
=
message_id
)
logger
.
info
(
f
"
Сообщение с ID {message_id} успешно удалено из чата {user_data['chat_id']}
."
)
logger
.
info
(
f
"
Message with ID {message_id} successfully deleted from chat
."
)
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"Bot message deletion error. Error: {e}"
)
logger
.
error
(
f
"Bot message deletion error. Error: {e}"
)
...
@@ -410,7 +409,7 @@ async def cleanup_messages(user_data):
...
@@ -410,7 +409,7 @@ async def cleanup_messages(user_data):
try
:
try
:
if
user_message
:
if
user_message
:
await
bot
.
delete_message
(
chat_id
=
user_data
[
"chat_id"
],
message_id
=
user_message
.
message_id
)
await
bot
.
delete_message
(
chat_id
=
user_data
[
"chat_id"
],
message_id
=
user_message
.
message_id
)
logger
.
info
(
f
"
Сообщение с ID {message_id} успешно удалено из чата {user_data['chat_id']}
."
)
logger
.
info
(
f
"
Message с ID {message_id} successfully deleted from chat
."
)
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"User message deletion error. Error: {e}"
)
logger
.
error
(
f
"User message deletion error. Error: {e}"
)
except
Exception
as
e
:
except
Exception
as
e
:
...
@@ -420,11 +419,16 @@ async def cleanup_messages(user_data):
...
@@ -420,11 +419,16 @@ async def cleanup_messages(user_data):
async
def
handle_message
(
message
:
Message
):
async
def
handle_message
(
message
:
Message
):
"""Обработчик сообщений от пользователей для проверки ответа."""
"""Обработчик сообщений от пользователей для проверки ответа."""
# П
роверка на статус пользователя в группе
# П
олучаем статус пользователя в чате (администратор, участник и т.д.)
try
:
try
:
chat_member
=
await
bot
.
get_chat_member
(
message
.
chat
.
id
,
message
.
from_user
.
id
)
chat_member
=
await
bot
.
get_chat_member
(
message
.
chat
.
id
,
message
.
from_user
.
id
)
if
chat_member
.
status
not
in
[
"member"
,
"administrator"
,
"creator"
]:
# Если пользователь не участник, удаляем его сообщение
# Пропускаем сообщения от администраторов
if
chat_member
.
status
in
[
"administrator"
,
"creator"
]:
return
# Не проверяем сообщения администраторов
if
chat_member
.
status
not
in
[
"member"
]:
# Если пользователь не обычный участник, удаляем его сообщение
await
message
.
delete
()
await
message
.
delete
()
return
return
except
AiogramError
as
e
:
except
AiogramError
as
e
:
...
@@ -437,6 +441,7 @@ async def handle_message(message: Message):
...
@@ -437,6 +441,7 @@ async def handle_message(message: Message):
if
text
and
has_mixed_layout
(
text
):
if
text
and
has_mixed_layout
(
text
):
try
:
try
:
await
message
.
delete
()
await
message
.
delete
()
logger
.
debug
(
f
"Message with a mixed layout successfully deleted from group."
)
return
return
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"Error deleting a message with a mixed layout. Error: {e}"
)
logger
.
error
(
f
"Error deleting a message with a mixed layout. Error: {e}"
)
...
@@ -445,7 +450,7 @@ async def handle_message(message: Message):
...
@@ -445,7 +450,7 @@ async def handle_message(message: Message):
if
(
message
.
photo
or
message
.
video
or
message
.
document
)
and
text
.
strip
()
and
is_spam
(
text
):
if
(
message
.
photo
or
message
.
video
or
message
.
document
)
and
text
.
strip
()
and
is_spam
(
text
):
try
:
try
:
await
message
.
delete
()
await
message
.
delete
()
logger
.
info
(
f
"Multimedia message with ID {message.message_id} successfully deleted from group
{message.chat.id}
."
)
logger
.
info
(
f
"Multimedia message with ID {message.message_id} successfully deleted from group."
)
return
return
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"Error deleting a multimedia message. Error: {e}"
)
logger
.
error
(
f
"Error deleting a multimedia message. Error: {e}"
)
...
@@ -456,7 +461,7 @@ async def handle_message(message: Message):
...
@@ -456,7 +461,7 @@ async def handle_message(message: Message):
if
button
.
url
and
any
(
spam_word
in
button
.
url
.
lower
()
for
spam_word
in
SPAM_KEYWORDS
):
if
button
.
url
and
any
(
spam_word
in
button
.
url
.
lower
()
for
spam_word
in
SPAM_KEYWORDS
):
try
:
try
:
await
message
.
delete
()
await
message
.
delete
()
logger
.
info
(
f
"Message with links/buttons with ID {message.message_id} successfully deleted from group
{message.chat.id}
."
)
logger
.
info
(
f
"Message with links/buttons with ID {message.message_id} successfully deleted from group."
)
return
return
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"Error when deleting a message with a button. Error: {e}"
)
logger
.
error
(
f
"Error when deleting a message with a button. Error: {e}"
)
...
@@ -465,7 +470,7 @@ async def handle_message(message: Message):
...
@@ -465,7 +470,7 @@ async def handle_message(message: Message):
if
is_spam
(
message
.
text
):
if
is_spam
(
message
.
text
):
try
:
try
:
await
message
.
delete
()
await
message
.
delete
()
logger
.
info
(
f
"Message wiht spam {message.message_id} successfully deleted from group
{message.chat.id}
."
)
logger
.
info
(
f
"Message wiht spam {message.message_id} successfully deleted from group."
)
return
return
except
Exception
as
e
:
except
Exception
as
e
:
logger
.
error
(
f
"Error when trying to delete spam messages. Error: {e}"
)
logger
.
error
(
f
"Error when trying to delete spam messages. Error: {e}"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment