Merge branch 'main' into security
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2025-09-07 14:22:04 +09:00
16 changed files with 1051 additions and 133 deletions

72
main.py
View File

@@ -21,22 +21,46 @@ logging.getLogger("httpx").setLevel(logging.WARNING)
logger = logging.getLogger(__name__)
import asyncio
from telegram.ext import CommandHandler
from sqlalchemy import select
from datetime import datetime
from db import AsyncSessionLocal
from models import ChannelAccess
from handlers.permissions import get_or_create_admin, token_hash
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
session = AsyncSessionLocal()
user_id = update.effective_user.id if update.effective_user else None
result = await session.execute(Admin.__table__.select().where(Admin.tg_id == user_id))
admin = result.first() if user_id else None
if not admin and user_id:
await session.execute(Admin.__table__.insert().values(tg_id=user_id))
await session.commit()
if update.message:
await update.message.reply_text('Вы зарегистрированы как админ.')
else:
if update.message:
await update.message.reply_text('Вы уже зарегистрированы.')
await session.close()
args = (context.args or [])
if args and args[0].startswith("sch_"):
# формат: sch_<invite_id>_<token>
try:
_, sid, token = args[0].split("_", 2)
invite_id = int(sid)
except Exception:
await update.message.reply_text("Неверная ссылка приглашения.")
return
async with AsyncSessionLocal() as session:
me = await get_or_create_admin(session, update.effective_user.id)
res = await session.execute(select(ChannelAccess).where(ChannelAccess.id == invite_id))
acc = res.scalar_one_or_none()
if not acc or acc.status != "pending":
await update.message.reply_text("Приглашение не найдено или уже активировано/отозвано.")
return
if acc.expires_at and acc.expires_at < datetime.utcnow():
await update.message.reply_text("Срок действия приглашения истёк.")
return
if token_hash(token) != acc.token_hash:
await update.message.reply_text("Неверный токен приглашения.")
return
acc.invited_admin_id = me.id
acc.accepted_at = datetime.utcnow()
acc.status = "active"
await session.commit()
await update.message.reply_text("Доступ к каналу успешно активирован. Можно постить через /new_post.")
return
async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
help_text = (
@@ -75,6 +99,18 @@ from handlers.group_buttons import group_buttons_conv
from handlers.channel_buttons import channel_buttons_conv
from handlers.edit_button import edit_button
from handlers.del_button import del_button
from handlers.share_channel import share_channel_conv
import logging
from telegram.error import BadRequest
logger = logging.getLogger(__name__)
async def on_error(update: Update, context: ContextTypes.DEFAULT_TYPE):
err = context.error
# подавляем шумные 400-е, когда контент/markup не меняется
if isinstance(err, BadRequest) and "Message is not modified" in str(err):
return
logger.exception("Unhandled exception", exc_info=err)
@@ -82,7 +118,7 @@ def main():
if not TELEGRAM_TOKEN:
print("Ошибка: TELEGRAM_TOKEN не найден в переменных окружения.")
return
sync_to_async(init_db())
# sync_to_async(init_db())
application = Application.builder().token(TELEGRAM_TOKEN).build()
application.add_handler(CommandHandler('start', start))
application.add_handler(CommandHandler('help', help_command))
@@ -95,8 +131,12 @@ def main():
application.add_handler(CommandHandler('edit_button', edit_button))
application.add_handler(CommandHandler('del_button', del_button))
application.add_handler(admin_panel_conv)
<<<<<<< HEAD
application.add_handler(share_bot_handler)
application.add_handler(invite_admin_handler)
=======
application.add_handler(share_channel_conv)
>>>>>>> main
import sys
import asyncio
if sys.platform.startswith('win'):
@@ -107,7 +147,7 @@ def main():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
application.run_polling()
if __name__ == "__main__":
main()