This commit is contained in:
2025-08-05 15:15:36 +02:00
parent 4bd960ed05
commit 7fabb4163a
192 changed files with 14901 additions and 0 deletions

View File

102
lib/clients/telegram/bot.py Normal file
View 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()

View 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}")

View 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

View 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()