mrsk_bot/bot.py
2025-10-02 21:11:22 +03:00

134 lines
4.7 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio
import logging
import os
from pathlib import Path
import pytz
from datetime import datetime
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher.filters import Text
from dotenv import load_dotenv
from main import start_parser
load_dotenv()
logging.basicConfig(
level=logging.INFO,
filename="logs/bot.log",
format="%(asctime)s - %(module)s - %(levelname)s - %(funcName)s: %(lineno)d - %(message)s",
datefmt='%H:%M:%S',
)
logger = logging.getLogger(__name__)
BOT_TOKEN = os.getenv("BOT_TOKEN")
WEBHOOK_URL = os.getenv("WEBHOOK_URL")
if not BOT_TOKEN:
raise ValueError("❌ Переменная BOT_TOKEN не задана в .env")
if not WEBHOOK_URL:
raise ValueError("❌ Переменная WEBHOOK_URL не задана в .env")
TZ = pytz.timezone('Europe/Moscow')
USER_LOG = Path("logs/users.log")
UPDATE_INTERVAL = 300 # 5 минут
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher(bot)
async def periodic_update():
while True:
logger.info("Запуск автоматического обновления данных...")
try:
start_parser()
logger.info("Автоматическое обновление завершено")
except Exception as e:
logger.error(f"Ошибка при автоматическом обновлении: {e}")
await asyncio.sleep(UPDATE_INTERVAL)
@dp.message_handler(commands='start')
async def cmd_start(message: types.Message):
buttons = ['Плановые', 'Внерегламентные', 'Аварийные', 'Информация']
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
keyboard.add(*buttons)
await message.answer('Выберите тип отключений:', reply_markup=keyboard)
async def send_file_content(message: types.Message, file_path: Path, empty_msg: str, log_msg: str):
await message.answer("Обновляю...")
if not file_path.exists() or file_path.stat().st_size == 0:
await message.answer(empty_msg)
else:
text = file_path.read_text(encoding='utf-8')
if len(text) > 4095:
for i in range(0, len(text), 4095):
await message.answer(text[i:i + 4095])
else:
await message.answer(text)
now = datetime.now(TZ).strftime('%d/%m/%Y %H:%M')
username = message.from_user.username or f"id{message.from_user.id}"
log_entry = f"{now} t.me/{username} получил инфу по {log_msg}.\n"
USER_LOG.parent.mkdir(exist_ok=True)
with USER_LOG.open('a', encoding='utf-8') as f:
f.write(log_entry)
logger.info(f"Пользователь {username} запросил {log_msg}")
@dp.message_handler(Text(equals='Плановые'))
async def plan(message: types.Message):
await send_file_content(
message,
Path("plan.txt"),
"[Нет плановых отключений]",
"плановым отключениям"
)
@dp.message_handler(Text(equals='Внерегламентные'))
async def vnereglament(message: types.Message):
await send_file_content(
message,
Path("vnereglament.txt"),
"[Нет внерегламентных отключений]",
"внерегламентным отключениям"
)
@dp.message_handler(Text(equals='Аварийные'))
async def avar(message: types.Message):
await send_file_content(
message,
Path("avar.txt"),
"[Нет аварийных отключений]",
"аварийным отключениям"
)
@dp.message_handler(Text(equals='Информация'))
async def info(message: types.Message):
await message.answer(
" Информация МРСК Белгород по отключениям эл-ва (v2)\n\n"
"✅ Данные обновляются автоматически каждые 5 минут.\n"
"📩 Вопросы и предложения: @pikusQQ"
)
@dp.message_handler()
async def fallback(message: types.Message):
await message.answer("Нажмите /start для начала работы.")
async def on_startup(dp):
await bot.set_webhook(WEBHOOK_URL)
asyncio.create_task(periodic_update())
logger.info(f"Webhook установлен на {WEBHOOK_URL}. Фоновое обновление запущено.")
async def on_shutdown(dp):
await bot.delete_webhook()
logger.info("Webhook удалён")
if __name__ == '__main__':
executor.start_webhook(
dispatcher=dp,
webhook_path='',
on_startup=on_startup,
on_shutdown=on_shutdown,
skip_updates=True,
host='0.0.0.0',
port=5000,
)