kb_bot.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #!env/bin/python
  2. import logging
  3. import asyncio
  4. from aiogram import Bot, Dispatcher, executor, types, utils
  5. from sys import exit
  6. from aiogram.types.chat import Chat
  7. from app.helpers import replacer
  8. from app.messages_templates import message_with_events, start_help_message, cant_create_message
  9. from app.data_provider import check_notifications_now, delete_meeting_and_notifications, get_all_users_meetings
  10. from app.event import handle_event_message
  11. from config.config import BOT_TOKEN
  12. from app.buttons import create_yes_no_btns, events_kb
  13. if not BOT_TOKEN:
  14. exit("Error: no token provided")
  15. try:
  16. bot = Bot(token=BOT_TOKEN, parse_mode=types.message.ParseMode.MARKDOWN_V2)
  17. except utils.exceptions.ValidationError:
  18. exit("Произошла ошибка валидации токена. Возможно, вам нужно указать \
  19. правильный бот токен в переменных окружения.\n=== Завершение программы ===")
  20. dp = Dispatcher(bot)
  21. logging.basicConfig(level=logging.INFO)
  22. async def check_if_user_can_create_event(message: types.Message) -> bool:
  23. """
  24. Проверяет может ли пользователь создавать мероприятия в этом чате
  25. Доступно только в группе и только для админов группы. Возвращает
  26. правду или ложь
  27. """
  28. chat_member = await message.chat.get_member(message.from_user.id)
  29. return True if chat_member.status == "creator" or chat_member.status\
  30. == "administrator" else False
  31. async def get_chat_title(chat_id: int) -> Chat:
  32. return await bot.get_chat(chat_id=chat_id)
  33. async def check_time_and_send_message(sleep_for):
  34. """
  35. Проверяет с определенным промежутком есть ли напоминания в данное время
  36. Делает рассылку напоминаний по чатам, если на это время есть напоминание
  37. """
  38. while True:
  39. await asyncio.sleep(sleep_for)
  40. notifications = check_notifications_now()
  41. for n in notifications:
  42. await bot.send_message(n["chat_id"], n["message"])
  43. @dp.message_handler(commands=["start", "help"])
  44. async def start_help(message: types.Message):
  45. """Обратаывает команды start help. Присылает инструкцию"""
  46. buttons = events_kb if message.from_user.id == message.chat.id else None
  47. await message.reply(
  48. start_help_message.format(bot_username=replacer(bot._me.username)),
  49. reply_markup=buttons)
  50. @dp.message_handler(lambda message: message.text.lower().startswith('встреча+'))
  51. async def event(message: types.Message):
  52. """
  53. Принимает, проверяет команду создания мероприятия. Отпраляет ошибку ввода
  54. или уведомление о созданном мероприятии
  55. """
  56. if not await check_if_user_can_create_event(message):
  57. return await message.answer(cant_create_message)
  58. try:
  59. message_now = handle_event_message(message)
  60. except ValueError as error:
  61. return await message.answer("Ошибка ввода данных: " + error.args[0])
  62. await message.answer(message_now)
  63. @dp.message_handler(
  64. lambda message: message.text == events_kb.keyboard[0][0].text\
  65. and message.from_user.id == message.chat.id)
  66. async def get_my_events(message: types.Message):
  67. """
  68. При запросе в чат с ботом с текстом -Мои мероприятия- или по кнопке
  69. функция отправит сообщение со всеми актуальными встречами, которые
  70. можно отменить
  71. """
  72. meetings = get_all_users_meetings(message.from_user.id)
  73. for i in range(len(meetings)):
  74. chat = await get_chat_title(meetings[i]["chat_id"])
  75. meetings[i]["chat_title"] = chat.title
  76. reply_text = message_with_events(meetings)
  77. try:
  78. await message.reply(reply_text)
  79. except Exception as err:
  80. print("Ошибка при отправке всех ивентов", reply_text, err, type(err))
  81. @dp.message_handler(lambda message: message.text.lower().startswith('/delete_'))
  82. async def delete_event(message: types.Message):
  83. await message.reply(
  84. "Вы уверены, что хотите отменить встречу и удалить напоминания?",
  85. reply_markup=create_yes_no_btns(message.text))
  86. @dp.callback_query_handler(lambda c: c.data == 'cancel')
  87. async def process_callback_cancel(callback_query: types.CallbackQuery):
  88. """Обрабатываем кнопку отмены. Ничего не делаем, просто посылаем ответ"""
  89. await bot.answer_callback_query(
  90. callback_query.id,
  91. text="Ура! Ничего не отменяем")
  92. await bot.delete_message(
  93. chat_id=callback_query.message.chat.id,
  94. message_id=callback_query.message.message_id)
  95. @dp.callback_query_handler(lambda c: c.data and c.data.startswith('/delete_'))
  96. async def process_callback_button2(callback_query: types.CallbackQuery):
  97. """
  98. Обрабатываем кнопку подтверждения удаления
  99. """
  100. user_id = callback_query.from_user.id
  101. meeting_id: int = int(callback_query.data[8:])
  102. await bot.delete_message(
  103. chat_id=callback_query.message.chat.id,
  104. message_id=callback_query.message.message_id)
  105. await bot.answer_callback_query(callback_query.id)
  106. try:
  107. delete_meeting_and_notifications(meeting_id, user_id)
  108. except Exception as error:
  109. return await bot.send_message(user_id, error.args[0])
  110. await bot.send_message(
  111. user_id, f'Встреча и все напоминания о ней были удалены\.')
  112. if __name__ == "__main__":
  113. print(f"Bot has been started...")
  114. loop = asyncio.get_event_loop()
  115. loop.create_task(check_time_and_send_message(60))
  116. executor.start_polling(dp, skip_updates=True)