Discord.py Выполнение команды с таймером
Пишу бота для дискорда. Пробовал многое. Не получается выполнить данное действие. Суть проблемы: Задан таймер(Например каждый час) бот должен выполнить заранее прописанную функцию. Что у меня получается? - Либо выполняется все по таймеру, но при этом больше бот не реагирует на команды. Либо бот реагирует на команды в чате, но не выполняет функцию по таймеру.
Ответы (2 шт):
from threading import Thread
import schedule # pip install schedule
import time
class ScheduledFunction (Thread):
def __init__(self, name):
Thread.__init__(self)
self.name = name
def someFunc(self):
print("Running scheduled function")
def run (self):
schedule.every().second.do(self.someFunc)
while True:
schedule.run_pending()
time.sleep(1)
if __name__ == "__main__":
thrd = ScheduledFunction ("Some name")
thrd.start()
while True:
print("Running the main thread")
time.sleep(0.25)
Задан таймер(Например каждый час) бот должен...
Лучше сделать не через time.sleep(), а с помощью библиотеки schedule
Так как вы хотите и время считать, и чтобы бот в то же время мог работать - вам нужен дополнительный поток.
В коде выше - создаётся и запускается поток с именем Some name, в методе run() планируется выполнение другого метода по таймеру - schedule.every().second.do(self.someFunc) (можете использовать schedule.every().hour.do(self.someFunc), чтобы выполнять функцию каждый час).
Далее вызывается:
schedule.run_pending()
time.sleep(1)
это нужно для того, чтобы scheduler мог отсчитывать время до следующего вызова метода.
А в main там временем начинается бесконечный цикл, выводящий просто текст.
Получается что-то вроде:
Running the main thread
Running the main thread
Running the main thread
Running the main thread
Running scheduled function
Running the main thread
И так до бесконечности...
Из вывода программы видно, что ни выполнение time.sleep(1) в методе run(), ни while True в main не блокируют друг друга и они прекрасно работают вместе.
Теперь вам просто остаётся переписать часть своего кода для использования многопоточности и планировщика задач :)
Библиотека discord.py асинхронная. Для подобных задач можно использовать Background Tasks.
Для этого произведите импорт from discord.ext import tasks.
Теперь используйте следующий код:
yourname.start() # Для запуска вашего таска
@tasks.loop(hours=1)
async def yourname(): # Назвать функцию можете как угодно.
# Действия которые вы хотите производить каждый час.
@your_name.before_loop # Это необходимо, чтобы ваш таск ждал, пока бот полностью запустится.
async def yourname2(): # Назвать эту функцию можно тоже как угодно.
await bot.wait_until_ready()
Также хотел бы подметить, что использовать time.sleep() в асинхронном коде нельзя. Вместо этого есть asyncio.sleep(), соответственно если будете его использовать, не забудьте импортировать.
Подробнее ознакомится с Background Tasks в оф. документации - https://discordpy.readthedocs.io/en/latest/ext/tasks/index.html