summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend_api.py5
-rw-r--r--bot.py17
-rw-r--r--keyboards.py4
-rw-r--r--states.py114
-rw-r--r--utils.py1
5 files changed, 139 insertions, 2 deletions
diff --git a/backend_api.py b/backend_api.py
index 951c570..491560f 100644
--- a/backend_api.py
+++ b/backend_api.py
@@ -55,6 +55,11 @@ def register_user(tg_id: int, username: str, fullname: str) -> Tuple[int, Dict]:
})
+def get_profiles():
+ logger.debug(f"Trying to retrieve all profiles")
+ return get_request(f"{BACKEND_URL}/profiles/")
+
+
def get_tasks():
logger.debug(f"Trying to retrieve all tasks")
return get_request(f"{BACKEND_URL}/tasks/")
diff --git a/bot.py b/bot.py
index 86eab31..d9aae67 100644
--- a/bot.py
+++ b/bot.py
@@ -12,7 +12,7 @@ from config import TG_TOKEN, REQUEST_KWARGS
import backend_api
from keyboards import (
MenuKeyboard, TasksKeyboard, TaskChosenKeyboard, ContinueKeyboard,
- AnsweringKeyboard, AdminKeyboard
+ AnsweringKeyboard, AdminKeyboard, BackToMenuKeyboard
)
from utils import *
from states import States, AdminStates
@@ -21,6 +21,8 @@ logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - %(leve
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
+raiseExceptions = True
+
def start(bot: Bot, update: Update, user_data: dict):
user_data.update({"chosen_task": None})
@@ -115,10 +117,23 @@ conversation_handler = ConversationHandler(
ANSWER_RIGHT: [MessageHandler(Filters.text, States.main_menu, pass_user_data=True)],
ANSWER_WRONG: [MessageHandler(Filters.text, States.show_task, pass_user_data=True)],
+ # ADMIN PANEL
+
ADMIN_MENU: [
MessageHandler(Filters.regex(AdminKeyboard.CANCEL), States.main_menu, pass_user_data=True),
MessageHandler(Filters.regex(AdminKeyboard.PUBLISH_TASK), AdminStates.choose_task_publish, pass_user_data=True),
MessageHandler(Filters.regex(AdminKeyboard.HIDE_TASK), AdminStates.choose_task_hide, pass_user_data=True),
+ MessageHandler(Filters.regex(AdminKeyboard.ANNOUNCE), AdminStates.wait_for_announcement, pass_user_data=True),
+ MessageHandler(Filters.regex(AdminKeyboard.MESSAGE_PLAYER), AdminStates.wait_for_message, pass_user_data=True),
+ ],
+
+ ADMIN_WAIT_FOR_ANNOUNCEMENT: [
+ MessageHandler(Filters.regex(BackToMenuKeyboard.CANCEL), AdminStates.admin_panel, pass_user_data=True),
+ MessageHandler(Filters.text, AdminStates.announce_message, pass_user_data=True),
+ ],
+ ADMIN_WAIT_FOR_MESSAGE: [
+ MessageHandler(Filters.regex(BackToMenuKeyboard.CANCEL), AdminStates.admin_panel, pass_user_data=True),
+ MessageHandler(Filters.text, AdminStates.message_plr, pass_user_data=True),
],
ADMIN_TASK_CHOOSE_HIDE: [
diff --git a/keyboards.py b/keyboards.py
index d544059..1d815f4 100644
--- a/keyboards.py
+++ b/keyboards.py
@@ -97,6 +97,8 @@ class AdminKeyboard(Keyboard):
CANCEL = "Вернуться в меню↩️"
PUBLISH_TASK = "Опубликовать задачу"
HIDE_TASK = "Скрыть задачу"
+ ANNOUNCE = "Сделать объявление"
+ MESSAGE_PLAYER = "Написать сообщение от имени бота"
@classmethod
def get_keyboard(cls, telegram_id=None):
@@ -104,4 +106,6 @@ class AdminKeyboard(Keyboard):
[cls.CANCEL],
[cls.PUBLISH_TASK],
[cls.HIDE_TASK],
+ [cls.ANNOUNCE],
+ [cls.MESSAGE_PLAYER],
]
diff --git a/states.py b/states.py
index 94f4fef..9aaa777 100644
--- a/states.py
+++ b/states.py
@@ -2,13 +2,21 @@ from telegram import ReplyKeyboardMarkup, ReplyKeyboardRemove
from keyboards import (
MenuKeyboard, TasksKeyboard, TaskChosenKeyboard, ContinueKeyboard,
- AnsweringKeyboard, AdminKeyboard, PublishTasksKeyboard
+ AnsweringKeyboard, AdminKeyboard, PublishTasksKeyboard, BackToMenuKeyboard
)
from utils import *
import backend_api
+from time import sleep
+import logging
# Typing
from telegram import Update, User, Bot
+from typing import List
+
+
+logger = logging.getLogger(__name__)
+logger.setLevel(logging.DEBUG)
+raiseExceptions = True
def save_state(func):
@@ -288,3 +296,107 @@ class AdminStates:
)
return ADMIN_TASK_PUBLISHED
+
+ @staticmethod
+ @save_state
+ def wait_for_announcement(bot: Bot, update: Update, user_data: dict):
+ update.message.reply_text(
+ "Введите объявление (Отправка сообщений может занять несколько секунд)",
+ reply_markup=ReplyKeyboardMarkup(BackToMenuKeyboard.get_keyboard())
+ )
+
+ return ADMIN_WAIT_FOR_ANNOUNCEMENT
+
+ @staticmethod
+ @save_state
+ def wait_for_message(bot: Bot, update: Update, user_data: dict):
+ update.message.reply_text(
+ "Введите сообщение (Отправка сообщений может занять несколько секунд)",
+ reply_markup=ReplyKeyboardMarkup(BackToMenuKeyboard.get_keyboard())
+ )
+
+ return ADMIN_WAIT_FOR_MESSAGE
+
+ @staticmethod
+ @save_state
+ def announce_message(bot: Bot, update: Update, user_data: dict):
+ status, profiles = backend_api.get_profiles()
+ if status != 200:
+ pass
+ else:
+ ids = []
+ for profile in profiles:
+ ids.append(int(profile["tg_id"]))
+
+ return AdminStates.send_to_ids(ids, update.message.text, bot, update)
+
+ @staticmethod
+ @save_state
+ def message_plr(bot: Bot, update: Update, user_data: dict):
+ text = update.message.text
+ _ = text.split(maxsplit=1)
+
+ if len(_) != 2:
+ update.message.reply_text(
+ "Ошибка в сообщении, попробуйте еще раз",
+ reply_markup=ReplyKeyboardMarkup(ContinueKeyboard.get_keyboard())
+ )
+ return ADMIN_TASK_PUBLISHED
+
+ ids_text, msg = _
+ ids_split = filter(lambda s: len(s) > 0 and s.isnumeric(), ids_text.split(','))
+ ids = list(map(int, ids_split))
+
+ if len(ids) == 0:
+ update.message.reply_text(
+ "Все id пользователей неверно введены",
+ reply_markup=ReplyKeyboardMarkup(ContinueKeyboard.get_keyboard())
+ )
+
+ return ADMIN_TASK_PUBLISHED
+
+ else:
+ return AdminStates.send_to_ids(ids, msg, bot, update)
+
+ @staticmethod
+ def send_to_ids(ids: List[int], message: str, bot: Bot, update: Update):
+ errors = []
+ for tg_id in ids:
+ try:
+ bot.send_message(tg_id, message)
+ print(tg_id)
+ except Exception as e:
+ logger.debug(f"Got exception while announcing message: {e}")
+ errors.append((tg_id, str(e)))
+ sleep(0.3)
+
+ sleep(0.05)
+
+ if len(errors) == 0:
+ update.message.reply_text(
+ "Сообщение успешно отправлено всем пользователям",
+ reply_markup=ReplyKeyboardMarkup(ContinueKeyboard.get_keyboard()),
+ )
+
+ # OKAY
+ return ADMIN_TASK_PUBLISHED
+
+ else:
+ error_msg = []
+ user_ids = []
+
+ for err in errors:
+ user_ids.append(str(err[0]))
+ error_msg.append(f"{err[0]}. Reason: {err[1]}")
+
+ msg = "\n".join(error_msg)
+ user_ids = ",".join(user_ids)
+
+ update.message.reply_text(
+ "Во время отправки сообщений возникли следующие ошибки:\n"
+ f"{msg}\n\n{user_ids}",
+ reply_markup=ReplyKeyboardMarkup(ContinueKeyboard.get_keyboard())
+ )
+
+ # OKAY
+ return ADMIN_TASK_PUBLISHED
diff --git a/utils.py b/utils.py
index 285aea6..473cf9d 100644
--- a/utils.py
+++ b/utils.py
@@ -5,6 +5,7 @@
ANSWER_RIGHT, ANSWER_WRONG,
ADMIN_MENU, ADMIN_TASK_CHOOSE_PUBLISH, ADMIN_TASK_CHOOSE_HIDE,
+ ADMIN_WAIT_FOR_ANNOUNCEMENT, ADMIN_WAIT_FOR_MESSAGE,
ADMIN_TASK_PUBLISHED,
ADMIN_ACCESS_DENIED,
*_