telegram / main.py
efswegfwg35's picture
Upload 3 files
086d7f5 verified
Raw
History Blame Contribute Delete
8.1 kB
import asyncio
import logging
import sqlite3
import os
from datetime import datetime
import pytz
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import Command
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.fsm.context import FSMContext
from aiogram.fsm.state import State, StatesGroup
# --- НАСТРОЙКИ ---
# Если запускаешь на ПК, можешь временно заменить os.getenv на свой токен в кавычках
TOKEN = os.getenv("BOT_TOKEN") or "8670682692:AAFM0jiSTY7z30O-PKkUZgj8QSpKX-GwHyo"
ADMIN_ID = 1753037099
CHANNEL_ID = "@TWIXER_MUSIC" # Юзернейм канала с @
CHANNEL_URL = "https://t.me/TWIXER_MUSIC"
MOSCOW_TZ = pytz.timezone('Europe/Moscow')
# --- ИНИЦИАЛИЗАЦИЯ БАЗЫ ДАННЫХ ---
def init_db():
conn = sqlite3.connect('database.db')
cur = conn.cursor()
# Таблица пользователей
cur.execute('''CREATE TABLE IF NOT EXISTS users
(user_id INTEGER PRIMARY KEY, username TEXT, received INTEGER, date TEXT)''')
# Таблица настроек (для ID файла и счетчика)
cur.execute('''CREATE TABLE IF NOT EXISTS settings
(key TEXT PRIMARY KEY, value TEXT)''')
# Установка начального счетчика скачиваний
cur.execute("INSERT OR IGNORE INTO settings (key, value) VALUES ('downloads', '0')")
conn.commit()
conn.close()
def get_setting(key):
conn = sqlite3.connect('database.db')
cur = conn.cursor()
cur.execute("SELECT value FROM settings WHERE key=?", (key,))
res = cur.fetchone()
conn.close()
return res[0] if res else None
def update_setting(key, value):
conn = sqlite3.connect('database.db')
cur = conn.cursor()
cur.execute("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", (key, value))
conn.commit()
conn.close()
def log_user(user_id, username, received):
conn = sqlite3.connect('database.db')
cur = conn.cursor()
now = datetime.now(MOSCOW_TZ).strftime("%d.%m.%Y %H:%M")
cur.execute("INSERT OR REPLACE INTO users VALUES (?, ?, ?, ?)", (user_id, username, received, now))
conn.commit()
conn.close()
def get_all_users():
conn = sqlite3.connect('database.db')
cur = conn.cursor()
cur.execute("SELECT * FROM users")
data = cur.fetchall()
conn.close()
return data
# --- ИНИЦИАЛИЗАЦИЯ БОТА ---
bot = Bot(token=TOKEN)
dp = Dispatcher()
class AdminStates(StatesGroup):
waiting_for_file = State()
# Клавиатура подписки
def get_sub_kb():
return InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="1. Подписаться на TWIXER", url=CHANNEL_URL)],
[InlineKeyboardButton(text="2. Получить Драм Кит", callback_data="check_sub")]
])
# --- ОБРАБОТЧИКИ ---
@dp.message(Command("start"))
async def start_handler(message: types.Message):
await message.answer(
f"Привет, {message.from_user.first_name}!\n"
f"Чтобы получить данный драм кит, нужно быть подписанным на канал TWIXER",
reply_markup=get_sub_kb()
)
@dp.callback_query(F.data == "check_sub")
async def check_sub_callback(callback: types.CallbackQuery):
user_id = callback.from_user.id
try:
# Проверяем статус в канале
chat_member = await bot.get_chat_member(chat_id=CHANNEL_ID, user_id=user_id)
if chat_member.status in ['member', 'administrator', 'creator']:
file_id = get_setting("drum_kit_file_id")
if not file_id:
await callback.message.answer("Админ еще не загрузил файл в бота.")
await callback.answer()
return
# Увеличиваем счетчик
count = int(get_setting("downloads") or 0) + 1
update_setting("downloads", str(count))
# Логируем пользователя
log_user(user_id, callback.from_user.username, 1)
# Отправляем файл
await callback.message.answer_document(
file_id,
caption=f"Драм кит успешно получен!\n\n🔥 Общее количество скачиваний: {count}"
)
await callback.answer("Файл отправлен!")
else:
# Если не подписан
await callback.answer("Вы не подписаны на канал!", show_alert=True)
await callback.message.answer(
"К сожалению вы не подписаны на канал.\n"
"Чтобы получить драм кит, надо быть подписанным на канал!",
reply_markup=get_sub_kb()
)
except Exception as e:
logging.error(e)
await callback.answer("Ошибка! Убедитесь, что бот добавлен в админы канала.", show_alert=True)
# --- АДМИН-КОМАНДЫ ---
@dp.message(Command("admin"))
async def admin_menu(message: types.Message):
if message.from_user.id != ADMIN_ID:
return
text = (
"⚙️ Меню администратора:\n\n"
"/admin - Показать список команд\n"
"/FileDK - Загрузить/изменить файл драм кита\n"
"/Stata - Посмотреть статистику и подписчиков"
)
await message.answer(text)
@dp.message(Command("FileDK"))
async def admin_file_dk(message: types.Message, state: FSMContext):
if message.from_user.id != ADMIN_ID: return
await message.answer("Пришлите файл (документ), который бот будет выдавать пользователям.")
await state.set_state(AdminStates.waiting_for_file)
@dp.message(AdminStates.waiting_for_file, F.document)
async def save_file_id(message: types.Message, state: FSMContext):
file_id = message.document.file_id
update_setting("drum_kit_file_id", file_id)
await message.answer("✅ Файл успешно сохранен! Теперь пользователи будут получать его.")
await state.clear()
@dp.message(Command("Stata"))
async def admin_stata(message: types.Message):
if message.from_user.id != ADMIN_ID: return
users = get_all_users()
if not users:
await message.answer("Статистика пока пуста.")
return
report = "📊 Детальная статистика:\n\n"
for uid, name, received, date in users:
# Проверяем статус подписки в реальном времени
try:
member = await bot.get_chat_member(chat_id=CHANNEL_ID, user_id=uid)
sub_status = "подписан" if member.status in ['member', 'administrator', 'creator'] else "не подписан"
except:
sub_status = "неизвестно (бот заблокирован?)"
rec_status = "получил(-а) файл" if received == 1 else "не получил(-а)"
username = f"@{name}" if name else f"ID: {uid}"
report += f"👤 {username} {sub_status} {rec_status}\n📅 {date}\n\n"
if len(report) > 3800: # Лимит сообщения в ТГ
await message.answer(report)
report = ""
if report:
await message.answer(report)
# --- ЗАПУСК ---
async def main():
init_db()
logging.basicConfig(level=logging.INFO)
print("Бот запущен!")
await dp.start_polling(bot)
if __name__ == "__main__":
try:
asyncio.run(main())
except (KeyboardInterrupt, SystemExit):
logging.info("Бот остановлен")