...
This commit is contained in:
		
							
								
								
									
										0
									
								
								herolib/clients/telegram/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								herolib/clients/telegram/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										102
									
								
								herolib/clients/telegram/bot.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								herolib/clients/telegram/bot.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,102 @@
 | 
			
		||||
import json
 | 
			
		||||
import redis
 | 
			
		||||
import telebot
 | 
			
		||||
import os
 | 
			
		||||
import logging
 | 
			
		||||
from termcolor import colored
 | 
			
		||||
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
 | 
			
		||||
from telebot.formatting import escape_markdown
 | 
			
		||||
 | 
			
		||||
from bot_audio import audio_add
 | 
			
		||||
from bot_text import text_add
 | 
			
		||||
from ai.ask import ai_assistent,AIAssistant
 | 
			
		||||
 | 
			
		||||
class MyBot:
 | 
			
		||||
    def __init__(self,ai_reset:bool=False):
 | 
			
		||||
        # Initialize logging
 | 
			
		||||
        logging.basicConfig(level=logging.INFO, format='%(message)s')
 | 
			
		||||
        self.logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
        # Initialize Redis connection   
 | 
			
		||||
        self.redis_client = redis.Redis(host='localhost', port=6379, db=0)
 | 
			
		||||
 | 
			
		||||
        # Initialize Telegram bot
 | 
			
		||||
        self.telebotkey = os.getenv("TELEBOT")
 | 
			
		||||
        if self.telebotkey:
 | 
			
		||||
            self.logger.info(colored("TELEBOT key set", "green"))
 | 
			
		||||
            self.bot = telebot.TeleBot(self.telebotkey)
 | 
			
		||||
        else:
 | 
			
		||||
            raise Exception("can't find TELEBOT in ENV")
 | 
			
		||||
 | 
			
		||||
        # Set up message handlers
 | 
			
		||||
        self.setup_handlers()
 | 
			
		||||
        audio_add(self)
 | 
			
		||||
        text_add(self,reset=ai_reset)
 | 
			
		||||
 | 
			
		||||
    def setup_handlers(self):
 | 
			
		||||
        @self.bot.message_handler(commands=['help'])
 | 
			
		||||
        def send_welcome(message):
 | 
			
		||||
            self.bot.reply_to(message, """\
 | 
			
		||||
Hi there, I am your hero.
 | 
			
		||||
Just speak to me or do /start or /help
 | 
			
		||||
""")
 | 
			
		||||
 | 
			
		||||
        @self.bot.message_handler(commands=['start'])
 | 
			
		||||
        def start_command(message):
 | 
			
		||||
            chat_id = message.chat.id
 | 
			
		||||
 | 
			
		||||
            keyboard = InlineKeyboardMarkup()
 | 
			
		||||
            subscribe_button = InlineKeyboardButton("Subscribe to Updates", callback_data='subscribe')
 | 
			
		||||
            unsubscribe_button = InlineKeyboardButton("Unsubscribe from Updates", callback_data='unsubscribe')
 | 
			
		||||
            keyboard.row(subscribe_button, unsubscribe_button)
 | 
			
		||||
 | 
			
		||||
            self.bot.reply_to(message, "Please choose an option:", reply_markup=keyboard)
 | 
			
		||||
 | 
			
		||||
        @self.bot.callback_query_handler(func=lambda call: True)
 | 
			
		||||
        def callback_query(call):
 | 
			
		||||
            chat_id = call.message.chat.id
 | 
			
		||||
 | 
			
		||||
            if call.data == 'subscribe':
 | 
			
		||||
                self.redis_client.hset('subscribed_chats', chat_id, '1')
 | 
			
		||||
                self.bot.answer_callback_query(call.id, "You have subscribed to updates.")
 | 
			
		||||
                print(f"User subscribed to updates: {chat_id}")
 | 
			
		||||
            elif call.data == 'unsubscribe':
 | 
			
		||||
                self.redis_client.hdel('subscribed_chats', chat_id)
 | 
			
		||||
                self.bot.answer_callback_query(call.id, "You have unsubscribed from updates.")
 | 
			
		||||
                print(f"User unsubscribed from updates: {chat_id}")
 | 
			
		||||
 | 
			
		||||
    def send_message_to_subscribers(self, message):
 | 
			
		||||
        subscribed_chats = self.redis_client.hgetall('subscribed_chats')
 | 
			
		||||
        for chat_id in subscribed_chats:
 | 
			
		||||
            try:
 | 
			
		||||
                self.bot.send_message(chat_id.decode('utf-8'), message)
 | 
			
		||||
            except Exception as e:
 | 
			
		||||
                print(f"Failed to send message to chat {chat_id}: {str(e)}")
 | 
			
		||||
 | 
			
		||||
    def send_error_to_telegram(self,chat_id, error_message):
 | 
			
		||||
        # Format the error message for Telegram
 | 
			
		||||
        telegram_message = f"🚨 Error Occurred 🚨\n\n"
 | 
			
		||||
        telegram_message += f"app: {escape_markdown(error_message['app'])}\n"
 | 
			
		||||
        telegram_message += f"Function: {escape_markdown(error_message['function'])}\n"
 | 
			
		||||
        telegram_message += f"msg: {escape_markdown(error_message['msg'])}\n"
 | 
			
		||||
        telegram_message += f"Exception Type: {escape_markdown(error_message['exception_type'])}\n"
 | 
			
		||||
        telegram_message += f"Exception Message: ```\n{escape_markdown(error_message['exception_message'])}\n```\n"
 | 
			
		||||
        if 'traceback' in error_message:
 | 
			
		||||
            telegram_message += f"Traceback:\n```\n{escape_markdown(error_message['traceback'])}\n```"
 | 
			
		||||
        # Send the error message to the subscribed chat
 | 
			
		||||
        self.bot.send_message(chat_id, telegram_message, parse_mode='Markdown')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def start(self):
 | 
			
		||||
        print("Bot started")
 | 
			
		||||
        # Start the bot
 | 
			
		||||
        self.bot.polling()
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
def bot_new() -> MyBot:
 | 
			
		||||
    return MyBot()
 | 
			
		||||
 | 
			
		||||
# Usage
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    my_bot = bot_new()
 | 
			
		||||
    my_bot.start()
 | 
			
		||||
							
								
								
									
										72
									
								
								herolib/clients/telegram/bot_audio.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								herolib/clients/telegram/bot_audio.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
import os
 | 
			
		||||
from pydub import AudioSegment
 | 
			
		||||
import whisper
 | 
			
		||||
 | 
			
		||||
def audio_add(self):
 | 
			
		||||
    
 | 
			
		||||
    self.model = whisper.load_model("base")
 | 
			
		||||
 | 
			
		||||
    @self.bot.message_handler(content_types=['audio', 'voice']) #, 'document'
 | 
			
		||||
    def handle_audio(message):
 | 
			
		||||
        try:
 | 
			
		||||
            chat_id = message.chat.id
 | 
			
		||||
            file_info = None
 | 
			
		||||
            audio_path = None
 | 
			
		||||
 | 
			
		||||
            if message.content_type == 'audio':
 | 
			
		||||
                file_info = self.bot.get_file(message.audio.file_id)
 | 
			
		||||
                audio_path = f"/tmp/audio/{message.audio.file_id}.mp3"
 | 
			
		||||
            elif message.content_type == 'voice':
 | 
			
		||||
                file_info = self.bot.get_file(message.voice.file_id)
 | 
			
		||||
                audio_path = f"/tmp/audio/{message.voice.file_id}.ogg"
 | 
			
		||||
 | 
			
		||||
            if file_info:
 | 
			
		||||
                downloaded_file = self.bot.download_file(file_info.file_path)
 | 
			
		||||
 | 
			
		||||
                # Ensure the directory exists
 | 
			
		||||
                os.makedirs(os.path.dirname(audio_path), exist_ok=True)
 | 
			
		||||
 | 
			
		||||
                # Save the audio file
 | 
			
		||||
                with open(audio_path, 'wb') as new_file:
 | 
			
		||||
                    new_file.write(downloaded_file)
 | 
			
		||||
 | 
			
		||||
                #bot.send_message(chat_id, f"Audio received and saved successfully to {audio_path}.")
 | 
			
		||||
                print(f"Audio received and saved to {audio_path}")
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                # Convert to WAV format if necessary
 | 
			
		||||
                wav_path = audio_path.replace('.mp3', '.wav').replace('.ogg', '.wav')
 | 
			
		||||
                if audio_path.endswith('.mp3') or audio_path.endswith('.ogg'):
 | 
			
		||||
                    audio = AudioSegment.from_file(audio_path)
 | 
			
		||||
                    audio.export(wav_path, format='wav')
 | 
			
		||||
                else:
 | 
			
		||||
                    wav_path = audio_path
 | 
			
		||||
 | 
			
		||||
                # Transcribe audio using Whisper
 | 
			
		||||
                result = self.model.transcribe(wav_path)
 | 
			
		||||
                transcription = result["text"]
 | 
			
		||||
 | 
			
		||||
                self.bot.send_message(chat_id, transcription, parse_mode='Markdown')
 | 
			
		||||
                print(f"Audio received and saved to {audio_path}")
 | 
			
		||||
                print(f"Transcription: {transcription}")     
 | 
			
		||||
                                
 | 
			
		||||
                text2 = self.text_process(self,transcription)
 | 
			
		||||
                
 | 
			
		||||
                print(f"Processed text {chat_id}: {text2}")      
 | 
			
		||||
                    
 | 
			
		||||
                if len(text2)>0:
 | 
			
		||||
                    self.bot.send_message(chat_id, text2)
 | 
			
		||||
 | 
			
		||||
                                            
 | 
			
		||||
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            error_message = {
 | 
			
		||||
                'app': 'Telegram Bot',
 | 
			
		||||
                'function': 'handle_audio',
 | 
			
		||||
                'msg': 'Failed to process audio file',
 | 
			
		||||
                'exception_type': type(e).__name__,
 | 
			
		||||
                'exception_message': str(e)
 | 
			
		||||
            }
 | 
			
		||||
            self.send_error_to_telegram(chat_id, error_message)
 | 
			
		||||
            print(f"Error processing audio file: {e}")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										51
									
								
								herolib/clients/telegram/bot_text.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								herolib/clients/telegram/bot_text.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
import os
 | 
			
		||||
from ai.ask import ai_assistent
 | 
			
		||||
 | 
			
		||||
def text_add(self,reset:bool=False):
 | 
			
		||||
    
 | 
			
		||||
    self.ai_assistent = ai_assistent(reset=reset)
 | 
			
		||||
    self.text_process = text_process
 | 
			
		||||
    
 | 
			
		||||
    @self.bot.message_handler(content_types=['text'])
 | 
			
		||||
    def handle_text(message):
 | 
			
		||||
        try:
 | 
			
		||||
            chat_id = message.chat.id
 | 
			
		||||
            
 | 
			
		||||
            text = message.text
 | 
			
		||||
 | 
			
		||||
            # Here you can add your logic to process the text
 | 
			
		||||
            # For now, let's just echo the message back
 | 
			
		||||
            # response = f"You said: {text}"
 | 
			
		||||
 | 
			
		||||
            print(f"Received text from {chat_id}: {text}")                        
 | 
			
		||||
            
 | 
			
		||||
            text2 = self.text_process(self,text)
 | 
			
		||||
            
 | 
			
		||||
            print(f"Processed text {chat_id}: {text2}")      
 | 
			
		||||
                
 | 
			
		||||
            if len(text2)>0:
 | 
			
		||||
                self.bot.send_message(chat_id, text2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        except Exception as e:
 | 
			
		||||
            error_message = {
 | 
			
		||||
                'app': 'Telegram Bot',
 | 
			
		||||
                'function': 'handle_text',
 | 
			
		||||
                'msg': 'Failed to process text',
 | 
			
		||||
                'exception_type': type(e).__name__,
 | 
			
		||||
                'exception_message': str(e)
 | 
			
		||||
            }
 | 
			
		||||
            self.send_error_to_telegram(chat_id, error_message)
 | 
			
		||||
            print(f"Error processing text file: {e}")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def text_process(self, txt) -> str:
 | 
			
		||||
    if "translate" not in txt.lower():            
 | 
			
		||||
        txt+='''\n\n
 | 
			
		||||
            only output the heroscript, no comments
 | 
			
		||||
            '''
 | 
			
		||||
    response = self.ai_assistent.ask(
 | 
			
		||||
        category='timemgmt',
 | 
			
		||||
        name='schedule',
 | 
			
		||||
        question=txt)
 | 
			
		||||
    return response
 | 
			
		||||
							
								
								
									
										36
									
								
								herolib/clients/telegram/errorqueue.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								herolib/clients/telegram/errorqueue.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
import json
 | 
			
		||||
import redis
 | 
			
		||||
import telebot
 | 
			
		||||
import threading
 | 
			
		||||
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
 | 
			
		||||
import time
 | 
			
		||||
from telebot.formatting import escape_markdown
 | 
			
		||||
import os
 | 
			
		||||
from telegram.bot import send_error_to_telegram
 | 
			
		||||
 | 
			
		||||
# Initialize Redis connection
 | 
			
		||||
redis_client = redis.Redis(host='localhost', port=6379, db=0)
 | 
			
		||||
 | 
			
		||||
#get errors from redis and send them to bot if subscription done
 | 
			
		||||
def process_error_queue():
 | 
			
		||||
    while True:
 | 
			
		||||
        # Pop an error message from the Redis queue
 | 
			
		||||
        error_json = redis_client.lpop('error_queue')
 | 
			
		||||
 | 
			
		||||
        if error_json:
 | 
			
		||||
            # Deserialize the error message from JSON
 | 
			
		||||
            error_message = json.loads(error_json)
 | 
			
		||||
 | 
			
		||||
            # Get all subscribed chat IDs from Redis
 | 
			
		||||
            subscribed_chats = redis_client.hgetall('subscribed_chats')
 | 
			
		||||
 | 
			
		||||
            # Send the error message to all subscribed chats
 | 
			
		||||
            for chat_id in subscribed_chats.keys():
 | 
			
		||||
                send_error_to_telegram(int(chat_id), error_message)
 | 
			
		||||
        else:
 | 
			
		||||
            # If the queue is empty, wait for a short interval before checking again
 | 
			
		||||
            time.sleep(1)
 | 
			
		||||
 | 
			
		||||
# Start processing the error queue
 | 
			
		||||
process_error_queue_thread = threading.Thread(target=process_error_queue)
 | 
			
		||||
process_error_queue_thread.start()
 | 
			
		||||
		Reference in New Issue
	
	Block a user