Задать вопрос
@Alwex0920

Не работает inline кнопка telebot?

При нажатии на кнопку ничего не происходит, а раньше всё работало.
вот код
def show_subscription_options(chat_id):
    USER_ID = chat_id  # Получаем user_id из chat_id
    markup = types.InlineKeyboardMarkup()

    # Кнопки для выбора тарифа
    for period, price in prices.items():
        btn = types.InlineKeyboardButton(text=f"{period.capitalize()} - {price}₽", callback_data=period)
        markup.add(btn)

    # Кнопка пробного периода только если можно активировать
    if can_activate_trial(USER_ID):
        trial_btn = types.InlineKeyboardButton(
            text="Активировать пробный период", 
            callback_data="activate_trial"
        )
        markup.add(trial_btn)
    else:
        bot.send_message(chat_id, "⚠️ Пробный период уже был использован")

    bot.send_message(chat_id, "Выберите тариф:", reply_markup=markup)

@bot.callback_query_handler(func=lambda call: call.data == "activate_trial")
def func_activate_trial(call):
    print("[DEBUG]: Кнопка activated_trial нажата!")
    try:
        USER_ID = call.from_user.id
        
        print(f"[DEBUG]: Активация пробного периода для {USER_ID}")
        bot.send_message(USER_ID, "Загрузка...")
        
        if not can_activate_trial(USER_ID):
            bot.send_message(USER_ID, "❌ Пробный период уже был активирован")
            return
            
        # Сбрасываем данные и активируем
        trial_data[USER_ID] = {
            'questions': 0,
            'symbols': 0,
            TRIAL_ACTIVATED_FLAG: True
        }
        trial_data.save_to_disk()
        
        bot.send_message(USER_ID, "✅ Пробный период активирован! Доступно: 10 вопросов / 10 000 символов")
        
        # Обновляем интерфейс
        bot.edit_message_reply_markup(
            chat_id=call.message.chat.id,
            message_id=call.message.message_id,
            reply_markup=None
        )
        
    except Exception as e:
        print(f"Ошибка активации: {str(e)}")
        bot.answer_callback_query(call.id, "❌ Ошибка активации", show_alert=True)

def can_activate_trial(user_id):
    data = trial_data[user_id]
    # Можно активировать только если не активирован ИЛИ активирован но не использован
    return not data[TRIAL_ACTIVATED_FLAG] or \
           (data[TRIAL_ACTIVATED_FLAG] and not is_trial_active(user_id))
  • Вопрос задан
  • 102 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
@eminsk
программирую на python
Я пробывал в твоем коде через telebot и да тоже не реагирует не как и я тебе переделал на aiogram и все заработало.
Ну а дальше уже сам реализовывай все остальные свои задачи.
Работоспособность проверялась на последней версии на дату публикации python 3.13
from __future__ import annotations
import logging
import os
import shelve
from datetime import datetime, timedelta
from pathlib import Path

from aiogram import Bot, Dispatcher, F
from aiogram.types import Message, CallbackQuery, InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.filters import Command
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.fsm.storage.memory import MemoryStorage
from aiogram.client.default import DefaultBotProperties

# Configure logging
logging.basicConfig(level=logging.INFO)

# Constants
TRIAL_FLAG = "active"

class UltraLiteSubBot:
    __slots__ = ("_bot", "_dp", "_prices", "_db", "_cmd_map", "_cb_map")
    def __init__(self, token: str, prices: dict[str, int], db: shelve.DbfilenameShelf):
        self._bot = Bot(token=token, default=DefaultBotProperties(parse_mode="HTML"))
        self._dp = Dispatcher(storage=MemoryStorage())
        self._prices = prices
        self._db = db
        self._cmd_map = {
            "start": self._show,
            "help": self._help
        }
        
        self._cb_map = {
            **{plan: self._plan(plan) for plan in prices},
            "activate": self._activate
        }
        self._register_handlers()

    def _register_handlers(self) -> None:
        self._dp.message.register(self._show, Command("start"))
        self._dp.message.register(self._help, Command("help"))
        self._dp.message.register(self._unknown)
        for plan in self._prices:
            self._dp.callback_query.register(self._plan(plan), F.data == plan)
        self._dp.callback_query.register(self._activate, F.data == "activate")
        self._dp.callback_query.register(self._unknown_callback)

    async def run(self) -> None:
        await self._bot.set_my_commands([
            {"command": "start", "description": "Выбрать тариф"},
            {"command": "help", "description": "Справка"}
        ])
        await self._dp.start_polling(self._bot)
    async def _show(self, msg: Message) -> None:
        uid = msg.chat.id
        builder = InlineKeyboardBuilder()
        for plan, price in self._prices.items():
            builder.button(text=f"{plan.title()} — {price}₽", callback_data=plan)
        if await self._trial_ok(uid):
            builder.button(text="Активировать пробный период", callback_data="activate")
        builder.adjust(1)
        await msg.answer("Выберите тариф:", reply_markup=builder.as_markup())

    async def _help(self, msg: Message) -> None:
        await msg.answer("/start — выбрать тариф\n/help — справка")

    async def _unknown(self, msg: Message) -> None:
        await msg.answer("Неизвестная команда. /help")

    async def _unknown_callback(self, call: CallbackQuery) -> None:
        await call.answer()
        await call.message.answer("Неизвестная операция.")

    def _plan(self, name: str):
        async def _handler(call: CallbackQuery) -> None:
            await call.answer()
            await call.message.answer(f"Вы выбрали тариф «{name}».")
        return _handler

    async def _activate(self, call: CallbackQuery) -> None:
        await call.answer()
        uid = str(call.from_user.id)
        try:
            self._db[uid] = {
                "started": datetime.utcnow(),
                TRIAL_FLAG: True,
                "questions": 0,
                "symbols": 0,
            }
            self._db.sync()
        except Exception as e:
            await call.message.answer(f"⚠️ Ошибка БД: {e}")
            return

        await call.message.answer(
            "✅ Пробный период активирован!\nДоступно: 10 вопросов / 10 000 символов"
        )
        
        try:
            await call.message.edit_reply_markup(reply_markup=None)
        except Exception:
            pass

    async def _trial_ok(self, uid: int) -> bool:
        rec = self._db.get(str(uid), {})
        return not rec.get(TRIAL_FLAG) or datetime.utcnow() - rec.get("started", datetime.min) >= timedelta(days=7)


async def main():
    TOKEN = os.getenv("BOT_TOKEN", "вставь свой токен сюда")
    PRICES = {"month": 199, "quarter": 549, "year": 1_490}
    db = shelve.open(str(Path(__file__).with_name("trial.db")), writeback=True)
    db.update({k: v | {TRIAL_FLAG: v.get(TRIAL_FLAG, False)} for k, v in db.items()})
    bot = UltraLiteSubBot(TOKEN, PRICES, db)
    await bot.run()


if __name__ == "__main__":
    import asyncio
    asyncio.run(main())
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@alekssamos
Программист любитель
Пишу для тех, кто, возможно, в будущем придёт из поисковых систем.

Иногда инлайн кнопки перестают работать, запросы вообще не отправляются, ничего не приходит, словно нажатия нет.
Выход: отозвать токен и сгенерировать новый.
Если у вас есть заброшенный бот в ботфазере, которому больше пяти лет, можете взять старый токен и попробовать, возможно, сработает, затем сделать revoke и запустить код уже с новым токеном, кнопки заработают.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы