diff --git a/.gitignore b/.gitignore index f21f1b3..0710587 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,20 @@ +# Ignore everything * -!.gitignore +# Except these files +!.gitignore !docker-compose.yaml !requirements.txt +!readme.md +# Except these directories and their contents !/app -!app/* - +!/app/* !/app/plugin -!app/plugin/* +!/app/plugin/* +# Ignore specific files and directories app/bot.py - __pycache__/ -.env \ No newline at end of file +.env +.venv \ No newline at end of file diff --git a/app/config.py b/app/config.py index 29e5ced..149b5ca 100644 --- a/app/config.py +++ b/app/config.py @@ -34,8 +34,11 @@ class Messages: "Привет! Это бот Quick dates (Random Coffee). Чтобы зарегистрироваться, пожалуйста, ответь на следующие вопросы." # несколько сообщений подряд ] HELPS = [ - "Доступные команды:" "\n/start - начать регистрацию" "n/help - помощь", - "Начало мероприятия: {} \nЭто через целых {} минут!", + "Доступные команды:" "\n/start - начать регистрацию", + "\n/help - помощь", + "\n/source - исходный код бота на Github", + "\n\nCreated by АйТи блок ВМК with love ❤️", + # "Начало мероприятия: {} \nЭто через целых {} минут!", ] ERROR = "Произошла ошибка" @@ -57,3 +60,4 @@ class Messages: MATCHING_START = ( "Мы начали подбор пар. Пожалуйста, подтверди, что ты находишься в аудитории" ) + START_DATE = f"Наше мероприятие начнётся {os.environ.get('DATE_START')} следите за новостями!" diff --git a/app/main.py b/app/main.py index 07d256d..4ac22b6 100644 --- a/app/main.py +++ b/app/main.py @@ -71,6 +71,17 @@ def help_message(message: types.Message): return +@bot.message_handler(commands=BotCommands.Source) +def source(message: types.Message): + bot.send_message( + message.chat.id, + "[Страничка бота на Github!](https://github.com/kr0sh512/rc-tgbot)", + parse_mode="Markdown", + ) + + return + + if __name__ == "__main__": print("/t--- Bot started ---") diff --git a/app/plugin/admin.py b/app/plugin/admin.py index ebca9a6..0b67754 100644 --- a/app/plugin/admin.py +++ b/app/plugin/admin.py @@ -115,7 +115,7 @@ class Admin: return wrapper - @bot.message_handler(commands=["admin"]) + @bot.message_handler(commands=["admin_reg"]) def add_admin_command(message): bot.send_message(message.chat.id, "Введите unique_key") bot.register_next_step_handler(message, Admin.add_admin_step) @@ -346,7 +346,7 @@ class AdminMessages: ADMIN_HELP = ( "Вы администратор! Вот что вы можете сделать:\n" "/remove_admin - удалить админа\n" - "/generate_key - сгенерировать уникальный ключ\n" + "/generate_key - сгенерировать уникальный ключ (admin_red - чтобы админ добавился)\n" "/delete_user - удалить пользователя\n" "/stats - статистика\n" "/send_message - отправить всем сообщение\n" diff --git a/app/plugin/bot_instance.py b/app/plugin/bot_instance.py index 5e12998..b610734 100644 --- a/app/plugin/bot_instance.py +++ b/app/plugin/bot_instance.py @@ -1,13 +1,34 @@ import telebot from config import config import threading +import time class BotCommands: Start = ["start", "s"] - Help = ["help", "h"] + Help = ["help", "h", "помощь"] + Source = ["source"] +original_send_message = telebot.TeleBot.send_message + + +def send_message_with_try_catch(self, chat_id, text, *args, **kwargs): + try: + return original_send_message(self, chat_id, text, *args, **kwargs) + except Exception as e: + print(f"Error sending message: {e}. Retrying in 5 seconds...") + + try: + time.sleep(5) + + return original_send_message(self, chat_id, text, *args, **kwargs) + except Exception as e: + print(f"Second attempt failed: {e}") + + +telebot.TeleBot.send_message = send_message_with_try_catch + bot = telebot.TeleBot( config.API_TOKEN, colorful_logs=True, diff --git a/app/plugin/register.py b/app/plugin/register.py index 404c1d3..ff8f1dd 100644 --- a/app/plugin/register.py +++ b/app/plugin/register.py @@ -176,10 +176,12 @@ def show_result(message: types.Message): message.chat.id, open(image_path, "rb"), caption=text, + show_caption_above_media=True, ) else: print("Image not found") bot.send_message(message.chat.id, TestMessages.TEST_FINISH) + bot.send_message(message.chat.id, Messages.START_DATE) return diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..bda1016 --- /dev/null +++ b/readme.md @@ -0,0 +1,64 @@ +# Бот Random Coffe для Telegram + +Бот реализован с помощью библиотеки [pyTelegramBotAPI](https://pypi.org/project/pyTelegramBotAPI/) и базы данных [MongoDB](https://www.mongodb.com/) + +## Запуск + +1. Создать [файл .env](#env) в директории `app` +2. Запустить контейнеры с помощью docker compose: + - `docker-compose up -d` + +Без контейнеров: + +1. Установка нужных модулей + - `pip3 install -r app/requirements.txt` +2. Запуск скрипта: + - `(cd ./app && python3 main.py)` + +## Функционал + +1. Регистрация участников с мини-тестом для определения типа личности +2. Генерация пар для рассадки людей по: + 1. М+Ж по MBTI + 2. М+Ж + 3. одного возраста + 4. всех остальных +3. Возможность уведомлять всех пользователей +4. Поддержка нескольких администраторов +5. Отправка за день уведомления о начале мероприятия + +## Команды + +### Пользователи + +- Вначале пользователям предоставляется небольшая регистрация после `/start` +- Довольно бесполезный `/help` +- Исходный код на Github `/source` + +### Администраторы + +- `/generate_key` - создание уникального ключа для добавления новых админов +- `/admin_reg` - добавиться в админы (с последующим вводом unique_key) +- `/stats` - получить информацию о пользователях +- `/delete_user` - удалить пользователя по id +- `/send_message` - сделать массовую рассылку всем зарегестрированным пользователям +- `/random` - запустить рассылку для регистрации на первый тур +- `/random_again` - сгенерировать повторную рассадку для людей первого тура (без повторной регистрации) +- `/clear_all` - удалить всех людей из базы данных +- `/remove_admin` - удалить админа по id + +## Настройка конфигурации + +Необходимые поля в `.env` файле: + +- `DATE_START` в формате `%Y-%m-%d` +- `TIME_START` в формате `%HH-%MM` +- `API_TOKEN` - токен для tg бота полученный у `@BotFather` +- `ADMIN_ID` - id **_главного админа_** +- `DB_PORT` порт для MongoDB, стандартно `27017` +- `ENV` - если выставлен как `dev`: + - возможность подключаться к базе данных удалённо через SSH + - `SSH_HOST` - имя/ip хоста + - `SSH_USER` - имя пользователя + - `SSH_KEY` - расположение ключа (может быть не указан если есть `SSH_PASSWORD`) + - `SSH_PASSWORD` - пароль порльзователя (может быть не указан если есть `SSH_KEY`)