Исправление кода Telegram бота

Created on: September 28, 2024

Answered using OpenAI 01 Preview by OpenAI01

Question

помоги исправить код выходят такие ошиби:D:\Program Files\Python312\Lib\site-packages\telegram\utils\request.py:54: UserWarning: python-telegram-bot wasn't properly installed. Please refer to README.rst on how to properly install.
warnings.warn(
Traceback (most recent call last):
File "D:\Program Files\Python312\Lib\site-packages\telegram\utils\request.py", line 36, in <module>
import telegram.vendor.ptb_urllib3.urllib3 as urllib3
File "D:\Program Files\Python312\Lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\__init__.py", line 7, in <module>
from .connectionpool import (
File "D:\Program Files\Python312\Lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\connectionpool.py", line 11, in <module>
from .exceptions import (
File "D:\Program Files\Python312\Lib\site-packages\telegram\vendor\ptb_urllib3\urllib3\exceptions.py", line 2, in <module>
from .packages.six.moves.http_client import (
ModuleNotFoundError: No module named 'telegram.vendor.ptb_urllib3.urllib3.packages.six.moves'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "e:\Python-Проекты\Bot.py", line 2, in <module>
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton
File "D:\Program Files\Python312\Lib\site-packages\telegram\__init__.py", line 187, in <module>
from .bot import Bot
File "D:\Program Files\Python312\Lib\site-packages\telegram\bot.py", line 107, in <module>
from telegram.utils.request import Request
File "D:\Program Files\Python312\Lib\site-packages\telegram\utils\request.py", line 44, in <module>
import urllib3.contrib.appengine as appengine # type: ignore[no-redef]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ModuleNotFoundError: No module named 'urllib3.contrib.appengine' УЛУЧШИ ВЕСЬ МОЙ КОД что бы не было ошибок вот мой код:import logging
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton
from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters,
CallbackContext, CallbackQueryHandler, ConversationHandler)
import webbrowser
import os
from datetime import datetime
import speech_recognition as sr
from pydub import AudioSegment
import requests
from bs4 import BeautifulSoup

# Настройка логирования
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

# Ключ API
TELEGRAM_BOT_TOKEN = '7738581629:AAH5bMJ5yD8-yEXbX5BKk2KIIR1RoEbxTE4'

# Состояния для ConversationHandler
MAIN_MENU, YOUTUBE_SEARCH, SHOWING_VIDEOS = range(3)

# Известные приложения для открытия
applications = {
'блокнот': 'notepad.exe',
'калькулятор': 'calc.exe',
}

def start(update: Update, context: CallbackContext):
keyboard = [
[KeyboardButton("🎥 YouTube"), KeyboardButton("🌐 Открыть сайт")],
[KeyboardButton("🖥️ Открыть приложение"), KeyboardButton("🕒 Текущее время")],
[KeyboardButton("🎤 Голосовой ввод")]
]
reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
update.message.reply_text(
'Здравствуйте! Я ваш персональный ассистент. Выберите действие:',
reply_markup=reply_markup
)
return MAIN_MENU

def handle_main_menu(update: Update, context: CallbackContext):
text = update.message.text.lower()
if "youtube" in text:
return start_youtube(update, context)
elif "открыть сайт" in text:
update.message.reply_text("Введите адрес сайта:")
return MAIN_MENU
elif "открыть приложение" in text:
keyboard = [[KeyboardButton(app)] for app in applications.keys()]
keyboard.append([KeyboardButton("Назад")])
reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
update.message.reply_text("Выберите приложение:", reply_markup=reply_markup)
return MAIN_MENU
elif "текущее время" in text:
now = datetime.now()
current_time = now.strftime('%H:%M:%S')
update.message.reply_text(f'Текущее время: {current_time}')
elif "голосовой ввод" in text:
update.message.reply_text("Отправьте голосовое сообщение.")
elif text.startswith('http'):
webbrowser.open(text)
update.message.reply_text(f'Открываю сайт {text}')
elif text in applications:
os.startfile(applications[text])
update.message.reply_text(f'Открываю {text}')
elif text == "назад":
return start(update, context)
else:
update.message.reply_text('Извините, я вас не понял. Пожалуйста, выберите действие из меню.')
return MAIN_MENU

def handle_voice(update: Update, context: CallbackContext):
voice = update.message.voice
file = context.bot.get_file(voice.file_id)
file.download('voice.ogg')

# Конвертация OGG в WAV
sound = AudioSegment.from_ogg('voice.ogg')
sound.export('voice.wav', format='wav')

# Распознавание речи
recognizer = sr.Recognizer()
with sr.AudioFile('voice.wav') as source:
audio = recognizer.record(source)

try:
text = recognizer.recognize_google(audio, language='ru-RU')
update.message.reply_text(f"Вы сказали: {text}")
update.message.text = text
return handle_main_menu(update, context)
except sr.UnknownValueError:
update.message.reply_text('Извините, я не смог распознать голосовое сообщение.')
except sr.RequestError as e:
update.message.reply_text('Ошибка сервиса распознавания речи.')
return MAIN_MENU

def start_youtube(update: Update, context: CallbackContext):
update.message.reply_text('Что вы хотите посмотреть на YouTube? Введите запрос.')
return YOUTUBE_SEARCH

def search_youtube(update: Update, context: CallbackContext):
query = update.message.text
videos = get_youtube_results(query)
context.user_data['videos'] = videos

keyboard = [[InlineKeyboardButton(video['title'][:40] + '...', callback_data=str(idx))] for idx, video in enumerate(videos)]
keyboard.append([InlineKeyboardButton('Отмена', callback_data='cancel')])

reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text('Вот что я нашёл:', reply_markup=reply_markup)
return SHOWING_VIDEOS

def button_callback(update: Update, context: CallbackContext):
query = update.callback_query
query.answer()
data = query.data

if data == 'cancel':
query.edit_message_text(text='Поиск отменен.')
return start(update, context)
else:
idx = int(data)
video = context.user_data['videos'][idx]
webbrowser.open(video['url'])
query.edit_message_text(text=f'Открываю видео: {video["title"]}')
return start(update, context)

def get_youtube_results(query):
url = f"https://www.youtube.com/results?search_query={query}"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
videos = []
for vid in soup.findAll('div', attrs={'class':'yt-lockup-content'}):
if len(videos) >= 5:
break
title = vid.find('a', attrs={'class':'yt-uix-tile-link'})
if title:
video_url = 'https://www.youtube.com' + title['href']
videos.append({'title': title.text, 'url': video_url})
return videos

def main():
updater = Updater(TELEGRAM_BOT_TOKEN, use_context=True)
dp = updater.dispatcher

conv_handler = ConversationHandler(
entry_points=[CommandHandler('start', start)],
states={
MAIN_MENU: [
MessageHandler(Filters.text & ~Filters.command, handle_main_menu),
MessageHandler(Filters.voice, handle_voice),
],
YOUTUBE_SEARCH: [MessageHandler(Filters.text & ~Filters.command, search_youtube)],
SHOWING_VIDEOS: [CallbackQueryHandler(button_callback)],
},
fallbacks=[CommandHandler('start', start)]
)

dp.add_handler(conv_handler)

updater.start_polling()
updater.idle()

if __name__ == '__main__':
main()

Thought

Понимание ошибки
Задача заключается в чтении сообщения об ошибке и требованиях пользователя. Взаимодействую с текстом, чтобы понять причину.

Реализуем улучшения

Ого, столкнулся с проблемой в Telegram библиотеках. Пришлось обновить urllib3 до версии 2, чтобы устранить эти ошибки.

Ищу повреждения

Сейчас я смотрю на сообщения об ошибках, связанные с библиотеками 'telegram.vendor.ptb_urllib3' и 'urllib3.contrib.appengine'. Это, возможно, указывает на проблемы с установкой или отсутствием зависимостей.

Устанавливаю зависимости

Проверка версии пакета

Я смотрю на установку пакета 'python-telegram-bot', потому что возможно, версия пакета не совпадает с версией кода, что приводит к несоответствиям и ошибкам.

Обновляю код

Проверяю совместимость кода с последней версией 'python-telegram-bot'. Использую виртуальное окружение и устанавливаю нужную версию.

Переустановка и обновление

Рекомендуется удалить текущую версию библиотеки 'python-telegram-bot', затем установить последнюю версию или сбалансированную для кода 13.x. Убедитесь, что установлены все зависимые пакеты, включая 'six' и 'urllib3'.

Символы внутренней работы

Вижу, как внутренняя структура библиотек меняется: 'Updater' заменяется на 'Application', 'Filters' теперь 'filters'. 'CallbackContext' больше не требуется.

Актуализируя библиотеку

Заменяю 'Updater' на 'Application', обновляю импорты, корректирую функции хендлеров на '<URL>', и меняю синтаксис для версии 20.x.

Обновление пакетов

Включаю новые импорты, такие как logging и ContextTypes, для улучшения функционала и обработки ошибок.

Реализую обновления

Использую ApplicationBuilder вместо Updater, добавляю обработчики и меняю вызов на run_polling(). Код адаптирую для ContextTypes.DEFAULT_TYPE.

Обновляю код

Проверяю функции start, handle_main_menu, handle_voice, start_youtube и search_youtube. Убедительно, что context.user_data и context.bot при этом сохраняют актуальность.

В функции 'main_menu', при выборе пользователем '🎤 Голосовой ввод', бот просит отправить голосовое сообщение. В 'handle_voice' это сообщение анализируется. Возможно, 'os.startfile' не работает, так как бот запущен на сервере.

Обновляю код

Проверяю документацию и замечаю, что методы должны быть async. Теперь перемещаю вызов файла чуть выше, чтобы понять, что асинхронные функции важны.

Обноление функции

Сейчас я переобновляю обновление сообщений, делая их асинхронными и включая 'await' для вызовов методов бота, чтобы поддерживать актуальные работы функций.

Импорт и настройка

Обновляю код, подключаю библиотеки и задаю константы для реализации Telegram-бота.

Реализация и настройки

Я документирую и объясняю функции управления меню, голосовым вводом и YouTube, чтобы пользователи могли легко получить доступ к различным функциям и информации.

Понимаю ограничения Telegram-бота

Изменение подхода

Теперь бот отправляет пользователю ссылки на открытие, а не пытается управлять устройством для открытия приложений или веб-страниц.

Размышляю о запуске

Пользователь считает, что код должен запускать приложения, но это не получится.

Устанавливаю зависимости
Проверяю, что все нужные пакеты, такие как python-telegram-bot, six, urllib3 и другие, установлены, а pydub не забудьте интегрировать с ffmpeg.

Answer

Похоже, что ваша проблема связана с несовместимостью версии библиотеки python-telegram-bot и вашего кода, а также с недостающими зависимостями. Я переписал ваш код, чтобы он соответствовал последней версии библиотеки python-telegram-bot (версия 20.x). Также убедитесь, что все необходимые пакеты установлены.

Шаги для решения проблемы:

  1. Удалите старую версию python-telegram-bot:

    pip uninstall python-telegram-bot
  2. Установите последнюю версию библиотеки:

    pip install python-telegram-bot --upgrade
  3. Установите недостающие зависимости:

    pip install six urllib3 SpeechRecognition pydub requests beautifulsoup4
  4. Установите ffmpeg для работы с аудио (если еще не установлен):

    • Windows: Скачайте и установите ffmpeg с официального сайта.
    • Добавьте путь к ffmpeg в переменные среды PATH.
  5. Обновите ваш код следующим образом:

import logging from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, KeyboardButton from telegram.ext import (ApplicationBuilder, CommandHandler, MessageHandler, filters, ContextTypes, CallbackQueryHandler, ConversationHandler) import webbrowser import os from datetime import datetime import speech_recognition as sr from pydub import AudioSegment import requests from bs4 import BeautifulSoup # Настройка логирования logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO ) # Ключ API TELEGRAM_BOT_TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN' # Состояния для ConversationHandler MAIN_MENU, YOUTUBE_SEARCH, SHOWING_VIDEOS = range(3) # Известные приложения для открытия applications = { 'блокнот': 'notepad.exe', 'калькулятор': 'calc.exe', } async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): keyboard = [ [KeyboardButton("🎥 YouTube"), KeyboardButton("🌐 Открыть сайт")], [KeyboardButton("🖥️ Открыть приложение"), KeyboardButton("🕒 Текущее время")], [KeyboardButton("🎤 Голосовой ввод")] ] reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True) await update.message.reply_text( 'Здравствуйте! Я ваш персональный ассистент. Выберите действие:', reply_markup=reply_markup ) return MAIN_MENU async def handle_main_menu(update: Update, context: ContextTypes.DEFAULT_TYPE): text = update.message.text.lower() if "youtube" in text: return await start_youtube(update, context) elif "открыть сайт" in text: await update.message.reply_text("Введите адрес сайта:") return MAIN_MENU elif "открыть приложение" in text: keyboard = [[KeyboardButton(app)] for app in applications.keys()] keyboard.append([KeyboardButton("Назад")]) reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True) await update.message.reply_text("Выберите приложение:", reply_markup=reply_markup) return MAIN_MENU elif "текущее время" in text: now = datetime.now() current_time = now.strftime('%H:%M:%S') await update.message.reply_text(f'Текущее время: {current_time}') elif "голосовой ввод" in text: await update.message.reply_text("Отправьте голосовое сообщение.") elif text.startswith('http'): await update.message.reply_text(f'Открываю сайт {text}') webbrowser.open(text) elif text in applications: os.startfile(applications[text]) await update.message.reply_text(f'Открываю {text}') elif text == "назад": return await start(update, context) else: await update.message.reply_text('Извините, я вас не понял. Пожалуйста, выберите действие из меню.') return MAIN_MENU async def handle_voice(update: Update, context: ContextTypes.DEFAULT_TYPE): voice = update.message.voice file = await context.bot.get_file(voice.file_id) await file.download_to_drive('voice.ogg') # Конвертация OGG в WAV sound = AudioSegment.from_ogg('voice.ogg') sound.export('voice.wav', format='wav') # Распознавание речи recognizer = sr.Recognizer() with sr.AudioFile('voice.wav') as source: audio = recognizer.record(source) try: text = recognizer.recognize_google(audio, language='ru-RU') await update.message.reply_text(f"Вы сказали: {text}") update.message.text = text return await handle_main_menu(update, context) except sr.UnknownValueError: await update.message.reply_text('Извините, я не смог распознать голосовое сообщение.') except sr.RequestError as e: await update.message.reply_text('Ошибка сервиса распознавания речи.') return MAIN_MENU async def start_youtube(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text('Что вы хотите посмотреть на YouTube? Введите запрос.') return YOUTUBE_SEARCH async def search_youtube(update: Update, context: ContextTypes.DEFAULT_TYPE): query = update.message.text videos = get_youtube_results(query) context.user_data['videos'] = videos keyboard = [[InlineKeyboardButton(video['title'][:40] + '...', callback_data=str(idx))] for idx, video in enumerate(videos)] keyboard.append([InlineKeyboardButton('Отмена', callback_data='cancel')]) reply_markup = InlineKeyboardMarkup(keyboard) await update.message.reply_text('Вот что я нашёл:', reply_markup=reply_markup) return SHOWING_VIDEOS async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE): query = update.callback_query await query.answer() data = query.data if data == 'cancel': await query.edit_message_text(text='Поиск отменен.') return await start(update, context) else: idx = int(data) video = context.user_data['videos'][idx] await query.edit_message_text(text=f'Открываю видео: {video["title"]}') webbrowser.open(video['url']) return await start(update, context) def get_youtube_results(query): url = f"https://www.youtube.com/results?search_query={query}" response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') videos = [] for vid in soup.findAll('a', attrs={'class': 'yt-uix-tile-link'}): if len(videos) >= 5: break video_url = 'https://www.youtube.com' + vid['href'] title = vid['title'] videos.append({'title': title, 'url': video_url}) return videos def main(): application = ApplicationBuilder().token(TELEGRAM_BOT_TOKEN).build() conv_handler = ConversationHandler( entry_points=[CommandHandler('start', start)], states={ MAIN_MENU: [ MessageHandler(filters.TEXT & ~filters.COMMAND, handle_main_menu), MessageHandler(filters.VOICE, handle_voice), ], YOUTUBE_SEARCH: [MessageHandler(filters.TEXT & ~filters.COMMAND, search_youtube)], SHOWING_VIDEOS: [CallbackQueryHandler(button_callback)], }, fallbacks=[CommandHandler('start', start)] ) application.add_handler(conv_handler) application.run_polling() if __name__ == '__main__': main()

Обратите внимание на следующие изменения:

  • Асинхронные функции: В версии 20.x все обработчики должны быть асинхронными (async def).
  • Использование await: При вызове методов бота необходимо использовать await.
  • Обновленные импорты: Updater заменен на ApplicationBuilder, Filters на filters, и т.д.
  • Обработка файлов: Загрузка файлов теперь выполняется с помощью await file.download_to_drive('voice.ogg').

Важно: Функции webbrowser.open и os.startfile будут работать только на компьютере, где запущен бот. Если бот развернут на сервере, эти функции будут пытаться открыть приложения и сайты на сервере, что, скорее всего, нежелательно. В контексте Telegram-бота обычно отправляют пользователю ссылки для открытия.

Рекомендация: Если вы хотите, чтобы пользователь открывал сайты или приложения, отправляйте ему сообщения с соответствующими ссылками или инструкциями.

Пример отправки ссылки пользователю:

await update.message.reply_text(f"Откройте сайт по ссылке: {text}")

Убедитесь, что все необходимые пакеты установлены и корректно работают. Если возникнут дополнительные ошибки, внимательно прочитайте сообщения об ошибках и убедитесь, что все зависимости установлены и соответствуют используемым версиям библиотек.

Share this Q&A