A
A
AsQ_QQ2022-01-14 04:48:41
Python
AsQ_QQ, 2022-01-14 04:48:41

How to make the handler fire every 10 seconds, aiogram, python?

in general, I made a bot that sends me the latest news from the site, but how can I make the handler that sends me the news automatic? so that I would not press the "latest news" button, but that it would turn on every 10 seconds?
here is the release of all the news (everything is fine here)

@dp.message_handler(commands='all')
async def get_all_news(message: types.Message):
  with open('news_dist_save.json') as file:
    news_dist = json.load(file)


  for k, v in sorted(news_dist.items()):
    news = f'{hcode(v["dates_id_print"])}\n' \
         f'{hlink(v["aubl_title"], v["aubl_url_split_print"])}'

    await message.answer(news)

but the latest news, I need to make this function run every 10 seconds.
@dp.message_handler(commands='news')
async def get_new_news(message: types.Message):
  fresh_news = chek_news_update()

  if len(fresh_news) >= 1:
    for k, v in sorted(fresh_news.items()):
      news = f'{hcode(v["dates_id_print"])}\n' \
           f'{hlink(v["aubl_title"], v["aubl_url_split_print"])}'
      await message.answer(news)
      #print('ok news')
  else:
    pass
    #await message.answer('no')


the bot works with a bang, but only from the button.
with the /all command, he displays everything, and with the /news command, he is silent, because the latest news has not yet been released.
61e0d63b9417e908559829.png

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vindicar, 2022-01-14
@AsQ_QQ

Well, something like that, just keep in mind that control over who can execute commands remains with you.
The bot either polls the news or it doesn't, and it will be more difficult to do it individually for different users.

stop_polling_site = None  # контролирует, продолжаем мы проверять новости или нет

async def get_news(message: types.Message):
  "Эта функция только проверяет и отправляет новости, она не является обработчиком событий"
  fresh_news = chek_news_update() # ты выполняешь сетевую операцию синхронно. Зачем?!

  if len(fresh_news) >= 1:
    for k, v in sorted(fresh_news.items()):
      news = f'{hcode(v["dates_id_print"])}\n' \
           f'{hlink(v["aubl_title"], v["aubl_url_split_print"])}'
      await message.answer(news)  # <<< не лучший способ отправлять сообщения в канал, но это твое дело.
      print('ok news')
  else:
    print('no')

@dp.message_handler(commands='startnews')
async def start_polling_news(message: types.Message):
  "Эта функция обрабатывает команду для начала опроса и реализует цикл опроса."
  global stop_polling_site
  if stop_polling_site is not None:
    await message.answer("Мы уже проверяем новости.")
    return
  stop_polling_site = asyncio.Event()
  while True:  # цикл опроса новостей
    try:
        # реализуем ожидание без остановки остального бота. Таймаут - сколько ждем в секундах.
        # такой подход используется вместо asyncio.sleep(), 
        # чтобы можно было в любой момент остановить опрос новостей.
        await asyncio.wait_for(stop_polling_site.wait(), timeout=600)
    except asyncio.TimeoutError:
        # дождались таймаута - работаем.
        try:
          await get_news(message)
        except:
          pass # была ошибка при получении новостей, думай сам что тут делать
    else:
        # таймаута не было - значит, поступила команда на остановку цикла
        break
  stop_polling_site = None

@dp.message_handler(commands='stopnews')
async def stop_polling_news(message: types.Message):
  "Эта функция обрабатывает команду для окончания опроса."
  global stop_polling_site
  if stop_polling_site is None:
    # цикл и так не работает
    await message.answer("Мы и так не проверяем новости.")
  else:
    # говорим остановить цикл
    stop_polling_site.set()

A
AsQ_QQ, 2022-01-14
@AsQ_QQ

in general, I made it so that it would work every 5 seconds

async def update_news_1(message: types.Message):
  fresh_news = chek_news_update()

  if len(fresh_news) >= 1:
    for k, v in sorted(fresh_news.items()):
      news = f'{hcode(v["dates_id_print"])}\n' \
           f'{hlink(v["aubl_title"], v["aubl_url_split_print"])}'
      await message.answer(news)
      print('ok news')
  else:
    print('no')

  time.sleep(5)

  return await update_news_1(message)

but, I can't use the rest of the bot commands) so either help with this or another way to do ripita

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question