commit 747f0bf64ba91ab03831d3e12f3056338b6be14b Author: Mootfrost777 Date: Tue Aug 23 18:01:23 2022 +0300 Initial. Слил данные, но там всего один коммит был, тк я ленивая жопа diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e733d04 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +NoVagonBot.session +NoVagonBot.session.save +db.sqlite +.env +venv/ +.idea/ +__pycache__/ +df_key.json diff --git a/db.py b/db.py new file mode 100644 index 0000000..2838ac0 --- /dev/null +++ b/db.py @@ -0,0 +1,57 @@ +import aiosqlite +from enum import Enum, auto + + +class DBAction(Enum): + fetchone = auto() + fetchall = auto() + commit = auto() + + +async def db_action(sql: str, args: tuple, action: DBAction): + """Runs a query on the database""" + conn = await aiosqlite.connect('db.sqlite') + cursor = await conn.cursor() + + await cursor.execute(sql, args) + if action == DBAction.fetchone: + result = await cursor.fetchone() + elif action == DBAction.fetchall: + result = await cursor.fetchall() + elif action == DBAction.commit: + conn.commit() + result = cursor.lastrowid + + await cursor.close() + await conn.close() + + return result + + +async def create_table(): + """Creates a table in the database""" + conn = await aiosqlite.connect('db.sqlite') + cursor = await conn.cursor() + + await cursor.execute('''CREATE TABLE IF NOT EXISTS chats ( + id INTEGER PRIMARY KEY, + chat_id INTEGER NOT NULL + )''') + + await cursor.execute("""CREATE TABLE IF NOT EXISTS user_exceptions ( + id INTEGER PRIMARY KEY, + user_id INTEGER NOT NULL, + chat_id INTEGER NOT NULL, + FOREIGN KEY(chat_id) REFERENCES chats(chat_id) + )""") + + await cursor.execute("""CREATE TABLE IF NOT EXISTS banned_stickerpacks ( + id INTEGER PRIMARY KEY, + pack_id INTEGER NOT NULL, + chat_id INTEGER NOT NULL, + FOREIGN KEY(chat_id) REFERENCES chats(chat_id) + )""") + + await cursor.close() + await conn.close() + diff --git a/df_utils.py b/df_utils.py new file mode 100644 index 0000000..cd7ed97 --- /dev/null +++ b/df_utils.py @@ -0,0 +1,20 @@ +from google.cloud import dialogflow_v2beta1 as dialogflow + +from dotenv import load_dotenv + +load_dotenv() + + +async def detect_intent_text(project_id, session_id, text, language_code): + session_client = dialogflow.SessionsClient() + session = session_client.session_path(project_id, session_id) + + text_input = dialogflow.types.TextInput(text=text, language_code=language_code) + query_input = dialogflow.types.QueryInput(text=text_input) + + response = session_client.detect_intent(session=session, query_input=query_input) + + if response.query_result.intent.is_fallback: + return None + else: + return response.query_result.fulfillment_text diff --git a/main.py b/main.py new file mode 100644 index 0000000..a500544 --- /dev/null +++ b/main.py @@ -0,0 +1,125 @@ +from telethon import TelegramClient, events +from telethon.tl.types import ChannelParticipantsAdmins, DocumentAttributeSticker +from datetime import timedelta + +from db import DBAction, db_action, create_table +from df_utils import detect_intent_text + +import random +import asyncio + +import os +from dotenv import load_dotenv + + +bot = TelegramClient(os.environ['SESSION_NAME'], int(os.environ['API_ID']), + os.environ['API_HASH']).start(bot_token=os.environ['BOT_TOKEN']) + +load_dotenv() +asyncio.get_event_loop().run_until_complete(create_table()) + + +async def check_admin(msg): + if not any([user.id == msg.sender_id async for user in bot.iter_participants(msg.chat_id, + filter=ChannelParticipantsAdmins)]): + await msg.reply('Эту команду может только администратор использовать') + raise events.StopPropagation + + +@bot.on(events.NewMessage()) +async def on_message(msg): + chats = await db_action('SELECT chat_id FROM chats', (), DBAction.fetchall) + if msg.chat_id not in chats: + await db_action('INSERT INTO chats (chat_id) VALUES (?)', (msg.chat_id,), DBAction.commit) + + +async def check_user_in_exceptions(user_id, chat_id): + """Checks if a user is in the exceptions list""" + return db_action('SELECT id FROM user_exceptions WHERE user_id = ? AND chat_id = ?', (user_id, chat_id), + DBAction.fetchone) is not None + + +@bot.on(events.NewMessage(pattern='/exception')) +async def on_exception(msg): + await check_admin(msg) + + args = msg.message.text.split(' ') + if len(args) < 4: + await msg.reply('Неверный формат') + raise events.StopPropagation + + if args[2]: + if args[2] == 'me': + user_id = msg.sender_id + else: + user_id = args[2] + elif msg.reply_to_message: + user_id = msg.reply_to_message.sender_id + else: + await msg.reply('Допиши к команде айди пользователя, "me", чтобы добавить себя, или ответь командой на сообщение нужного пользователя') + raise events.StopPropagation + + match args[1]: + case 'add': + if await check_user_in_exceptions(user_id, msg.chat_id): + await msg.reply('Пользователь уже есть в списке исключений') + raise events.StopPropagation + + await db_action('INSERT INTO user_exceptions (user_id) VALUES (?)', (user_id,), DBAction.commit) + await msg.reply('Пользователь добавлен в исключения, теперь его сообщения не будут проверяться ботом') + case 'remove': + if not await check_user_in_exceptions(user_id, msg.chat_id): + await msg.reply('Пользователя пока нет в исключениях') + raise events.StopPropagation + + await db_action('DELETE FROM user_exceptions WHERE user_id = ?', (user_id,), DBAction.commit) + await msg.reply('Пользователь удален из списка исключений') + + +@bot.on(events.NewMessage(pattern='/addstickerpack')) +async def add_stickerpack(msg): + await check_admin(msg) + + args = msg.text.split() + if args[1]: + stickerpack_id = args[1] + elif msg.reply_to_message.sticker: + for attr in msg.sticker.attributes: + if isinstance(attr, DocumentAttributeSticker): + stickerpack_id = attr.stickerset.id + break + else: + msg.reply('Допиши к команде айди набора стикеров или ответь командой на стикер из набора') + raise events.StopPropagation + + if await db_action("SELECT * FROM banned_stickerpacks WHERE pack_id = ? AND chat_id = ?", + (stickerpack_id, msg.chat_id,), DBAction.fetchone) is None: + await db_action("INSERT INTO banned_stickerpacks (pack_id, chat_id) VALUES (?, ?)", + (stickerpack_id, msg.chat_id,), DBAction.commit) + await msg.reply(f"Стикерпак с айди {msg.text.split(' ')[1]} добавлен в банлист") + else: + await msg.reply(f"Стикерпак с айди {msg.text.split(' ')[1]} уже в банлисте") + + raise events.StopPropagation + + +async def on_banword(msg): + await bot.edit_permissions(msg.chat_id, msg.sender_id, timedelta(minutes=5), send_messages=False) + await msg.reply(random.choice(['Харе про вагоны писать', 'Надоел уже со своими номерными', 'Никаких вагонов тут нет'])) + + +@bot.on(events.NewMessage()) +async def handler(msg): + if msg.is_private: + await msg.respond('Hello! Add me to a group to start using me!') + return + + await msg.reply(await detect_intent_text(os.environ['GOOGLE_PROJECT_ID'], msg.chat_id, msg.raw_text, 'ru')) + + banstickerpacks = [stickerpack[0] for stickerpack in db_action('SELECT pack_id FROM banned_stickerpacks', (), DBAction.fetchall)] + + if msg.sticker and any([x.stickerset.id in banstickerpacks for x in msg.sticker.attributes if isinstance(x, DocumentAttributeSticker)]): + await on_banword(msg) + + +bot.run_until_disconnected() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..46eec51 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +telethon +pymorphy2 +pyenchant +google-cloud-dialogflow +python-dotenv \ No newline at end of file