Есть код, который по выгруженному файлу JSON (история чата из телеграм канала) ищет сообщения.
Ищет он их командой
!s словодляпоиска
Он выдает по 1 сообщению и дописывает к нему 2 кнопки (Далее и Подробно). Кнопка далее должна показывать следующее сообщение из поиска, а кнопка подробно - должно отображать 5 сообщений до найденого id и после 5. Обработчик показывает, что все корректно и ищет.
Received callback: command=search, param=next_1
Received callback: command=search, param=detailed_700
Но в чат ничего не выводит. Почему?
import json
import telebot
from telebot import types
# Загрузка JSON файла
with open('result.json', 'r', encoding='utf-8') as file:
data = json.load(file)
chat_history = data.get('messages', [])
# Проверяем, что chat_history — это список
if not isinstance(chat_history, list):
raise TypeError("chat_history должен быть списком")
# Токен вашего бота
TOKEN = "ТОКЕН"
bot = telebot.TeleBot(TOKEN)
# Словарь для хранения состояния поиска пользователей
user_search_state = {}
def extract_text_from_message(message):
"""
Извлекает текст из сообщения, игнорируя text_entities.
"""
text = message.get('text', '')
if isinstance(text, str):
return text.strip()
elif isinstance(text, list):
return ' '.join(item.get('text', '') for item in text if isinstance(item, dict))
return ''
def format_message(message):
"""
Форматирует сообщение в виде:
id date
from: text
"""
return f"{message.get('id', 'Неизвестно')} {message.get('date', 'Неизвестно')}\n{message.get('actor', 'Неизвестно')}: {extract_text_from_message(message)}"
def create_navigation_keyboard(page, total_results, message_id):
"""
Создает клавиатуру с кнопками для управления результатами поиска.
"""
markup = types.InlineKeyboardMarkup()
total_pages = (len(total_results) + 9) // 10 # Количество страниц
# Кнопка "Назад" (если не на первой странице)
if page > 0:
prev_button = types.InlineKeyboardButton('Назад', callback_data=f'search_prev_{page - 1}')
markup.add(prev_button)
# Кнопка "Вперед" (если есть больше результатов)
if len(total_results) > (page + 1) * 10:
next_button = types.InlineKeyboardButton('Вперед', callback_data=f'search_next_{page + 1}')
markup.add(next_button)
# Кнопка "Подробно"
detailed_button = types.InlineKeyboardButton('Подробно', callback_data=f'search_detailed_{message_id}')
markup.add(detailed_button)
return markup
@bot.message_handler(func=lambda message: message.text and message.text.startswith('!s'))
def search(message):
try:
keyword = message.text[2:].strip()
if keyword:
results = [msg for msg in chat_history if keyword.lower() in extract_text_from_message(msg).lower()]
if results:
user_search_state[message.chat.id] = {
'results': results,
'page': 0
}
# Отправляем первое сообщение
display_message(message.chat.id, 0)
else:
bot.send_message(message.chat.id, 'Ничего не найдено.')
else:
bot.send_message(message.chat.id, 'Пожалуйста, укажите ключевое слово для поиска.')
except IndexError:
bot.send_message(message.chat.id, 'Пожалуйста, укажите ключевое слово для поиска.')
def display_message(chat_id, page):
state = user_search_state.get(chat_id, {})
results = state.get('results', [])
if not results:
bot.send_message(chat_id, 'Нет сообщений для отображения.')
return
start = page * 10
end = start + 10 # Показываем 10 сообщений
result_to_display = results[start:end]
if result_to_display:
bot.send_message(chat_id, format_message(result_to_display[0]), reply_markup=create_navigation_keyboard(page, results, result_to_display[0].get('id')))
else:
bot.send_message(chat_id, 'Нет дополнительных сообщений.')
@bot.callback_query_handler(func=lambda call: call.data.startswith('search_'))
def handle_navigation(call):
try:
command, param = call.data.split('_', 1)
chat_id = call.message.chat.id
# Отладочные сообщения
print(f"Received callback: command={command}, param={param}")
if command == 'search_prev':
page = int(param)
display_message(chat_id, page)
elif command == 'search_next':
page = int(param)
display_message(chat_id, page)
elif command == 'search_detailed':
message_id = int(param)
display_detailed_messages(chat_id, message_id)
elif command == 'search_cancel':
if chat_id in user_search_state:
del user_search_state[chat_id]
bot.send_message(chat_id, 'Поиск отменён.')
bot.answer_callback_query(call.id)
except ValueError as e:
bot.send_message(call.message.chat.id, f'Произошла ошибка при обработке: {e}')
def display_detailed_messages(chat_id, message_id):
state = user_search_state.get(chat_id, {})
results = state.get('results', [])
if not results:
bot.send_message(chat_id, 'Нет сообщений для отображения.')
return
# Найти индекс текущего сообщения
index = next((i for i, msg in enumerate(results) if msg.get('id') == message_id), None)
if index is None:
bot.send_message(chat_id, 'Сообщение не найдено.')
return
# Вывод сообщений до и после
start_index = max(index - 5, 0)
end_index = min(index + 6, len(results))
detailed_results = results[start_index:end_index]
for result in detailed_results:
bot.send_message(chat_id, format_message(result))
# Обработчик для команды !top
@bot.message_handler(func=lambda message: message.text and message.text.startswith('!top'))
def top_messages(message):
try:
if isinstance(chat_history, list) and len(chat_history) > 0:
top_messages = chat_history[:10]
if top_messages:
for msg in top_messages:
bot.send_message(message.chat.id, format_message(msg))
else:
bot.send_message(message.chat.id, 'Нет сообщений для отображения.')
else:
bot.send_message(message.chat.id, 'Нет сообщений в истории.')
except Exception as e:
bot.send_message(message.chat.id, f'Произошла ошибка: {e}')
# Запуск бота
bot.polling()
Формат JSON можно взять экспортом из своего канала для теста.