Telezab/utilities/rabbitmq.py
UdoChudo 52e31864b3 feat: Develop web interface
- Implemented the initial version of the web interface.
refactor: Begin Telegram bot refactoring
- Started restructuring the bot’s code for better maintainability.
chore: Migrate to Flask project structure
- Reorganized the application to follow Flask's project structure.
cleanup: Extensive code cleanup
- Removed redundant code and improved readability.

Signed-off-by: UdoChudo <stream@udochudo.ru>
2025-06-10 14:39:11 +05:00

122 lines
4.7 KiB
Python

import asyncio
import json
from flask import current_app
from app.models.users import Users
import aio_pika
import telebot
import pika
import backend_bot
from config import RABBITMQ_LOGIN, RABBITMQ_PASS, RABBITMQ_HOST, RABBITMQ_QUEUE, RABBITMQ_URL_FULL
# Semaphore for rate limiting
rate_limit_semaphore = asyncio.Semaphore(25)
def rabbitmq_connection():
credentials = pika.PlainCredentials(RABBITMQ_LOGIN, RABBITMQ_PASS)
parameters = pika.ConnectionParameters(
host=RABBITMQ_HOST,
credentials=credentials,
heartbeat=600,
blocked_connection_timeout=300
)
connection = pika.BlockingConnection(parameters)
channel = connection.channel()
channel.queue_declare(queue=RABBITMQ_QUEUE, durable=True)
return connection, channel
def send_to_queue(message):
connection, channel = rabbitmq_connection()
channel.basic_publish(
exchange='',
routing_key=RABBITMQ_QUEUE,
body=json.dumps(message),
properties=pika.BasicProperties(
delivery_mode=2,
))
connection.close()
async def consume_from_queue():
while True:
try:
connection = await aio_pika.connect_robust(RABBITMQ_URL_FULL)
async with connection:
channel = await connection.channel()
queue = await channel.declare_queue(RABBITMQ_QUEUE, durable=True)
async for message in queue:
async with message.process():
try:
data = json.loads(message.body.decode('utf-8'))
chat_id = data["chat_id"]
message_text = data["message"]
await send_notification_message(chat_id, message_text)
except (json.JSONDecodeError, KeyError) as e:
telebot.logger.error(f"Error processing message: {e}")
except Exception as e:
telebot.logger.error(f"Error sending message: {e}")
except aio_pika.exceptions.AMQPError as e:
telebot.logger.error(f"RabbitMQ error: {e}")
except Exception as e:
telebot.logger.error(f"Critical error: {e}")
finally:
await asyncio.sleep(5)
# async def send_message(chat_id, message, is_notification=False):
# try:
# if is_notification:
# await rate_limit_semaphore.acquire()
# await asyncio.to_thread(backend_bot.bot.send_message, chat_id, message, parse_mode='HTML')
# formatted_message = message.replace('\n', ' ').replace('\r', '') # Добавляем форматирование сообщения
# telebot.logger.info(f'Send notification to {chat_id} from RabbitMQ [{formatted_message}]') # Добавляем логирование
# except telebot.apihelper.ApiTelegramException as e:
# if "429" in str(e):
# await asyncio.sleep(1)
# await send_message(chat_id, message, is_notification)
# else:
# telebot.logger.error(f"Failed to send message: {e}")
# except Exception as e:
# telebot.logger.error(f"Unexpected error: {e}")
# finally:
# if is_notification:
# rate_limit_semaphore.release()
async def send_message(chat_id, message, is_notification=False):
telegram_id = "unknown"
try:
if is_notification:
await rate_limit_semaphore.acquire()
# Получение telegram_id через app_context
def get_user():
with current_app.app_context():
user = Users.query.get(chat_id)
return user.telegram_id if user else "unknown"
telegram_id = await asyncio.to_thread(get_user)
# Отправка сообщения
await asyncio.to_thread(backend_bot.bot.send_message, chat_id, message, parse_mode='HTML')
# Форматирование и лог
formatted_message = message.replace('\n', ' ').replace('\r', '')
telebot.logger.info(f'Send notification to {telegram_id} ({chat_id}) from RabbitMQ [{formatted_message}]')
except telebot.apihelper.ApiTelegramException as e:
if "429" in str(e):
await asyncio.sleep(1)
await send_message(chat_id, message, is_notification)
else:
telebot.logger.error(f"Failed to send message to {telegram_id} ({chat_id}): {e}")
except Exception as e:
telebot.logger.error(f"Unexpected error sending message to {telegram_id} ({chat_id}): {e}")
finally:
if is_notification:
rate_limit_semaphore.release()
async def send_notification_message(chat_id, message):
await send_message(chat_id, message, is_notification=True)