Объединение двух ботов на discord py в одного
У меня есть два бота и две задачи для них. Я их не могу объеденить по одной причине. Есть две функции on_message и on_ready В функции on_ready реализован бесконечный цикл. Отправка сообщений утром и вечером А в функции on_message разные условия для сообщений По отдельности работает, вместе - нет. Я предполагаю, что это из за бесконечного цикла. То есть бесконечно проверяет время сейчас и нужное мне и поэтому не реагирует на сообщения, потому что занят проверкой времени. В этом ли проблема и если да, то как по другому реализовать функцию on_ready, чтобы она и функция on_message работала.
import discord
from datetime import datetime, time
import time
client = discord.Client()
@client.event
async def on_ready():
channel = client.get_channel(id)
while True:
if str(datetime.now().hour) == '6':
await channel.send(f"Доброе утро")
time.sleep(4000)
elif str(datetime.now().hour) == '20':
await channel.send(f"Спокойной ночи")
time.sleep(4000)
@client.event
async def on_message(message):
if message.content == 'hi':
await message.reply('hi')
Ответы (2 шт):
Самый простой вариант — вынести бесконечный цикл в отдельный поток. Для этого в asyncio предусмотрена специальная функция run_coroutine_threadsafe(func(), client.loop), которая первым аргументом принимает вызов функции, а вторым цикл событий, где нужно запустить эту функцию с сохранением основного потока.
Таким образом должно получиться что-то такое:
import asyncio
. . .
async def loop():
channel = client.get_channel(id)
while True:
if str(datetime.now().hour) == '6':
await channel.send(f"Доброе утро")
time.sleep(4000)
elif str(datetime.now().hour) == '20':
await channel.send(f"Спокойной ночи")
time.sleep(4000)
@client.event
async def on_ready():
asyncio.run_coroutine_threadsafe(loop(), client.loop)
# а далее уже остальные действия
. . .
. . .
Можно подойти к задаче немного иначе, вынести бесконечный цикл из события и тем самым дополнительно подготовить код к дальнейшему расширению функционала. Пока кода не очень много возможность расширения его может казаться не проблемой, но если код изначально плохо спроектирован - то придется его переписывать или писать костыли, чтобы добавить функционал.
В python есть библиотека планировщик, которой можно задать точное время выполнения каких либо функций.
Таким образом код можно организовать примерно так:
import discord
from datetime import datetime, time
import time
import schedule
client = discord.Client()
@client.event
def on_ready():
channel = client.get_channel(id)
schedule.every().day.at("06:00").do(lambda: channel.send(f"Доброе утро"))
schedule.every().day.at("20:00").do(lambda: channel.send(f"Спокойной ночи"))
@client.event
async def on_message(message):
if message.content == 'hi':
await message.reply('hi')
while True:
schedule.run_pending()
# другие действия
time.sleep(1)