owen-tg/main.py
2025-02-20 15:12:49 +03:00

204 lines
7.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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.

#!/usr/bin/env python
import logging
import os
import json
from datetime import datetime
from typing import Dict
from dotenv import load_dotenv
from telegram import ReplyKeyboardMarkup, KeyboardButton, Update
from telegram.constants import ParseMode
from telegram.ext import (
Application,
CommandHandler,
ContextTypes,
MessageHandler,
filters,
CallbackContext,
)
# Загружаем переменные окружения
load_dotenv()
TOKEN = os.getenv("TOKEN")
ADMIN_ID = int(os.getenv("ADMIN_ID", "0"))
PASSWORD = os.getenv("PASSWORD", "supersecret")
USERS_FILE = "users.json" # Файл для хранения пользователей
# Логирование
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
)
logger = logging.getLogger(__name__)
def load_users() -> Dict[str, Dict]:
"""Загружает список авторизованных пользователей из JSON."""
if os.path.exists(USERS_FILE):
try:
with open(USERS_FILE, "r", encoding="utf-8") as file:
return json.load(file)
except Exception as e:
logger.error(f"Ошибка загрузки users.json: {e}")
return {}
def save_users(users: Dict[str, Dict]) -> None:
"""Сохраняет список авторизованных пользователей в JSON."""
try:
with open(USERS_FILE, "w", encoding="utf-8") as file:
json.dump(users, file, indent=4, ensure_ascii=False)
except Exception as e:
logger.error(f"Ошибка сохранения users.json: {e}")
def get_main_menu() -> ReplyKeyboardMarkup:
"""Создаёт Reply-клавиатуру для авторизованных пользователей."""
keyboard = [
[KeyboardButton("⚙️ Частота вращения"), KeyboardButton("📩 Тест")],
]
return ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
async def start(update: Update, context: CallbackContext) -> None:
"""Команда /start — Проверка JSON перед авторизацией."""
user_id = str(update.effective_user.id)
users = load_users()
if user_id in users:
await update.message.reply_text(
"✅ Вы уже авторизованы! Выберите действие:",
reply_markup=get_main_menu(),
)
else:
await update.message.reply_text(
"🚫 Вы не авторизованы. Используйте /password <пароль>."
)
async def handle_buttons(update: Update, context: CallbackContext) -> None:
"""Обработчик текстовых кнопок."""
user_id = str(update.effective_user.id)
users = load_users()
if user_id not in users:
await update.message.reply_text("🚫 Вы не авторизованы.")
return
text = update.message.text
if text == "⚙️ Частота вращения":
await update.message.reply_text("⚙️ Частота вращения: 1500 об/мин")
elif text == "📩 Тест":
await update.message.reply_text("✅ Это тестовое сообщение!")
async def password(update: Update, context: CallbackContext) -> None:
"""Команда /password <пароль> — Авторизация пользователя."""
user_id = str(update.effective_user.id)
users = load_users()
if user_id in users:
await update.message.reply_text("✅ Вы уже авторизованы!")
return
if len(context.args) != 1:
await update.message.reply_text("❌ Используйте: /password <пароль>")
return
if context.args[0] == PASSWORD:
first_name = update.effective_user.first_name
last_name = update.effective_user.last_name or ""
registered_at = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
users[user_id] = {
"id": user_id,
"first_name": first_name,
"last_name": last_name,
"registered_at": registered_at,
}
save_users(users) # Сохраняем в файл
await update.message.reply_text(
f"{first_name}, вы авторизованы!", reply_markup=get_main_menu()
)
# Уведомляем администратора о новом пользователе
if ADMIN_ID:
try:
await context.bot.send_message(
ADMIN_ID,
f"🔔 Новый пользователь авторизовался:\n"
f"👤 {first_name} {last_name}\n"
f"🆔 ID: {user_id}\n"
f"📅 Дата регистрации: {registered_at}"
)
except Exception as e:
logger.error(f"Ошибка отправки админу: {e}")
else:
await update.message.reply_text("❌ Неверный пароль.")
async def print_users(update: Update, context: CallbackContext) -> None:
"""Команда /print_users — Показывает список авторизованных пользователей."""
user_id = str(update.effective_user.id)
users = load_users()
if user_id != str(ADMIN_ID):
await update.message.reply_text("У вас нет доступа к этой команде.")
return
if not users:
await update.message.reply_text("Нет авторизованных пользователей.")
return
users_text = "📜 <b>Список авторизованных пользователей:</b>\n\n"
for user in users.values():
users_text += (
f"👤 <b>{user['first_name']} {user['last_name']}</b>\n"
f"🆔 ID: {user['id']}\n"
f"📅 Дата регистрации: {user['registered_at']}\n"
f"——————————\n"
)
await update.message.reply_text(users_text, parse_mode=ParseMode.HTML)
async def help_command(update: Update, context: CallbackContext) -> None:
"""Команда /help — выводит список команд."""
help_text = (
"🛠 <b>Доступные команды:</b>\n\n"
"/start - Начать работу с ботом\n"
"/password <пароль> - Авторизоваться\n"
"/print_users - Список пользователей (только для админа)\n"
"/help - Справка по командам\n\n"
"⚙️ Также доступны кнопки с действиями!"
)
await update.message.reply_text(help_text, parse_mode=ParseMode.HTML)
def main() -> None:
"""Запуск бота."""
if not TOKEN:
logger.error("Не задан токен!")
return
application = Application.builder().token(TOKEN).build()
# Добавление команд
application.add_handler(CommandHandler("start", start))
application.add_handler(CommandHandler("password", password))
application.add_handler(CommandHandler("print_users", print_users))
application.add_handler(CommandHandler("help", help_command))
# Обработка нажатий кнопок
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_buttons))
logger.info("🤖 Бот запущен...")
application.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()