mirror of
https://gitflic.ru/project/maks1ms/ocab.git
synced 2024-12-24 00:33:05 +03:00
Открытое бета тестирование + фиксы первого дня
This commit is contained in:
parent
370ac7d02b
commit
9d89aee578
3
.gitignore
vendored
3
.gitignore
vendored
@ -6,4 +6,5 @@ env
|
|||||||
venv
|
venv
|
||||||
__pycache__
|
__pycache__
|
||||||
OCAB.db
|
OCAB.db
|
||||||
paths.json
|
src/paths.json
|
||||||
|
src/core/config.yaml
|
21
src/core/example_config.yaml
Normal file
21
src/core/example_config.yaml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
TELEGRAM:
|
||||||
|
TOKEN: xxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
APPROVED_CHAT_ID: "-123456789 | -012345678"
|
||||||
|
ADMINCHATID: -12345678
|
||||||
|
DEFAULT_CHAT_TAG: "@alt_gnome_chat"
|
||||||
|
CHECK_BOT: True
|
||||||
|
|
||||||
|
YANDEXGPT:
|
||||||
|
TOKEN: xxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
TOKEN_FOR_REQUEST: 8000
|
||||||
|
TOKEN_FOR_ANSWER: 2000
|
||||||
|
CATALOGID: xxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
PROMPT: "Ты чат-бот ..."
|
||||||
|
STARTWORD: "Бот| Бот, | бот | бот,"
|
||||||
|
INWORD: "помогите | не работает"
|
||||||
|
|
||||||
|
ROLES:
|
||||||
|
ADMIN: 2
|
||||||
|
MODERATOR: 1
|
||||||
|
USER: 0
|
||||||
|
BOT: 3
|
24
src/core/logger.py
Normal file
24
src/core/logger.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
async def check_log_file():
|
||||||
|
# Проверка наличия файла для логов в формате log-dd-mm-yyyy.log
|
||||||
|
# Если файл существует, то pass
|
||||||
|
# Если файл не существует, то создаём его. файл лежит в директории src.core.log
|
||||||
|
current_data = time.strftime("%d-%m-%Y")
|
||||||
|
log_file = os.path.join(os.path.dirname(__file__), "log/", f"log-{current_data}.log")
|
||||||
|
if not os.path.exists(log_file):
|
||||||
|
with open(log_file, 'w') as file:
|
||||||
|
file.write("Log file created\n")
|
||||||
|
file.close()
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def log(message):
|
||||||
|
await check_log_file()
|
||||||
|
current_data = time.strftime("%d-%m-%Y")
|
||||||
|
log_file = os.path.join(os.path.dirname(__file__), "log/", f"log-{current_data}.log")
|
||||||
|
# print(log_file)
|
||||||
|
with open(log_file, 'a') as file:
|
||||||
|
file.write(f"{time.strftime('%H:%M:%S')} {message}\n")
|
||||||
|
file.close()
|
@ -1,7 +1,10 @@
|
|||||||
from aiogram import Dispatcher
|
from aiogram import Dispatcher, Router, F, Bot
|
||||||
|
from aiogram.types import Message
|
||||||
|
|
||||||
|
from src.modules.standard.info.routers import router as info_router
|
||||||
from src.modules.standard.admin.routers import router as admin_router
|
from src.modules.standard.admin.routers import router as admin_router
|
||||||
from src.modules.external.yandexgpt.routers import router as yandexgpt_router
|
from src.modules.standard.message_processing.message_api import router as process_message
|
||||||
|
from src.modules.standard.welcome.routers import router as welcome_router
|
||||||
|
|
||||||
|
|
||||||
async def include_routers(dp: Dispatcher):
|
async def include_routers(dp: Dispatcher):
|
||||||
@ -9,5 +12,7 @@ async def include_routers(dp: Dispatcher):
|
|||||||
Подключение роутеров в бота
|
Подключение роутеров в бота
|
||||||
dp.include_router()
|
dp.include_router()
|
||||||
"""
|
"""
|
||||||
dp.include_router(yandexgpt_router)
|
dp.include_router(info_router)
|
||||||
dp.include_router(admin_router)
|
dp.include_router(admin_router)
|
||||||
|
dp.include_router(process_message)
|
||||||
|
|
10
src/modules/external/yandexgpt/handlers.py
vendored
10
src/modules/external/yandexgpt/handlers.py
vendored
@ -2,12 +2,18 @@ from aiogram import Bot
|
|||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
from src.modules.external.yandexgpt.yandexgpt import *
|
from src.modules.external.yandexgpt.yandexgpt import *
|
||||||
from src.modules.standard.config.config import get_yandexgpt_token, get_yandexgpt_catalog_id, get_yandexgpt_prompt
|
from src.modules.standard.config.config import get_yandexgpt_token, get_yandexgpt_catalog_id, get_yandexgpt_prompt
|
||||||
|
from src.modules.standard.database.db_api import add_message
|
||||||
|
from src.core.logger import log
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
|
||||||
async def answer_to_message(message: Message, bot: Bot):
|
async def answer_to_message(message: Message, bot: Bot):
|
||||||
|
# print("answer_to_message")
|
||||||
|
await log("answer_to_message")
|
||||||
yagpt = YandexGPT(get_yandexgpt_token(), get_yandexgpt_catalog_id())
|
yagpt = YandexGPT(get_yandexgpt_token(), get_yandexgpt_catalog_id())
|
||||||
text = message.text
|
text = message.text
|
||||||
prompt = get_yandexgpt_prompt()
|
prompt = get_yandexgpt_prompt()
|
||||||
response = await yagpt.async_yandexgpt(system_prompt=prompt, input_messages=text)
|
# response = await yagpt.async_yandexgpt(system_prompt=prompt, input_messages=text)
|
||||||
await message.reply(response, parse_mode="Markdown")
|
response = await yagpt.yandexgpt_request(chat_id = message.chat.id, message_id = message.message_id, type = "yandexgpt")
|
||||||
|
reply = await message.reply(response, parse_mode="Markdown")
|
||||||
|
add_message(reply, message_ai_model="yandexgpt")
|
||||||
|
2
src/modules/external/yandexgpt/routers.py
vendored
2
src/modules/external/yandexgpt/routers.py
vendored
@ -3,5 +3,5 @@ from aiogram import Router, F
|
|||||||
from src.modules.external.yandexgpt.handlers import answer_to_message
|
from src.modules.external.yandexgpt.handlers import answer_to_message
|
||||||
|
|
||||||
router = Router()
|
router = Router()
|
||||||
# Если сообщение содержит в начале текст "Гномик" или "гномик", то вызывается функция answer_to_message
|
# Если сообщение содержит в начале текст "Гномик" или "гномик" или отвечает на сообщение бота, то вызывается функция answer_to_message
|
||||||
router.message.register(answer_to_message, F.text.startswith("Гномик") | F.text.startswith("гномик"))
|
router.message.register(answer_to_message, F.text.startswith("Гномик") | F.text.startswith("гномик"))
|
89
src/modules/external/yandexgpt/yandexgpt.py
vendored
89
src/modules/external/yandexgpt/yandexgpt.py
vendored
@ -2,6 +2,7 @@ import requests
|
|||||||
import json
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
from src.core.logger import log
|
||||||
|
|
||||||
from ...standard.database import *
|
from ...standard.database import *
|
||||||
from ...standard.config.config import *
|
from ...standard.config.config import *
|
||||||
@ -23,28 +24,44 @@ class YandexGPT:
|
|||||||
self.token = token
|
self.token = token
|
||||||
self.catalog_id = catalog_id
|
self.catalog_id = catalog_id
|
||||||
|
|
||||||
async def async_token_check(self, messages, gpt, max_tokens, del_msg_id=1):
|
|
||||||
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/tokenize"
|
|
||||||
while True:
|
|
||||||
text = ""
|
|
||||||
for message in messages:
|
|
||||||
text += message["text"]
|
|
||||||
try:
|
|
||||||
response = requests.post(url, json={"model": gpt, "text": text})
|
|
||||||
except Exception as e: # TODO: Переделать обработку ошибок
|
|
||||||
print(e)
|
|
||||||
continue
|
|
||||||
if int(response.text) < max_tokens - 2000:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
messages.pop(del_msg_id)
|
|
||||||
return messages
|
|
||||||
|
|
||||||
async def async_request(self, url, headers, prompt) -> dict:
|
async def async_request(self, url, headers, prompt) -> dict:
|
||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.post(url, headers=headers, json=prompt) as response:
|
async with session.post(url, headers=headers, json=prompt) as response:
|
||||||
return await response.json()
|
return await response.json()
|
||||||
|
|
||||||
|
async def async_token_check(self, messages, gpt, max_tokens, stream, temperature, del_msg_id=1):
|
||||||
|
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/tokenizeCompletion"
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Authorization": f"Api-Key {self.token}"
|
||||||
|
}
|
||||||
|
answer_token = get_yandexgpt_token_for_answer()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
request = {
|
||||||
|
"modelUri": gpt,
|
||||||
|
"completionOptions": {
|
||||||
|
"stream": stream,
|
||||||
|
"temperature": temperature,
|
||||||
|
"maxTokens": max_tokens
|
||||||
|
},
|
||||||
|
"messages": messages
|
||||||
|
}
|
||||||
|
response = await self.async_request(url=url, headers=headers, prompt=request)
|
||||||
|
except Exception as e: # TODO: Переделать обработку ошибок
|
||||||
|
# print(e)
|
||||||
|
await log(f"Error: {e}")
|
||||||
|
|
||||||
|
continue
|
||||||
|
if int(len(response["tokens"])) < (max_tokens - answer_token):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
messages.pop(del_msg_id)
|
||||||
|
except IndexError:
|
||||||
|
Exception("IndexError: list index out of range")
|
||||||
|
return messages
|
||||||
|
|
||||||
async def async_yandexgpt_lite(self, system_prompt, input_messages, stream=False, temperature=0.6, max_tokens=8000):
|
async def async_yandexgpt_lite(self, system_prompt, input_messages, stream=False, temperature=0.6, max_tokens=8000):
|
||||||
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/completion"
|
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/completion"
|
||||||
gpt = f"gpt://{self.catalog_id}/yandexgpt-lite/latest"
|
gpt = f"gpt://{self.catalog_id}/yandexgpt-lite/latest"
|
||||||
@ -71,7 +88,14 @@ class YandexGPT:
|
|||||||
response = requests.post(url, headers=headers, json=prompt).text
|
response = requests.post(url, headers=headers, json=prompt).text
|
||||||
return json.loads(response)["result"]["alternatives"][0]["message"]["text"]
|
return json.loads(response)["result"]["alternatives"][0]["message"]["text"]
|
||||||
|
|
||||||
async def async_yandexgpt(self, system_prompt, input_messages, stream=False, temperature=0.6, max_tokens=8000):
|
async def async_yandexgpt(
|
||||||
|
self,
|
||||||
|
system_prompt,
|
||||||
|
input_messages,
|
||||||
|
stream=False,
|
||||||
|
temperature=0.6,
|
||||||
|
max_tokens=get_yandexgpt_token_for_request()
|
||||||
|
):
|
||||||
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/completion"
|
url = "https://llm.api.cloud.yandex.net/foundationModels/v1/completion"
|
||||||
gpt = f"gpt://{self.catalog_id}/yandexgpt/latest"
|
gpt = f"gpt://{self.catalog_id}/yandexgpt/latest"
|
||||||
headers = {
|
headers = {
|
||||||
@ -79,13 +103,14 @@ class YandexGPT:
|
|||||||
"Authorization": f"Api-Key {self.token}"
|
"Authorization": f"Api-Key {self.token}"
|
||||||
}
|
}
|
||||||
|
|
||||||
messages = [{"role": "system", "text": system_prompt}]
|
messages = []
|
||||||
messages.append({"role": "user", "text": input_messages})
|
messages.append({"role": "system", "text": system_prompt})
|
||||||
# for message in input_messages:
|
for message in input_messages:
|
||||||
# messages.append(message)
|
messages.append(message)
|
||||||
# messages = await self.async_token_check(messages, gpt, max_tokens)
|
|
||||||
|
|
||||||
prompt = {
|
messages = await self.async_token_check(messages, gpt, max_tokens, stream, temperature)
|
||||||
|
|
||||||
|
request = {
|
||||||
"modelUri": gpt,
|
"modelUri": gpt,
|
||||||
"completionOptions": {
|
"completionOptions": {
|
||||||
"stream": stream,
|
"stream": stream,
|
||||||
@ -94,7 +119,7 @@ class YandexGPT:
|
|||||||
},
|
},
|
||||||
"messages": messages
|
"messages": messages
|
||||||
}
|
}
|
||||||
response = await self.async_request(url=url, headers=headers, prompt=prompt)
|
response = await self.async_request(url=url, headers=headers, prompt=request)
|
||||||
return response["result"]["alternatives"][0]["message"]["text"]
|
return response["result"]["alternatives"][0]["message"]["text"]
|
||||||
|
|
||||||
|
|
||||||
@ -153,21 +178,21 @@ class YandexGPT:
|
|||||||
# TODO: Сделать функцию Vision
|
# TODO: Сделать функцию Vision
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
async def collect_messages(self, message_id, chat_id, start_message_id):
|
async def collect_messages(self, message_id, chat_id):
|
||||||
messages = []
|
messages = []
|
||||||
# Собираем цепочку сообщений в формате: [{"role": "user", "text": "<Имя_пользователя>: Привет!"},
|
# Собираем цепочку сообщений в формате: [{"role": "user", "text": "<Имя_пользователя>: Привет!"},
|
||||||
# {"role": "assistant", "text": "Привет!"}]
|
# {"role": "assistant", "text": "Привет!"}]
|
||||||
while True:
|
while True:
|
||||||
message = db_api.get_message_text(chat_id, message_id)
|
message = db_api.get_message_text(chat_id, message_id)
|
||||||
if db_api.get_message_ai_model(chat_id, start_message_id) != None:
|
if db_api.get_message_ai_model(chat_id, message_id) != None:
|
||||||
messages.append({"role": "assistant", "text": message})
|
messages.append({"role": "assistant", "text": message})
|
||||||
else:
|
else:
|
||||||
sender_name = db_api.get_user_name(db_api.get_message_sender_id(chat_id, start_message_id))
|
sender_name = db_api.get_user_name(db_api.get_message_sender_id(chat_id, message_id))
|
||||||
messages.append({"role": "user", "text": sender_name + ": " + message})
|
messages.append({"role": "user", "text": sender_name + ": " + message})
|
||||||
message_id = db_api.get_message_answer_to_message_id(chat_id, message_id)
|
message_id = db_api.get_answer_to_message_id(chat_id, message_id)
|
||||||
if message_id is None:
|
if message_id is None:
|
||||||
break
|
break
|
||||||
return messages.reverse()
|
return list(reversed(messages))
|
||||||
|
|
||||||
async def collecting_messages_for_history(self, start_message_id, end_message_id, chat_id):
|
async def collecting_messages_for_history(self, start_message_id, end_message_id, chat_id):
|
||||||
messages = []
|
messages = []
|
||||||
@ -195,11 +220,13 @@ class YandexGPT:
|
|||||||
stream=False, temperature=0.6, max_tokens=8000
|
stream=False, temperature=0.6, max_tokens=8000
|
||||||
)
|
)
|
||||||
elif type == "yandexgpt":
|
elif type == "yandexgpt":
|
||||||
|
# print("yandexgpt_request")
|
||||||
|
await log("yandexgpt_request")
|
||||||
messages = await self.collect_messages(message_id, chat_id)
|
messages = await self.collect_messages(message_id, chat_id)
|
||||||
return await self.async_yandexgpt(
|
return await self.async_yandexgpt(
|
||||||
system_prompt=get_yandexgpt_prompt(),
|
system_prompt=get_yandexgpt_prompt(),
|
||||||
input_messages=messages,
|
input_messages=messages,
|
||||||
stream=False, temperature=0.6, max_tokens=8000
|
stream=False, temperature=0.6, max_tokens=get_yandexgpt_token_for_request()
|
||||||
)
|
)
|
||||||
elif type == "yandexgpt-translate":
|
elif type == "yandexgpt-translate":
|
||||||
return await self.async_yandexgpt_translate(
|
return await self.async_yandexgpt_translate(
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
from aiogram import Bot
|
from aiogram import Bot
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message
|
||||||
|
from src.modules.standard.config.config import get_default_chat_tag
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
async def delete_message(message: Message, bot: Bot):
|
async def delete_message(message: Message, bot: Bot):
|
||||||
@ -11,3 +13,34 @@ async def error_access(message: Message, bot: Bot):
|
|||||||
|
|
||||||
async def get_chat_id(message: Message, bot: Bot):
|
async def get_chat_id(message: Message, bot: Bot):
|
||||||
await message.reply(f"ID данного чата: `{message.chat.id}`", parse_mode="MarkdownV2")
|
await message.reply(f"ID данного чата: `{message.chat.id}`", parse_mode="MarkdownV2")
|
||||||
|
|
||||||
|
async def chat_not_in_approve_list(message: Message, bot: Bot):
|
||||||
|
await message.reply(
|
||||||
|
f"Бот недоступен в данном чате, пожалуйста,"
|
||||||
|
f" обратитесь к администратору для добавления чата в список доступных или перейдите в чат "
|
||||||
|
f"{get_default_chat_tag()}"
|
||||||
|
)
|
||||||
|
await get_chat_id(message, bot)
|
||||||
|
|
||||||
|
async def mute_user(chat_id: int, user_id: int, time: int, bot: Bot):
|
||||||
|
# *, can_send_messages: bool | None = None, can_send_audios: bool | None = None, can_send_documents: bool | None = None, can_send_photos: bool | None = None, can_send_videos: bool | None = None, can_send_video_notes: bool | None = None, can_send_voice_notes: bool | None = None, can_send_polls: bool | None = None, can_send_other_messages: bool | None = None, can_add_web_page_previews: bool | None = None, can_change_info: bool | None = None, can_invite_users: bool | None = None, can_pin_messages: bool | None = None, can_manage_topics: bool | None = None, **extra_data: Any)
|
||||||
|
|
||||||
|
mutePermissions = {
|
||||||
|
"can_send_messages": False,
|
||||||
|
"can_send_audios": False,
|
||||||
|
"can_send_documents": False,
|
||||||
|
"can_send_photos": False,
|
||||||
|
"can_send_videos": False,
|
||||||
|
"can_send_video_notes": False,
|
||||||
|
"can_send_voice_notes": False,
|
||||||
|
"can_send_polls": False,
|
||||||
|
"can_send_other_messages": False,
|
||||||
|
"can_add_web_page_previews": False,
|
||||||
|
"can_change_info": False,
|
||||||
|
"can_invite_users": False,
|
||||||
|
"can_pin_messages": False,
|
||||||
|
"can_manage_topics": False
|
||||||
|
}
|
||||||
|
end_time = time + int(time.time())
|
||||||
|
await bot.restrict_chat_member(chat_id, user_id, until_date=end_time, **mutePermissions)
|
||||||
|
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
from aiogram import Router, F
|
from aiogram import Router, F
|
||||||
|
|
||||||
from src.modules.standard.admin.handlers import delete_message, error_access, get_chat_id
|
from src.modules.standard.admin.handlers import delete_message, error_access, get_chat_id, chat_not_in_approve_list
|
||||||
from src.modules.standard.filters.admin import ChatModerOrAdminFilter
|
from src.modules.standard.filters.filters import ChatModerOrAdminFilter, ChatNotInApproveFilter
|
||||||
|
|
||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
|
# Если сообщение содержит какой либо текст и выполняется фильтр ChatNotInApproveFilter, то вызывается функция chat_not_in_approve_list
|
||||||
|
router.message.register(chat_not_in_approve_list, ChatNotInApproveFilter(), F.text)
|
||||||
|
|
||||||
router.message.register(get_chat_id, ChatModerOrAdminFilter(), F.text == '/chatID')
|
router.message.register(get_chat_id, ChatModerOrAdminFilter(), F.text == '/chatID')
|
||||||
|
|
||||||
router.message.register(delete_message, ChatModerOrAdminFilter(), F.text == '/rm')
|
router.message.register(delete_message, ChatModerOrAdminFilter(), F.text == '/rm')
|
||||||
|
@ -17,6 +17,20 @@ config = get_config()
|
|||||||
def get_telegram_token() -> str:
|
def get_telegram_token() -> str:
|
||||||
return config["TELEGRAM"]["TOKEN"]
|
return config["TELEGRAM"]["TOKEN"]
|
||||||
|
|
||||||
|
def get_telegram_check_bot() -> bool:
|
||||||
|
return config["TELEGRAM"]["CHECK_BOT"]
|
||||||
|
|
||||||
|
def get_aproved_chat_id() -> list:
|
||||||
|
# Возваращем сплитованный список id чатов в формате int
|
||||||
|
return [int(chat_id) for chat_id in config["TELEGRAM"]["APPROVED_CHAT_ID"].split(" | ")]
|
||||||
|
|
||||||
|
def get_user_role_name(role_number) -> dict:
|
||||||
|
# Возвращаем название роли пользвателя по номеру роли, если такой роли нет, возвращаем неизвестно
|
||||||
|
return config["ROLES"].get(role_number, "Неизвестно")
|
||||||
|
|
||||||
|
def get_default_chat_tag() -> str:
|
||||||
|
return config["TELEGRAM"]["DEFAULT_CHAT_TAG"]
|
||||||
|
|
||||||
def get_yandexgpt_token() -> str:
|
def get_yandexgpt_token() -> str:
|
||||||
return config["YANDEXGPT"]["TOKEN"]
|
return config["YANDEXGPT"]["TOKEN"]
|
||||||
|
|
||||||
@ -26,7 +40,21 @@ def get_yandexgpt_catalog_id() -> str:
|
|||||||
def get_yandexgpt_prompt() -> str:
|
def get_yandexgpt_prompt() -> str:
|
||||||
return config["YANDEXGPT"]["PROMPT"]
|
return config["YANDEXGPT"]["PROMPT"]
|
||||||
|
|
||||||
|
def get_yandexgpt_start_words() -> list:
|
||||||
|
return config["YANDEXGPT"]["STARTWORD"].split(" | ")
|
||||||
|
|
||||||
|
def get_yandexgpt_in_words() -> list:
|
||||||
|
return config["YANDEXGPT"]["INWORD"].split(" | ")
|
||||||
|
|
||||||
|
def get_yandexgpt_token_for_request() -> int:
|
||||||
|
return config["YANDEXGPT"]["TOKEN_FOR_REQUEST"]
|
||||||
|
|
||||||
|
def get_yandexgpt_token_for_answer() -> int:
|
||||||
|
return config["YANDEXGPT"]["TOKEN_FOR_ANSWER"]
|
||||||
|
|
||||||
def get_access_rights() -> dict:
|
def get_access_rights() -> dict:
|
||||||
return get_config()["ACCESS_RIGHTS"]
|
return get_config()["ACCESS_RIGHTS"]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from .models.chat_stats import ChatStats
|
|||||||
from ....service import paths
|
from ....service import paths
|
||||||
from ..exceptions.module_exceptions import MissingModuleName, NotExpectedModuleName
|
from ..exceptions.module_exceptions import MissingModuleName, NotExpectedModuleName
|
||||||
import peewee as pw
|
import peewee as pw
|
||||||
|
from aiogram.types import Message
|
||||||
|
|
||||||
|
|
||||||
def connect_database(is_test: bool = False, module: str | None = None):
|
def connect_database(is_test: bool = False, module: str | None = None):
|
||||||
@ -39,7 +40,7 @@ def add_chat(chat_id, chat_name, chat_type=10, chat_stats=0):
|
|||||||
chat, created = Chats.get_or_create(id=chat_id, defaults={
|
chat, created = Chats.get_or_create(id=chat_id, defaults={
|
||||||
'chat_name': chat_name,
|
'chat_name': chat_name,
|
||||||
'chat_type': chat_type,
|
'chat_type': chat_type,
|
||||||
'chat_stats': chat_stats,
|
'chat_all_stat': chat_stats,
|
||||||
})
|
})
|
||||||
if not created:
|
if not created:
|
||||||
# Обновить существующий чат, если он уже существует
|
# Обновить существующий чат, если он уже существует
|
||||||
@ -49,7 +50,12 @@ def add_chat(chat_id, chat_name, chat_type=10, chat_stats=0):
|
|||||||
chat.save()
|
chat.save()
|
||||||
|
|
||||||
|
|
||||||
def add_user(user_id, user_name, user_tag=None, user_role=0, user_stats=0, user_rep=0):
|
def add_user(user_id, user_first_name, user_last_name=None, user_tag=None, user_role=0, user_stats=0, user_rep=0):
|
||||||
|
if user_last_name is None:
|
||||||
|
user_name = user_first_name
|
||||||
|
else:
|
||||||
|
user_name = user_first_name + " " + user_last_name
|
||||||
|
|
||||||
user, created = Users.get_or_create(id=user_id, defaults={
|
user, created = Users.get_or_create(id=user_id, defaults={
|
||||||
'user_tag': user_tag,
|
'user_tag': user_tag,
|
||||||
'user_name': user_name,
|
'user_name': user_name,
|
||||||
@ -67,15 +73,18 @@ def add_user(user_id, user_name, user_tag=None, user_role=0, user_stats=0, user_
|
|||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
|
|
||||||
def add_message(message_chat_id, message_id, message_sender_id, message_text, answer_to_message_id=None,
|
def add_message(message: Message, message_ai_model=None):
|
||||||
message_ai_model=None):
|
if message.reply_to_message:
|
||||||
|
answer_to_message_id = message.reply_to_message.message_id
|
||||||
|
else:
|
||||||
|
answer_to_message_id = None
|
||||||
Messages.create(
|
Messages.create(
|
||||||
message_chat_id=message_chat_id,
|
message_chat_id=message.chat.id,
|
||||||
message_id=message_id,
|
message_id=message.message_id,
|
||||||
message_sender_id=message_sender_id,
|
message_sender_id=message.from_user.id,
|
||||||
answer_to_message_id=answer_to_message_id,
|
answer_to_message_id=answer_to_message_id,
|
||||||
message_ai_model=message_ai_model,
|
message_ai_model=message_ai_model,
|
||||||
message_text=message_text
|
message_text=message.text
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -127,6 +136,10 @@ def get_user_tag(user_id):
|
|||||||
user = Users.get_or_none(Users.id == user_id)
|
user = Users.get_or_none(Users.id == user_id)
|
||||||
return user.user_tag if user else None
|
return user.user_tag if user else None
|
||||||
|
|
||||||
|
def get_user_id(user_tag):
|
||||||
|
user = Users.get_or_none(Users.user_tag == user_tag)
|
||||||
|
return user.id if user else None
|
||||||
|
|
||||||
|
|
||||||
def get_user_name(user_id):
|
def get_user_name(user_id):
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
user = Users.get_or_none(Users.id == user_id)
|
||||||
@ -148,7 +161,11 @@ def get_user_rep(user_id):
|
|||||||
return user.user_rep if user else None
|
return user.user_rep if user else None
|
||||||
|
|
||||||
|
|
||||||
def change_user_name(user_id, new_user_name):
|
def change_user_name(user_id, user_first_name, user_last_name=None):
|
||||||
|
if user_last_name is None:
|
||||||
|
new_user_name = user_first_name
|
||||||
|
else:
|
||||||
|
new_user_name = user_first_name + " " + user_last_name
|
||||||
query = Users.update(user_name=new_user_name).where(Users.id == user_id)
|
query = Users.update(user_name=new_user_name).where(Users.id == user_id)
|
||||||
query.execute()
|
query.execute()
|
||||||
|
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
from aiogram.filters import BaseFilter
|
|
||||||
from aiogram.types import Message
|
|
||||||
from aiogram import Bot
|
|
||||||
|
|
||||||
from src.modules.standard.roles.roles import Roles
|
|
||||||
|
|
||||||
class ChatModerOrAdminFilter(BaseFilter):
|
|
||||||
async def __call__(self, message: Message, bot: Bot) -> bool:
|
|
||||||
user_id = message.from_user.id
|
|
||||||
roles = Roles()
|
|
||||||
admins = await bot.get_chat_administrators(message.chat.id)
|
|
||||||
return await roles.check_admin_permission(user_id) or \
|
|
||||||
await roles.check_moderator_permission(user_id) or any(user_id == admin.user.id for admin in admins)
|
|
29
src/modules/standard/filters/filters.py
Normal file
29
src/modules/standard/filters/filters.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from aiogram.filters import BaseFilter
|
||||||
|
from aiogram.types import Message
|
||||||
|
from aiogram import Bot
|
||||||
|
|
||||||
|
from src.modules.standard.roles.roles import Roles
|
||||||
|
from src.modules.standard.config.config import get_aproved_chat_id
|
||||||
|
from src.core.logger import log
|
||||||
|
|
||||||
|
class ChatModerOrAdminFilter(BaseFilter):
|
||||||
|
async def __call__(self, message: Message, bot: Bot) -> bool:
|
||||||
|
user_id = message.from_user.id
|
||||||
|
roles = Roles()
|
||||||
|
admins = await bot.get_chat_administrators(message.chat.id)
|
||||||
|
return await roles.check_admin_permission(user_id) or \
|
||||||
|
await roles.check_moderator_permission(user_id) or any(user_id == admin.user.id for admin in admins)
|
||||||
|
|
||||||
|
class ChatNotInApproveFilter(BaseFilter):
|
||||||
|
async def __call__(self, message: Message, bot: Bot) -> bool:
|
||||||
|
# print("chat_check")
|
||||||
|
await log("chat_check")
|
||||||
|
chat_id = message.chat.id
|
||||||
|
if chat_id in get_aproved_chat_id():
|
||||||
|
# print(f"Chat in approve list: {chat_id}")
|
||||||
|
await log(f"Chat in approve list: {chat_id}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# print(f"Chat not in approve list: {chat_id}")
|
||||||
|
await log(f"Chat not in approve list: {chat_id}")
|
||||||
|
return True
|
0
src/modules/standard/info/__init__.py
Normal file
0
src/modules/standard/info/__init__.py
Normal file
60
src/modules/standard/info/handlers.py
Normal file
60
src/modules/standard/info/handlers.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
from aiogram import Bot
|
||||||
|
from aiogram.types import Message
|
||||||
|
from src.modules.standard.config.config import get_user_role_name
|
||||||
|
from src.modules.standard.roles.roles import Roles
|
||||||
|
from src.modules.standard.database.db_api import *
|
||||||
|
from src.core.logger import log
|
||||||
|
|
||||||
|
async def get_info_answer_by_id(message: Message, bot: Bot, user_id: int):
|
||||||
|
if get_message_ai_model(message.chat.id, message.message_id) is not None:
|
||||||
|
await message.reply("Это сообщение было сгенерировано ботом используя модель: " + get_message_ai_model(message.chat.id, message.message_id))
|
||||||
|
elif user_id == bot.id:
|
||||||
|
await message.reply("Это сообщение было отправлено ботом")
|
||||||
|
elif get_user(user_id) is None:
|
||||||
|
await message.reply("Пользователь не найден")
|
||||||
|
# print(get_user(user_id))
|
||||||
|
await log(f"Пользователь не найден: {user_id}, {get_user(user_id)}")
|
||||||
|
else:
|
||||||
|
roles = Roles()
|
||||||
|
answer = (
|
||||||
|
f"Пользователь: {get_user_name(user_id)}\n"
|
||||||
|
f"Роль: {await roles.get_role_name(role_id=get_user_role(user_id))}\n"
|
||||||
|
f"Тег: @{get_user_tag(user_id)}\n"
|
||||||
|
f"Кол-во сообщений: {get_user_all_stats(user_id)}\n"
|
||||||
|
f"Репутация: {get_user_rep(user_id)}"
|
||||||
|
)
|
||||||
|
await message.reply(answer)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_user_info(message: Message, bot: Bot):
|
||||||
|
# Проверяем содержимое сообщения, если содержит вторым элементом тег пользователя, то выводим информацию о нем
|
||||||
|
# Если сообщение отвечает на другое сообщение, то выводим информацию о пользователе, на чье сообщение был ответ
|
||||||
|
# Если это бот то выводим информацию что это бот и какая модель yandexgpt используется
|
||||||
|
try:
|
||||||
|
if len(message.text.split()) > 1 and message.text.split()[1].startswith("@"):
|
||||||
|
user_tag = message.text.split()[1][1:]
|
||||||
|
user_id = get_user_id(user_tag)
|
||||||
|
if user_id:
|
||||||
|
await get_info_answer_by_id(message, bot, user_id)
|
||||||
|
else:
|
||||||
|
await message.reply(f"Пользователь с тегом @{user_tag} не найден")
|
||||||
|
elif message.reply_to_message:
|
||||||
|
user_id = message.reply_to_message.from_user.id
|
||||||
|
await get_info_answer_by_id(message, bot, user_id)
|
||||||
|
else:
|
||||||
|
await get_info_answer_by_id(message, bot, message.from_user.id)
|
||||||
|
except Exception as e:
|
||||||
|
await message.reply("В вашем запросе что-то пошло не так,"
|
||||||
|
" попробуйте запросить информацию о пользователе по его тегу или ответив на его сообщение")
|
||||||
|
# print(e)
|
||||||
|
await log(e)
|
||||||
|
|
||||||
|
async def get_chat_info(message: Message, bot: Bot):
|
||||||
|
answer = (
|
||||||
|
f"*Название чата:* {message.chat.title}\n"
|
||||||
|
f"*ID чата:* `{message.chat.id}`\n \n"
|
||||||
|
f"*Суммарное количество сообщений в чате:* {get_chat_all_stat(message.chat.id)}\n"
|
||||||
|
f"*Количество пользователей в чате:* {await bot.get_chat_member_count(message.chat.id)}\n"
|
||||||
|
f"*Количество администраторов в чате:* {len(await bot.get_chat_administrators(message.chat.id))}"
|
||||||
|
)
|
||||||
|
await message.reply(answer, parse_mode="MarkdownV2")
|
8
src/modules/standard/info/routers.py
Normal file
8
src/modules/standard/info/routers.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from aiogram import Router, F
|
||||||
|
|
||||||
|
from src.modules.standard.info.handlers import get_user_info, get_chat_info
|
||||||
|
|
||||||
|
router = Router()
|
||||||
|
|
||||||
|
router.message.register(get_user_info, F.text.startswith("/info") == True)
|
||||||
|
router.message.register(get_chat_info, F.text.startswith("/chatinfo") == True)
|
0
src/modules/standard/message_processing/__init__.py
Normal file
0
src/modules/standard/message_processing/__init__.py
Normal file
99
src/modules/standard/message_processing/message_api.py
Normal file
99
src/modules/standard/message_processing/message_api.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
from aiogram import Router, F, Bot, types
|
||||||
|
|
||||||
|
from src.modules.external.yandexgpt.handlers import answer_to_message
|
||||||
|
from src.modules.standard.database.db_api import *
|
||||||
|
from src.modules.standard.config.config import get_yandexgpt_start_words, get_yandexgpt_in_words, get_aproved_chat_id
|
||||||
|
from src.core.logger import log
|
||||||
|
|
||||||
|
|
||||||
|
async def chat_check(message: types.Message):
|
||||||
|
# Проверка наличия id чата в базе данных чатов
|
||||||
|
# Если чата нет в базе данных, то проверяем его в наличии в конфиге и если он там есть то добавляем его в БД
|
||||||
|
# Если чат есть в базе данных, то pass
|
||||||
|
if get_chat(message.chat.id) is None:
|
||||||
|
if message.chat.id in get_aproved_chat_id():
|
||||||
|
# print(f"Chat in approve list: {message.chat.id} {message.chat.title}")
|
||||||
|
await log(f"Chat in approve list: {message.chat.id} {message.chat.title}")
|
||||||
|
add_chat(message.chat.id, message.chat.title)
|
||||||
|
# print(f"Chat added: {message.chat.id} {message.chat.title}")
|
||||||
|
await log(f"Chat added: {message.chat.id} {message.chat.title}")
|
||||||
|
else:
|
||||||
|
# print(f"Chat not in approve list: {message.chat.id} {message.chat.title}")
|
||||||
|
await log(f"Chat not in approve list: {message.chat.id} {message.chat.title}")
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Проверяем обновление названия чата
|
||||||
|
chat = get_chat(message.chat.id)
|
||||||
|
if chat.chat_name != message.chat.title:
|
||||||
|
chat.chat_name = message.chat.title
|
||||||
|
chat.save()
|
||||||
|
# print(f"Chat updated: {message.chat.id} {message.chat.title}")
|
||||||
|
await log(f"Chat updated: {message.chat.id} {message.chat.title}")
|
||||||
|
else:
|
||||||
|
# print(f"Chat already exists: {message.chat.id} {message.chat.title}")
|
||||||
|
await log(f"Chat already exists: {message.chat.id} {message.chat.title}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def user_check(message: types.Message):
|
||||||
|
# Проверка наличия id пользователя в базе данных пользователей
|
||||||
|
# Если пользователя нет в базе данных, то добавляем его
|
||||||
|
# Если пользователь есть в базе данных, то pass
|
||||||
|
current_user_name = ""
|
||||||
|
if message.from_user.last_name is None:
|
||||||
|
current_user_name = message.from_user.first_name
|
||||||
|
else:
|
||||||
|
current_user_name = message.from_user.first_name + " " + message.from_user.last_name
|
||||||
|
|
||||||
|
if get_user(message.from_user.id) is None:
|
||||||
|
add_user(message.from_user.id,
|
||||||
|
message.from_user.first_name, message.from_user.last_name,
|
||||||
|
message.from_user.username)
|
||||||
|
# print(f"User added: {message.from_user.id} {message.from_user.first_name} {message.from_user.last_name}")
|
||||||
|
await log(f"User added: {message.from_user.id} {current_user_name}")
|
||||||
|
else:
|
||||||
|
# print(f"User already exists: {message.from_user.id} {message.from_user.first_name} {message.from_user.last_name} {message.from_user.username}")
|
||||||
|
await log(f"User already exists: {message.from_user.id} {current_user_name} {message.from_user.username}")
|
||||||
|
# Проверяем обновление имени пользователя
|
||||||
|
if get_user_name(message.from_user.id) != current_user_name:
|
||||||
|
change_user_name(message.from_user.id, current_user_name)
|
||||||
|
# print(f"User updated: {message.from_user.id} {message.from_user.first_name} {message.from_user.last_name}")
|
||||||
|
await log(f"User name updated: {message.from_user.id} {current_user_name}")
|
||||||
|
# Проверяем обновление username пользователя
|
||||||
|
if get_user_tag(message.from_user.id) != message.from_user.username:
|
||||||
|
change_user_tag(message.from_user.id, message.from_user.username)
|
||||||
|
# print(f"User updated: {message.from_user.id} {message.from_user.username}")
|
||||||
|
await log(f"User tag updated: {message.from_user.id} {message.from_user.username}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
async def add_stats(message: types.Message):
|
||||||
|
# Добавляем пользователю и чату статистику
|
||||||
|
update_chat_all_stat(message.chat.id)
|
||||||
|
update_user_all_stat(message.from_user.id)
|
||||||
|
|
||||||
|
|
||||||
|
async def message_processing(message: types.Message, bot: Bot):
|
||||||
|
await chat_check(message)
|
||||||
|
await user_check(message)
|
||||||
|
await add_stats(message)
|
||||||
|
|
||||||
|
add_message(message)
|
||||||
|
# Если сообщение в начале содержит слово из списка или внутри сообщения содержится слово из списка или сообщение отвечает на сообщение бота
|
||||||
|
|
||||||
|
if ((message.text.split(" ")[0] in get_yandexgpt_start_words())
|
||||||
|
or (any(word in message.text for word in get_yandexgpt_in_words()))):
|
||||||
|
# print("message_processing")
|
||||||
|
await log("message_processing")
|
||||||
|
await answer_to_message(message, bot)
|
||||||
|
|
||||||
|
elif message.reply_to_message is not None:
|
||||||
|
if message.reply_to_message.from_user.is_bot:
|
||||||
|
# print("message_processing")
|
||||||
|
await log("message_processing")
|
||||||
|
await answer_to_message(message, bot)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
router = Router()
|
||||||
|
# Если сообщение содержит текст то вызывается функция message_processing
|
||||||
|
router.message.register(message_processing, F.text)
|
@ -45,69 +45,31 @@ class Moderation:
|
|||||||
async def ban_user(self, chat_id, user_id, bot: aiogram.Bot):
|
async def ban_user(self, chat_id, user_id, bot: aiogram.Bot):
|
||||||
await bot.ban_chat_member(chat_id, user_id)
|
await bot.ban_chat_member(chat_id, user_id)
|
||||||
|
|
||||||
async def mute_user(self, message, chat_id, user_id, bot: aiogram.Bot, time=0):
|
async def mute_user(chat_id, user_id, time, bot: aiogram.Bot):
|
||||||
# Проверка что отправитель является администратором чата
|
mutePermissions = {
|
||||||
# Проверяем мин
|
"can_send_messages": False,
|
||||||
try:
|
"can_send_audios": False,
|
||||||
if check_admin_permission(message.from_user.id):
|
"can_send_documents": False,
|
||||||
# Проверка отвечает ли сообщение на другое сообщение
|
"can_send_photos": False,
|
||||||
if message.reply_to_message is not None:
|
"can_send_videos": False,
|
||||||
time = message.text.split(' ')[1]
|
"can_send_video_notes": False,
|
||||||
# получаем id отправителя сообщение на которое отвечает message
|
"can_send_voice_notes": False,
|
||||||
target_id = message.reply_to_message.from_user.id
|
"can_send_polls": False,
|
||||||
target_name = \
|
"can_send_other_messages": False,
|
||||||
cursor.execute("SELECT user_name FROM user_list WHERE user_id = ?", (target_id,)).fetchone()[0]
|
"can_add_web_page_previews": False,
|
||||||
# Проверка, что человек пользователь
|
"can_change_info": False,
|
||||||
if cursor.execute("SELECT user_role FROM user_list WHERE user_id = ?", (target_id,)).fetchone()[
|
"can_invite_users": False,
|
||||||
0] == 0:
|
"can_pin_messages": False,
|
||||||
# ограничения прав пользователя по отправке сообщений на time секунд
|
"can_manage_topics": False
|
||||||
time_sec = await time_to_seconds(message.text.split(' ')[1])
|
}
|
||||||
if time_sec <= 30 or time_sec >= 31536000:
|
end_time = time + int(time.time())
|
||||||
await message.reply("Время мута должно быть больше 30 секунд и меньше 365 дней")
|
await bot.restrict_chat_member(chat_id, user_id, until_date=end_time, **mutePermissions)
|
||||||
return
|
|
||||||
date_string = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
date_time = datetime.datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
|
async def unmute_user(chat_id, user_id, bot: aiogram.Bot):
|
||||||
unix_time = int(mktime(date_time.timetuple()))
|
await bot.restrict_chat_member(chat_id, user_id, use_independent_chat_permissions=True)
|
||||||
await bot.restrict_chat_member(message.chat.id, target_id, until_date=unix_time + time_sec,
|
|
||||||
permissions=types.ChatPermissions(can_send_messages=False))
|
async def ban_user(chat_id, user_id, bot: aiogram.Bot):
|
||||||
await message.reply(
|
await bot.ban_chat_member(chat_id, user_id)
|
||||||
f"Пользователь {target_name} замьючен на {await short_time_to_time(time)}")
|
|
||||||
else:
|
|
||||||
await message.reply(
|
|
||||||
f"Пользователь [{target_name}](tg://user?id={target_id}) является {await get_role(target_id)} и не может быть замьючен",
|
|
||||||
parse_mode='Markdown')
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
target_tag = message.text.split(' ')[1]
|
|
||||||
target_tag = target_tag[1:]
|
|
||||||
target_id = int(
|
|
||||||
cursor.execute("SELECT user_id FROM user_list WHERE user_name = ?", (target_tag,)).fetchone()[
|
|
||||||
0])
|
|
||||||
target_name = \
|
|
||||||
cursor.execute("SELECT user_name FROM user_list WHERE user_id = ?", (target_id,)).fetchone()[0]
|
|
||||||
# ограничения прав пользователя по отправке сообщений на time секунд
|
|
||||||
time_mute = message.text.split(' ')[2]
|
|
||||||
|
|
||||||
if cursor.execute("SELECT user_role FROM user_list WHERE user_id = ?", (target_id,)).fetchone()[
|
|
||||||
0] == 0:
|
|
||||||
# ограничения прав пользователя по отправке сообщений на time секунд
|
|
||||||
time_sec = await time_to_seconds(message.text.split(' ')[2])
|
|
||||||
if time_sec <= 30 or time_sec >= 31536000:
|
|
||||||
await message.reply("Время мута должно быть больше 30 секунд и меньше 365 дней")
|
|
||||||
return
|
|
||||||
date_string = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
||||||
date_time = datetime.datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
|
|
||||||
unix_time = int(mktime(date_time.timetuple()))
|
|
||||||
await bot.restrict_chat_member(message.chat.id, target_id, until_date=unix_time + time_sec,
|
|
||||||
permissions=types.ChatPermissions(can_send_messages=False))
|
|
||||||
await message.reply(
|
|
||||||
f"Пользователь {target_name} замьючен на {await short_time_to_time(time_mute)}.")
|
|
||||||
else:
|
|
||||||
await message.reply(
|
|
||||||
f"Пользователь [{target_name}](tg://user?id={target_id}) является {await get_role(target_id)} и не может быть замьючен",
|
|
||||||
parse_mode="Markdown")
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
await message.reply("Ошибка данных. Возможно пользователь ещё ничего не написал.")
|
|
||||||
|
|
||||||
|
|
||||||
|
74
src/modules/standard/welcome/handlers.py
Normal file
74
src/modules/standard/welcome/handlers.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
from aiogram import Bot
|
||||||
|
from aiogram.types import Message
|
||||||
|
from src.modules.standard.config.config import get_telegram_check_bot
|
||||||
|
from src.modules.standard.roles.roles import Roles
|
||||||
|
from src.modules.standard.database.db_api import *
|
||||||
|
from src.modules.standard.moderation.moderation import mute_user, unmute_user, ban_user
|
||||||
|
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||||
|
from aiogram.types import inline_keyboard_button as types
|
||||||
|
import random, asyncio
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
|
async def create_math_task():
|
||||||
|
first_number = random.randint(1, 100)
|
||||||
|
second_number = random.randint(1, 100)
|
||||||
|
answer = first_number + second_number
|
||||||
|
fake_answers = []
|
||||||
|
for i in range(3):
|
||||||
|
diff = random.randint(1, 10)
|
||||||
|
diff_sign = random.choice(["+", "-"])
|
||||||
|
fake_answers.append(answer + diff if diff_sign == "+" else answer - diff)
|
||||||
|
fake_answers.append(answer)
|
||||||
|
random.shuffle(fake_answers)
|
||||||
|
return [answer, first_number, second_number, fake_answers]
|
||||||
|
|
||||||
|
async def ban_user_timer(chat_id: int, user_id: int, time: int, bot: Bot):
|
||||||
|
await asyncio.sleep(time)
|
||||||
|
if get_user(user_id) is not None:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
await ban_user()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async def check_new_user(message: Message, bot: Bot):
|
||||||
|
print("check_new_user")
|
||||||
|
if get_telegram_check_bot():
|
||||||
|
# Проверяем наличие пользователя в базе данных
|
||||||
|
|
||||||
|
if get_user(message.from_user.id) is None:
|
||||||
|
# Выдаём пользователю ограничение на отправку сообщений на 3 минуты
|
||||||
|
ban_task = Thread(target=ban_user_timer, args=(message.chat.id, message.from_user.id, 180, bot))
|
||||||
|
ban_task.start()
|
||||||
|
# Создаём задачу с отложенным выполнением на 3 минуты
|
||||||
|
|
||||||
|
math_task = await create_math_task()
|
||||||
|
text = f"{math_task[1]} + {math_task[2]}"
|
||||||
|
builder = InlineKeyboardBuilder()
|
||||||
|
for answer in math_task[3]:
|
||||||
|
if answer == math_task[0]:
|
||||||
|
builder.add(types.InlineKeyboardButton(
|
||||||
|
text=answer,
|
||||||
|
callback_data=f"check_math_task_true")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
builder.add(types.InlineKeyboardButton(
|
||||||
|
text=answer,
|
||||||
|
callback_data=f"check_math_task_false")
|
||||||
|
)
|
||||||
|
await message.reply(
|
||||||
|
f"Приветствую, {message.from_user.first_name}!\n"
|
||||||
|
f"Для продолжения работы с ботом, пожалуйста, решите математический пример в течении 3х минут:\n"
|
||||||
|
f"*{text}*",
|
||||||
|
reply_markup=builder.as_markup()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def math_task_true(message: Message, bot: Bot):
|
||||||
|
await message.reply(f"Верно! Добро пожаловать в чат {message.from_user.first_name}")
|
||||||
|
await unmute_user(message.chat.id, message.from_user.id, bot)
|
||||||
|
add_user(message.from_user.id,
|
||||||
|
message.from_user.first_name + ' ' + message.from_user.last_name,
|
||||||
|
message.from_user.username)
|
||||||
|
pass
|
10
src/modules/standard/welcome/routers.py
Normal file
10
src/modules/standard/welcome/routers.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
from aiogram import Router, F
|
||||||
|
|
||||||
|
from src.modules.standard.welcome.handlers import check_new_user
|
||||||
|
|
||||||
|
router = Router()
|
||||||
|
|
||||||
|
# Если в чат пришел новый пользователь
|
||||||
|
router.message.register(check_new_user, F.new_chat_members.exists())
|
||||||
|
# Ловин колбеки от кнопок с callback_data=f"check_math_task_true"
|
||||||
|
router.callback_query.register(check_new_user, F.callback_data == "check_math_task_true")
|
Loading…
Reference in New Issue
Block a user