diff --git a/README.md b/README.md index d0b8b85..8378572 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,11 @@ * **!access *all/owner***, **!доступ *владелец/все*** — позволяет в беседе установить уровень доступа к командам *!midnight*, *!subscribe* и *!debug*. *all* - все могут пользоваться. *owner* - только вы. Доступно только вам * **!turnoff, !выкл** — даёт боту команду на выключение. Доступно только вам * **!admin_mode, !админмод** — если чат, в которой активируется команда, является беседой и в ней у бота есть полномочия администратора, то бот переходит в режим модерации. Пока что он может только кикать людей за @all и @online, реагировать на приход/уход участника беседы и дать возможность пользоваться командой *!ban*. Введите ещё раз, чтобы выключить режим модерации. Доступно только вам -* **!ban, !бан *@user*** — банит пользователя из беседы (в смысле выгоняет, юзер не сможет вернутся пока бот или админ не предложит). Требует режим модерации -* **!resist, !запретить *@user*** — запрещает пользователю пользоваться ботом -* **!restore, !разрешить *@user*** — снова разрешает пользователю пользоваться ботом +* **!ban, !бан *@user*** — банит пользователя из беседы (в смысле выгоняет, юзер не сможет вернутся пока бот или админ не предложит). Требует режим модерации, могут воспользоваться только администраторы +* **!resist, !запретить *@user*** — запрещает пользователю пользоваться ботом, могут воспользоваться только администраторы +* **!restore, !разрешить *@user*** — снова разрешает пользователю пользоваться ботом, могут воспользоваться только администраторы +* **!spammer *add* *@user*, !спаммер *добавить* *@user*** — Добавляет пользователя в "базу спаммеров". Если пользователь из этой базы попытается присоединится к беседе, в которой он внесён в эту самую базу, он тут же будет изгнан. Требует режим модерации, могут воспользоваться только администраторы +* **!spammer *remove* *@user*, !спаммер *удалить* *@user*** — Убирает пользователя из "базу спаммеров". Требует режим модерации, могут воспользоваться только администраторы # Установка и запуск бота Лучшим решением будет иметь платный аккаунт на [pythonanywhere](https://www.pythonanywhere.com/) чтобы запускать бота, как Always-on task. Можно, конечно, запускать бота в консоли, но pythonanywhere может выключить вашу консоль, если вы долго не будете посещать её. @@ -45,7 +47,7 @@ Эта команда установит все необходимые библиотеки для работы бота. -Настроим ваше сообщество для работы с ботом: заходим в *Управление -> Работа с API*. Здесь создаём токен сообщества с правами доступа к сообщениям, фотографиям и стене. Идем в *Long Poll API*, включаем его и ставим последнюю доступную версию (на момент написания этой версии README это 5.120). В *Типы событий* должны стоять галочки на следующих событиях: Входящее сообщение, Запрет на получение, Добавление записи на стене. +Настроим ваше сообщество для работы с ботом: заходим в *Управление -> Работа с API*. Здесь создаём токен сообщества с правами доступа к сообщениям, фотографиям и стене. Идем в *Long Poll API*, включаем его и ставим последнюю доступную версию (бот тестировался на версии 5.120). В *Типы событий* должны стоять галочки на следующих событиях: Входящее сообщение, Запрет на получение, Добавление записи на стене. Создадим файл конфигурации для бота: В pythonanywhere тыкаем на *Files*, переходим в директорию *dan63047pythonbot* и создаём там новый фаил с названием `config.py`. В нём должно быть написано следующее: ```python diff --git a/dan63047VKbot.py b/dan63047VKbot.py index 80dd1c5..fe93381 100644 --- a/dan63047VKbot.py +++ b/dan63047VKbot.py @@ -44,7 +44,9 @@ def log(warning, text): bot = {} errors_array = {"access": "Отказано в доступе", - "miss_argument": "Отсуствует аргумент", "command_off": "Команда отключена"} + "miss_argument": "Отсуствует аргумент", + "command_off": "Команда отключена", + "not_a_multichat": "Данный чат не является беседой"} try: vk = vk_api.VkApi(token=config.vk_group_token) @@ -191,15 +193,16 @@ class Database_worker(): if(config.use_database): try: cur = self._CON.cursor() - cur.execute( - f"UPDATE bot_users SET {thing} = %s WHERE bot_users.chat_id = %s;", (new_value, chat_id)) + cur.execute(f"UPDATE bot_users SET {thing} = %s WHERE bot_users.chat_id = %s;", (new_value, chat_id)) self._CON.commit() cur.close() except Exception as e: debug_array['db_warnings'] += 1 - log(True, - f"Unable to update info about user in database: {str(e)}") + log(True, f"Unable to update info about user in database: {str(e)}") else: + if not data['bot-data'].get(thing): + if thing == "spam_list": + self._DATA_DIST['users'][str(chat_id)][thing] = [] self._DATA_DIST['users'][str(chat_id)][thing] = new_value open("data.json", "w").write(json.dumps(self._DATA_DIST)) @@ -301,6 +304,7 @@ class VkBot: """ log(False, f"[BOT_{peer_id}] Created new bot-object") self._CHAT_ID = peer_id + self._SPAMMER_LIST = {} self._AWAITING_INPUT_MODE = awaiting self._ACCESS_TO_ALL = access self._MIDNIGHT_EVENT = midnight @@ -369,10 +373,17 @@ class VkBot: action = event.message.action if action['type'] == 'chat_invite_user' or action['type'] == 'chat_invite_user_by_link': user_info = vk.method('users.get', {'user_ids': action["member_id"], 'fields': 'verified,last_seen,sex'}) + chat_info = db.get_from_users(int(self._CHAT_ID)) + if chat_info.get("spam_list"): + if int(action["member_id"]) in chat_info["spam_list"]: + self.send(f'Привет, {user_info[0]["first_name"]}. К сожалению, администраторы этой беседы признали тебя спамером, поэтому мне придётся выгнать тебя отсюда') + vk.method("messages.removeChatUser", {"chat_id": int(self._CHAT_ID)-2000000000, "member_id": action["member_id"]}) + return self.send(f'Добро пожаловать в беседу, {user_info[0]["first_name"]} {user_info[0]["last_name"]}') elif action['type'] == 'chat_kick_user': - user_info = vk.method('users.get', {'user_ids': action["member_id"], 'fields': 'verified,last_seen,sex'}) - self.send(f'{user_info[0]["first_name"]} {user_info[0]["last_name"]} покинул беседу') + pass + # user_info = vk.method('users.get', {'user_ids': action["member_id"], 'fields': 'verified,last_seen,sex'}) + # self.send(f'{user_info[0]["first_name"]} {user_info[0]["last_name"]} покинул беседу') if self._AWAITING_INPUT_MODE: if message == "Назад": self.change_await() @@ -518,7 +529,7 @@ class VkBot: f"[BOT_{self._CHAT_ID}] can't kick user {victum} - {str(e)}") else: if int(self._CHAT_ID) <= 2000000000: - respond['text'] = "Данный чат не является беседой" + respond['text'] = errors_array["not_a_multichat"] if not self._ADMIN_MODE: respond["text"] = "Бот не в режиме модерирования" else: @@ -554,7 +565,7 @@ class VkBot: elif message[0] == "!admin_mode" or message[0] == "!админмод": if int(self._CHAT_ID) <= 2000000000: - respond['text'] = "Данный чат не является беседой" + respond['text'] = errors_array["not_a_multichat"] elif int(user_id) != int(config.owner_id): respond['text'] = errors_array["access"] else: @@ -626,6 +637,45 @@ class VkBot: else: respond["text"] = errors_array["access"] + elif message[0] == "!spammer" or message[0] == "!спаммер": + if int(self._CHAT_ID) <= 2000000000: + respond['text'] = errors_array["not_a_multichat"] + elif (self._OWNER or int(user_id) in config.admins or int(user_id) == int(config.owner_id)): + try: + message = message[1].split(' ', 1) + victum = re.search(r'id\d+', message[1]) + victum = victum[0][2:] + if db.get_from_users(int(self._CHAT_ID)).get("spam_list"): + chat_spammers_list = db.get_from_users(int(self._CHAT_ID))["spam_list"] + else: + chat_spammers_list = [] + if message[0] == "add" or message [0] == "добавить": + if int(victum) != int(config.owner_id): + if int(victum) not in chat_spammers_list: + chat_spammers_list.append(int(victum)) + respond["text"] = "Теперь он считается спамером" + log(False, f"[BOT_{self._CHAT_ID}] user {victum} added to spammer list") + else: + respond["text"] = "Он и так уже в этой базе" + else: + log(False, f"[BOT_{self._CHAT_ID}] can't add to spammer list owner") + elif message[0] == "remove" or message[0] == "удалить": + if int(victum) != int(config.owner_id): + if int(victum) in chat_spammers_list: + chat_spammers_list.pop(int(victum)) + respond["text"] = "Теперь он не считается спамером" + log(False, f"[BOT_{self._CHAT_ID}] user {victum} removed to spammer list") + else: + respond["text"] = "Его нет в этой базе" + else: + log(False, f"[BOT_{self._CHAT_ID}] can't restore owner") + db.update_user(int(self._CHAT_ID), "spam_list", chat_spammers_list) + except IndexError: + respond['text'] = errors_array["miss_argument"] + except Exception as e: + respond['text'] = f"Ошибка: {str(e)}" + log(True, f"[BOT_{self._CHAT_ID}] spammer action {message[1]} with {victum} - {str(e)}") + if respond['text'] or respond['attachment']: self.send(respond['text'], respond['attachment']) diff --git a/help.txt b/help.txt index a7c645c..e5df20a 100644 --- a/help.txt +++ b/help.txt @@ -27,5 +27,5 @@ !h, !help, !п, !помощь - справка -Дата последнего обновления: 03.04.2022 (Функции по запрету пользования ботом) +Дата последнего обновления: 09.04.2022 (Функции для администрирования беседы) Проект бота на GitHub: https://github.com/dan63047/dan63047pythonbot