Как реализовать счетчик нажатий на инлайн кнопку?
Не могу реализовать этот счетчик, после того как отправилась фотка в канал с описанием и двумя кнопками, я по ней нажимаю, и ничего не происходит, возможно хендлер не ловит, или нужно чтобы начинался полинг, но сообщения в канал отправляются пока не наступит полинг, когда он начнется сообщения не отправляется, не знаю как исправить все это, очень был бы рад, если бы кто-то помог!!!
import asyncio
from asyncio.log import logger
from os import listdir
from aiogram import types
from aiogram.types import InputFile
from aiogram.utils.markdown import hlink
from config import channels
from keyboards.good_or_bad import good_or_bad_keyboard
from loader import bot, dp
from utils.notify_admins import on_startup_notify
import datetime
async def on_startup(dp):
await on_startup_notify(dp)
async def send_photo(chat_id: int, photo: InputFile, caption: str):
await bot.send_photo(chat_id, photo, caption)
# Переменные для итерации фото
mypath = "images"
photos = list()
formats = ['.jpg', '.jpeg', '.png']
savedSet = set()
# Переменные для ссылки на канал
one = '9x16 - Name Channel'
two = 't.me/link_on_channel'
three = '@name_channel'
url = two
# Переменные для итерации времени
time_3 = str(datetime.time(hour=11, minute=39))
time_3 = time_3[:-3]
time_5 = str(datetime.time(hour=11, minute=40))
time_5 = time_5[:-3]
time_7 = str(datetime.time(hour=11, minute=41))
time_7 = time_7[:-3]
# Переменные для итерации реакций
async def main(dp):
async def generator_1(param):
param += 1
return param
x_global = 0
y_global = 0
while True:
@dp.callback_query_handler(text_contains='good')
async def good_reaction(call: types.CallbackQuery):
await call.answer('Вам понравилась публикация')
x_local = 0
x_local = x_global
await generator_1(param=x_local)
@dp.callback_query_handler(text_contains='bad')
async def bad_reaction(call: types.CallbackQuery):
await call.answer('Вам не понравилась публикация')
y_local = 0
y_local = y_global
await generator_1(param=y_local)
now_global = datetime.datetime.now()
now_global = str(now_global.time())
now_global = now_global.split('.')[0]
now_global = now_global[:-3]
if now_global == time_3:
for i in formats:
for j in filter(lambda x: x.endswith(i), listdir(mypath)):
photos.append(j)
for i in photos:
now_local = datetime.datetime.now()
now_local = str(now_local.time())
now_local = now_local.split('.')[0]
now_local = now_local[:-3]
if now_local == time_3 or time_5 or time_7:
with open(f"{mypath}/{i}", 'rb') as photo:
print(f'Сейчас {now_local}')
print('Отправляю фото')
await bot.send_photo(chat_id=channels, photo=photo, caption=f'{hlink(one, url=two)}\n'
f'{hlink(two, url=two)}\n'
f'{hlink(three, url=two)}',
reply_markup=good_or_bad_keyboard)
@dp.callback_query_handler(text_contains='good')
async def good_reaction(call: types.CallbackQuery):
await call.answer('Вам понравилась публикация')
x_local = 0
x_local = x_global
await generator_1(param=x_local)
@dp.callback_query_handler(text_contains='bad')
async def bad_reaction(call: types.CallbackQuery):
await call.answer('Вам не понравилась публикация')
y_local = 0
y_local = y_global
await generator_1(param=y_local)
await asyncio.sleep(60)
if now_local == time_7:
print('Остановка')
await asyncio.sleep(120)
else:
pass
try:
await dp.start_polling()
finally:
await dp.storage.close()
await dp.storage.wait_closed()
await bot.session.close()
if __name__ == '__main__':
try:
asyncio.run(main(dp))
except (KeyboardInterrupt, SystemExit):
logger.error("Bot stopped!")
Ответы (1 шт):
Класс для установки InlineKeyboard
В кнопке устанавливаем callback_data="InlineKeyboardDay"
class TrainingCalendar:
"""
async Класс для создания InlineKeyboard в виде календаря
Args:
month (int): Месяц, по умолчанию текщий. Defaults to None.
year (int): Год, по умолчанию текщий. Defaults to None.
Returns:
InlineKeyboardMarkup: возвращает клавиатуру в виде календаря
"""
def __init__(self, month: int = None, year: int = None) -> None:
dt_now = datetime.datetime.now()
if not month:
month = dt_now.month
if not year:
year = dt_now.year
self.month = month
self.year = year
self.day_of_week = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"]
async def creating_calendar_list(self) -> list:
"""
Создает список календаря
Returns:
list: [['month int(year)'],[days..],[days..],[days..],[days..],[days..],[days..]]
"""
try:
calendar_list = calendar.month(self.year, self.month, 2, 1).split()
month_and_year = ' '.join(calendar_list[:2])
list_of_days = calendar.monthcalendar(self.year, self.month)
new_calendar_list = list_of_days
new_calendar_list.insert(0, [month_and_year])
return new_calendar_list
except IndexError as errore:
logger.error(f"\n{errore}\nПередан месяц: {self.month}.\
\nМесяц не может быть больше 12")
except TypeError as errore:
logger.error(f"\n{errore}\nМесяц и год не могут быть строкой: \
\n {self.month}: {type(self.month)}\n \
{self.year}: {type(self.year)}")
async def _add_month_and_year_to_the_keyboard(self, keyboar: InlineKeyboardMarkup,
month_and_year: list) -> None:
"""
Добавляем месяц и год а так же кнопку назад и вперед
"""
keyboar_list = [InlineKeyboardButton(
text='< ',
callback_data="InlineKeyboardBack"),
InlineKeyboardButton(
text=''.join(month_and_year),
callback_data="InlineKeyboardNone"),
InlineKeyboardButton(
text=' >',
callback_data="InlineKeyboardNext")]
keyboar.row(*keyboar_list)
async def _add_days_of_the_week_to_the_keyboard(self, keyboar: InlineKeyboardMarkup) -> None:
"""
Добавляем дни недели
"""
button_list = []
for i in self.day_of_week:
button_list.append(InlineKeyboardButton(
text=i,
callback_data="InlineKeyboardNone"))
keyboar.row(*button_list)
async def _add_days_to_the_keyboard(self, keyboar: InlineKeyboardMarkup,
days_list: list) -> None:
"""
Добавляем дни
"""
for cildren in days_list:
button_list = []
for day in cildren:
if day == 0:
day = " "
Notebook_data = await Notebook.getting_data_from_json(f"{day}.{self.month}.{self.year}")
if Notebook_data is not None and Notebook_data.get("workout") == True:
button_list.append(InlineKeyboardButton(
text=str(day) + "✅", callback_data="InlineKeyboardDay"))
else:
button_list.append(InlineKeyboardButton(
text=str(day), callback_data="InlineKeyboardDay"))
keyboar.row(*button_list)
async def _create_calendar_keyboard(self) -> InlineKeyboardMarkup:
if calendar_list := await self.creating_calendar_list():
# Создаем клавиатуру
keyboar = InlineKeyboardMarkup(row_width=7)
# Добавляем месяц и год
await self._add_month_and_year_to_the_keyboard(keyboar, calendar_list[0])
# Добавляем дни недели
await self._add_days_of_the_week_to_the_keyboard(keyboar)
# Добавляем дни
await self._add_days_to_the_keyboard(keyboar, calendar_list[1:])
return keyboar
async def get_calendar_keyboard(self) -> InlineKeyboardMarkup:
"""
Публичный метод для получения клавиатуры
Returns:
InlineKeyboardMarkup: клавиатура в виде календаря
"""
if keyboar := await self._create_calendar_keyboard():
return keyboar
После чего мы ловим InlineKeyboardDay (callback_data="InlineKeyboardDay")
@dispatcher.callback_query_handler(lambda c: c.data and 'InlineKeyboardDay' in c.data)
async def process_callback_button1(callback_query: types.CallbackQuery):
"""
Обрабатываем CallbackQuery
"""
await bot.answer_callback_query(callback_query.id)
callback_data = callback_query.data
message = json.loads(callback_query.as_json())
for i in message["message"]["reply_markup"]["inline_keyboard"]:
for j in i:
if j["callback_data"] == callback_data:
CallbackDataDict.update({message["from"]["id"]: {callback_data: j}})
pass
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
keyboard.add(*["✅Добавить тренировку", "❌Отменить тренировку"])
keyboard.add(*["✅Добавить парметры тела", "?Показать парметры тела"])
await bot.send_message(callback_query.from_user.id, text="Выберите команду", reply_markup=keyboard)
А ты качестве callback_data ловишь просто текст а не callback @dp.callback_query_handler(text_contains='good')
Попробуй так @dispatcher.callback_query_handler(lambda c: c.data and 'good' in c.data)