Не реагирует на нажатия телеграмм бот
Я написал бота на телебот и сделал инлайн клавиатуры, я новичок в телеботе и до конца не понял как работает call_back, у меня есть меню: Смотреть новости/Настройки. При нажатии на любую все отлично, если я перехожу в настройки, то там еще одна клавиатура, но при нажатии на нее ничего не происходит.
import telebot
from newsapi import NewsApiClient
from telebot import types
bot = telebot.TeleBot('токен')
newsapi = NewsApiClient(api_key='токен')
language_var='ru'
category_var=''
country_var=''
@bot.message_handler(commands=["start"])
def main_menu(message):
markup=types.InlineKeyboardMarkup(row_width=1)
markup.add(types.InlineKeyboardButton('Смотреть новости',callback_data='CheckNews'),
types.InlineKeyboardButton('Настройки', callback_data='Settings'),
)
bot.send_message(message.chat.id, text='*Меню:*', reply_markup=markup,parse_mode="Markdown")
@bot.callback_query_handler(func=lambda call:True)
def news_settings_handler(call):
if call.data=='Settings':
settings_markup = types.InlineKeyboardMarkup(row_width=1)
settings_markup.add(types.InlineKeyboardButton('Язык', callback_data='Language_settings'),
types.InlineKeyboardButton('Категория', callback_data='Category_settings'),
types.InlineKeyboardButton('Страна', callback_data='Country_settings'),
)
bot.send_message(call.message.chat.id, text='*Настройки:*', reply_markup=settings_markup, parse_mode="Markdown")
@bot.callback_query_handler(func=lambda call: True)
def settings_handler(call):
if call.data == 'Language_settings':
language_markup = types.InlineKeyboardMarkup(row_width=1)
language_markup.add(types.InlineKeyboardButton('Русский', callback_data='ru'),
types.InlineKeyboardButton('Английский', callback_data='en'),
types.InlineKeyboardButton('Немецкий', callback_data='de'),
types.InlineKeyboardButton('Назад', callback_data='back')
)
bot.send_message(call.message.chat.id, text='*На каком языке вы хотите читать новости?*',
reply_markup=language_markup,parse_mode="Markdown")
@bot.callback_query_handler(func=lambda call: True)
def language_handler(call):
global language_var
if call.data=='ru':
language_var='ru'
elif call.data=='en':
language_var='en'
elif call.data=='de':
language_var='de'
elif call.data=='back':
main_menu(call.message)
elif call.data == 'Category_settings':
category_markup = types.InlineKeyboardMarkup(row_width=2)
category_markup.add(types.InlineKeyboardButton('Спорт', callback_data='sport'),
types.InlineKeyboardButton('Бизнес', callback_data='business'),
types.InlineKeyboardButton('Развлечения', callback_data='entertainment'),
types.InlineKeyboardButton('Общее', callback_data='general'),
types.InlineKeyboardButton('Медицина', callback_data='health'),
types.InlineKeyboardButton('Наука', callback_data='science'),
types.InlineKeyboardButton('Технологии', callback_data='technology'),
types.InlineKeyboardButton('Все категории', callback_data='Default'),
)
bot.send_message(call.message.chat.id, text='*Какие новости вы хотите читать?*',
reply_markup=category_markup, parse_mode="Markdown")
@bot.callback_query_handler(func=lambda call: True)
def category_handler(call):
global category_var
if call.data == 'sport':
category_var = 'sports'
if call.data == 'business':
category_var = 'business'
if call.data == 'entertainment':
category_var = 'entertainment'
if call.data == 'general':
category_var = 'general'
if call.data == 'health':
category_var = 'health'
if call.data == 'science':
category_var = 'science'
if call.data == 'technology':
category_var = 'technology'
if call.data == 'Default':
category_var = ''
elif call.data == 'Country_settings':
country_markup = types.InlineKeyboardMarkup(row_width=2)
country_markup.add(types.InlineKeyboardButton('Китай', callback_data='ch'),
types.InlineKeyboardButton('США', callback_data='us'),
types.InlineKeyboardButton('Россия', callback_data='ru'),
types.InlineKeyboardButton('Польша', callback_data='pl'),
types.InlineKeyboardButton('Украина', callback_data='ua'),
types.InlineKeyboardButton('Германия', callback_data='de')
)
bot.send_message(call.message.chat.id, text='*Новости из какой страны вы хотите читать?*',
reply_markup=country_markup, parse_mode="Markdown")
@bot.callback_query_handler(func=lambda call: True)
def country_handler(call):
global country_var
if call.data == 'ru':
country_var = 'ru'
elif call.data == 'us':
country_var = 'us'
elif call.data == 'de':
country_var = 'de'
elif call.data == 'ua':
country_var = 'ua'
elif call.data == 'ch':
country_var = 'ch'
elif call.data == 'pl':
country_var = 'pl'
elif call.data=='CheckNews':
global category_var
global language_var
global country_var
titles = []
descriptions = []
if category_var!='' and country_var!='':
top_headlines = newsapi.get_top_headlines(category=category_var,language=language_var,country=country_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
elif category_var!='' and country_var=='':
top_headlines = newsapi.get_top_headlines(category=category_var, language=language_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
elif category_var=='' and country_var!='':
top_headlines = newsapi.get_top_headlines(language=language_var,country=country_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
elif category_var=='' and country_var=='':
top_headlines = newsapi.get_top_headlines(language=language_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
for i in range (len(titles)):
try:
bot.send_message(call.message.chat.id, text='*'+titles[i]+'*\n'+'\n'+descriptions[i],parse_mode="Markdown")
except:
pass
if __name__ == '__main__':
bot.polling(none_stop=True)
Ответы (1 шт):
Автор решения: oleksandrigo
→ Ссылка
Переделал всё что было...
# делаем словарь с юзерами
users = {}
# делаем функцию для более удобного получения данных из словаря
def get_data(user_id: int, data: str, default=None):
users.setdefault(user_id, {"state": "", "language_var": "ru"})
return users[user_id].get(data, default)
@bot.message_handler(commands=["start"])
def start(message: types.Message):
# при старте делаем запись юзера в словарь
users.setdefault(message.from_user.id, {"state": "", "language_var": "ru"})
markup = types.InlineKeyboardMarkup(row_width=1)
markup.add(types.InlineKeyboardButton('Смотреть новости', callback_data='CheckNews'),
types.InlineKeyboardButton('Настройки', callback_data='Settings'))
bot.send_message(message.chat.id, text='*Меню:*', reply_markup=markup, parse_mode="Markdown")
# как вы можете заметить я разбил всё что вы написали на отдельные хендлеры,
# старайтесь ридерживаться именно такого написания кода
@bot.callback_query_handler(func=lambda call: call.data == "Settings")
def news_settings(call: types.CallbackQuery):
settings_markup = types.InlineKeyboardMarkup(row_width=1)
settings_markup.add(types.InlineKeyboardButton('Язык', callback_data='Language_settings'),
types.InlineKeyboardButton('Категория', callback_data='Category_settings'),
types.InlineKeyboardButton('Страна', callback_data='Country_settings'))
bot.send_message(call.message.chat.id, text='*Настройки:*', reply_markup=settings_markup, parse_mode="Markdown")
# ловить нужный колбек можно вот так
@bot.callback_query_handler(func=lambda call: call.data == "CheckNews")
def check_news(call: types.CallbackQuery):
# пользуемся нашим словарем, если данных в нем не будет, то вернет пустую строку
category_var = get_data(call.message.from_user.id, "category_var", '')
language_var = get_data(call.message.from_user.id, "language_var", '')
country_var = get_data(call.message.from_user.id, "country_var", '')
titles = []
descriptions = []
if category_var != '' and country_var != '':
top_headlines = newsapi.get_top_headlines(category=category_var, language=language_var, country=country_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
elif category_var != '' and country_var == '':
top_headlines = newsapi.get_top_headlines(category=category_var, language=language_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
elif category_var == '' and country_var != '':
top_headlines = newsapi.get_top_headlines(language=language_var, country=country_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
elif category_var == '' and country_var == '':
top_headlines = newsapi.get_top_headlines(language=language_var)
for article in top_headlines['articles']:
titles.append(article['title'])
descriptions.append(article['description'])
for i in range(len(titles)):
try:
bot.send_message(call.message.chat.id,
text=f'*{titles[i]}*\n{descriptions[i]}',
parse_mode="Markdown")
except Exception:
pass
@bot.callback_query_handler(func=lambda call: call.data == "Language_settings")
def lang_settings(call: types.CallbackQuery):
language_markup = types.InlineKeyboardMarkup(row_width=1)
# я поменял колбек дату, для того чтобы понимать откуда именно был колбек
# в этом случае я добавил префикс choise_lang чтобы бот реагировал на их всех, но не на другие
language_markup.add(types.InlineKeyboardButton('Русский', callback_data='choise_lang:ru'),
types.InlineKeyboardButton('Английский', callback_data='choise_lang:en'),
types.InlineKeyboardButton('Немецкий', callback_data='choise_lang:de'),
types.InlineKeyboardButton('Назад', callback_data='choise_lang:back'))
bot.send_message(call.message.chat.id,
text='*На каком языке вы хотите читать новости?*',
reply_markup=language_markup,
parse_mode="Markdown")
# такие колбеки ловим вот так
@bot.callback_query_handler(func=lambda call: call.data.startswith("choise_lang"))
def language_handler(call: types.CallbackQuery):
# к слову колбек дата ведь уже другая и её нужно обработать, мы разбиваем стоку по : и берем правую часть
result = call.data.split(":")[1]
# сразу обработаем вариант с кнопкой назад
if result == "back":
main_menu(call.message)
return
# если же это была нажата не кнопка назад, то тогда просто запишите колбек в дату, не вижу смысла в куче ифов
users[call.message.from_user.id]['language_var'] = result
@bot.callback_query_handler(func=lambda call: call.data == "Category_settings")
def category_choise(call: types.CallbackQuery):
category_markup = types.InlineKeyboardMarkup(row_width=2)
category_markup.add(types.InlineKeyboardButton('Спорт', callback_data='choise_category:sport'),
types.InlineKeyboardButton('Бизнес', callback_data='choise_category:business'),
types.InlineKeyboardButton('Развлечения', callback_data='choise_category:entertainment'),
types.InlineKeyboardButton('Общее', callback_data='choise_category:general'),
types.InlineKeyboardButton('Медицина', callback_data='choise_category:health'),
types.InlineKeyboardButton('Наука', callback_data='choise_category:science'),
types.InlineKeyboardButton('Технологии', callback_data='choise_category:technology'),
types.InlineKeyboardButton('Все категории', callback_data='choise_category:Default'))
bot.send_message(call.message.chat.id,
text='*Какие новости вы хотите читать?*',
reply_markup=category_markup,
parse_mode="Markdown")
@bot.callback_query_handler(func=lambda call: call.data.startswith("choise_category"))
def category_handler(call: types.CallbackQuery):
result = call.data.split(":")[1]
if result == "Default":
users[call.message.from_user.id]['category_var'] = ''
return
users[call.message.from_user.id]['category_var'] = result
@bot.callback_query_handler(func=lambda call: call.data == "Country_settings")
def category_choise(call: types.CallbackQuery):
country_markup = types.InlineKeyboardMarkup(row_width=2)
country_markup.add(types.InlineKeyboardButton('Китай', callback_data='choise_lang:ch'),
types.InlineKeyboardButton('США', callback_data='choise_lang:us'),
types.InlineKeyboardButton('Россия', callback_data='choise_lang:ru'),
types.InlineKeyboardButton('Польша', callback_data='choise_lang:pl'),
types.InlineKeyboardButton('Украина', callback_data='choise_lang:ua'),
types.InlineKeyboardButton('Германия', callback_data='choise_lang:de'))
bot.send_message(call.message.chat.id,
text='*Новости из какой страны вы хотите читать?*',
reply_markup=country_markup,
parse_mode="Markdown")
@bot.callback_query_handler(func=lambda call: call.data.startswith("choise_category"))
def category_handler(call: types.CallbackQuery):
result = call.data.split(":")[1]
users[call.message.from_user.id]['category_var'] = result