From f4e3fae4fb70d73ad9cc44696dc29261c5b6e9b0 Mon Sep 17 00:00:00 2001 From: Anton Palgunov Date: Sat, 1 Apr 2023 19:54:15 +0100 Subject: [PATCH] =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D0=BB=20=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=BD=D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D1=8B=20=D0=B2?= =?UTF-8?q?=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB.=20=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BB=20=D0=B0=D0=B2=D1=82=D0=BE=D1=87=D0=B8=D1=81=D1=82=D0=BA?= =?UTF-8?q?=D1=83=20=D1=82=D1=80=D0=B0=D0=BD=D1=81=D0=BA=D1=80=D0=B8=D0=BF?= =?UTF-8?q?=D1=82=D0=BE=D0=B2,=20=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B5=20=D0=B7=D0=B0=D1=81=D0=BE=D1=80=D1=8F=D1=82=D1=8C=20?= =?UTF-8?q?=D0=BF=D0=B0=D0=BC=D1=8F=D1=82=D1=8C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 43 +++++++++++++++++++++++++++++++++++++++++++ transcription_dict.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 transcription_dict.py diff --git a/bot.py b/bot.py index 564ec7e..36da547 100644 --- a/bot.py +++ b/bot.py @@ -7,6 +7,10 @@ import requests import openai from dotenv import load_dotenv from pydub import AudioSegment +import hashlib +import threading +from datetime import datetime, timedelta +from transcription_dict import TranscriptionDict # Load the environment variables from the .env file load_dotenv() @@ -17,6 +21,7 @@ openai.api_key = os.environ.get("OPENAI_API_KEY") # Load the Telegram bot token from the environment variable bot = telebot.TeleBot(os.environ.get("TELEGRAM_BOT_TOKEN")) +transcription_dict = TranscriptionDict() def check_user(func): def check_user_int(message): @@ -147,9 +152,46 @@ def handle_voice_message(message): # Return the transcribed text back to the user bot.reply_to(message, transcription) + + transcription_hash = hashlib.md5(transcription.encode('utf-8')).hexdigest()[:8] + transcription_dict.set(transcription_hash, transcription) + + markup = telebot.types.InlineKeyboardMarkup() + markup.add(telebot.types.InlineKeyboardButton("Отправить текст", callback_data=f"voice_text:{transcription_hash}")) + bot.send_message(message.chat.id, f"Текст сообщения: {transcription}", reply_markup=markup) else: bot.reply_to(message, "Не удалось получить голосовое сообщение.") +# Define a callback function to handle the voice text button click +@bot.callback_query_handler(func=lambda call: call.data.startswith("voice_text:")) +def send_voice_text(call): + # Extract the transcribed text from the callback data + transcription_hash = call.data.split(':')[1] + voice_text = transcription_dict.get(transcription_hash) + + if voice_text: + # Generate a response using the ChatGPT model + (response_text, reason, cost) = generate_chat_response(voice_text) + + print(response_text) + + # Send the response back to the user with markdown formatting + try: + ans = bot.send_message(chat_id=call.message.chat.id, text=response_text , parse_mode='Markdown') + bot.reply_to(ans, f"Finish reason: {reason} \nCost: {cost}") + except Exception as e: + print(e) + bot.send_message(chat_id=call.message.chat.id, text="Что-то пошло не так c ответом. Пробую другой метод...") + + try: + bot.send_message(chat_id=call.message.chat.id, text=response_text) + except Exception as e: + print(e) + bot.send_message(chat_id=call.message.chat.id, text="Что-то пошло не так c ответом") + + else: + bot.send_message(chat_id=call.message.chat.id, text="Не удалось получить текст голосового сообщения.") + # Define a handler function for incoming messages @bot.message_handler(func=lambda message: True) @check_user @@ -179,5 +221,6 @@ def handle_message(message): bot.reply_to(message, "Что-то пошло не так c ответом...") + # Start the bot and listen for incoming messages bot.polling() diff --git a/transcription_dict.py b/transcription_dict.py new file mode 100644 index 0000000..e33531e --- /dev/null +++ b/transcription_dict.py @@ -0,0 +1,38 @@ +import time +import threading + +class TranscriptionDict: + def __init__(self, max_size=1000): + self.max_size = max_size + self._dict = {} + + # Start a thread to clean expired items every 3 minutes + self._clean_thread = threading.Thread(target=self._clean_expired_items_periodically) + self._clean_thread.daemon = True + self._clean_thread.start() + + def __len__(self): + return len(self._dict) + + def get(self, key): + return self._dict[key] + + def set(self, key, value): + self._dict[key] = value + if len(self._dict) > self.max_size: + self._clean_expired_items() + + def __contains__(self, key): + return key in self._dict + + def _clean_expired_items(self): + now = time.time() + expired_items = [k for k, v in self._dict.items() if now - v[1] >= 180] # 180 seconds = 3 minutes + for key in expired_items: + del self._dict[key] + + def _clean_expired_items_periodically(self): + while True: + time.sleep(180) # Check for expired items every 3 minutes + self._clean_expired_items() + \ No newline at end of file