Задать вопрос
@fialol

Ошибка в коде python, бот для тг канала, в чем проблема?

import logging
from telegram import Bot
from telegram.error import TelegramError
from apscheduler.schedulers.background import BackgroundScheduler
import requests
import asyncio

# Настройки
BOT_TOKEN = ''
CHANNEL_ID = '@'
UPDATE_INTERVAL = 30  # 30 сек

# Глобальная переменная для хранения ID закрепленного сообщения
PINNED_MESSAGE_ID = None

bot = Bot(token=BOT_TOKEN)
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)


def get_crypto_prices():
    try:
        response = requests.get(
            'https://api.coingecko.com/api/v3/simple/price',
            params={
                'ids': 'bitcoin,the-open-network',
                'vs_currencies': 'usd',
                'include_market_cap': 'true',
                'include_24hr_change': 'true'
            }
        )
        return response.json()
    except Exception as e:
        logging.error(f'Ошибка получения данных: {e}')
        return None


def format_message(prices):
    if not prices:
        return "❌ Не удалось получить данные"

    btc = prices.get('bitcoin', {})
    ton = prices.get('the-open-network', {})

    return (
        " **Актуальные курсы**\n\n"
        f" Bitcoin (BTC)\n"
        f"• Цена: ${btc.get('usd', 'N/A'):,}\n"
        f"• Изменение (24ч): {btc.get('usd_24h_change', 'N/A'):.2f}%\n\n"
        f" TON\n"
        f"• Цена: ${ton.get('usd', 'N/A'):,}\n"
        f"• Изменение (24ч): {ton.get('usd_24h_change', 'N/A'):.2f}%\n\n"
        "_Обновлено автоматически_"
    )


async def create_initial_message():
    global PINNED_MESSAGE_ID
    try:
        # Создаем первое сообщение
        msg = await bot.send_message(
            chat_id=CHANNEL_ID,
            text=" Загрузка данных...",
            parse_mode='Markdown'
        )
        # Закрепляем сообщение
        await bot.pin_chat_message(
            chat_id=CHANNEL_ID,
            message_id=msg.message_id
        )
        PINNED_MESSAGE_ID = msg.message_id
        logging.info(f"Создано новое закрепленное сообщение ID: {PINNED_MESSAGE_ID}")
    except Exception as e:
        logging.error(f"Ошибка создания сообщения: {e}")


async def update_message():
    global PINNED_MESSAGE_ID
    try:
        prices = get_crypto_prices()
        message = format_message(prices)

        # Если сообщение еще не создано
        if not PINNED_MESSAGE_ID:
            await create_initial_message()

        # Обновляем существующее сообщение
        await bot.edit_message_text(
            chat_id=CHANNEL_ID,
            message_id=PINNED_MESSAGE_ID,
            text=message,
            parse_mode='Markdown'
        )

    except TelegramError as e:
        # Если сообщение было удалено - создаем новое
        if "message to edit not found" in str(e):
            logging.warning("Сообщение не найдено, создаем новое")
            await create_initial_message()
        else:
            logging.error(f"Ошибка Telegram: {e}")
    except Exception as e:
        logging.error(f"Общая ошибка: {e}")


def scheduled_task():
    # Создаем новый цикл событий для каждого вызова
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(update_message())
    loop.close()


if __name__ == '__main__':
    # Первоначальное создание сообщения
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    loop.run_until_complete(create_initial_message())
    loop.close()

    # Запуск планировщика
    scheduler = BackgroundScheduler()
    scheduler.add_job(scheduled_task, 'interval', seconds=UPDATE_INTERVAL)
    scheduler.start()

    try:
        while True:
            pass
    except (KeyboardInterrupt, SystemExit):
        scheduler.shutdown()

Это Бот для автообновления в сообщении курса валюты.
После того как прошло 30 секунд (заданное время) - должны изменится данные в сообщении, а выходит вот эта ошибка:

2025-01-27 20:05:01,195 - apscheduler.executors.default - INFO - Running job "scheduled_task (trigger: interval[0:00:30], next run at: 2025-01-27 20:05:01 MSK)" (scheduled at 2025-01-27 20:05:01.183768+03:00)

2025-01-27 20:05:01,783 - root - ERROR - Ошибка Telegram: Unknown error in HTTP implementation: RuntimeError('Event loop is closed')

2025-01-27 20:05:01,810 - apscheduler.executors.default - INFO - Job "scheduled_task (trigger: interval[0:00:30], next run at: 2025-01-27 20:05:31 MSK)" executed successfully
  • Вопрос задан
  • 54 просмотра
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
Lord_of_Rings
@Lord_of_Rings
Дунадан - северный странник. Злой, но очень добрый
Вам надо использовать один и тот же цикл событий, а не закрывать его. В логах вообще-то это написано
...
def scheduled_task():
    loop = asyncio.get_event_loop()
    loop.run_until_complete(update_message())

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(create_initial_message())

    scheduler = BackgroundScheduler()
    scheduler.add_job(scheduled_task, 'interval', seconds=UPDATE_INTERVAL)
    scheduler.start()

    try:
        while True:
            pass
    except (KeyboardInterrupt, SystemExit):
        scheduler.shutdown()
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы