scheduleモジュールを使うことで、特定の時間に関数を実行させることは出来るのですが
前提として、
- discord.py は非同期IOで動かすライブラリ。
- schedule は同期ループで動かすライブラリ。
同期ループは、非同期IOのイベントループをブロッキングする為、
質問のコードのようなループ処理を同時に実行する事はできません。
discord FAQ:「ブロッキング」とはなんですか。 に書かれている bad のコードに該当します。
方法がないわけではないのですが、
同期 <=> 非同期間のやりとりで手間が増えるので、
非同期IOに対応した aioschedule の利用をお勧めします。
- discord のコマンドを作る: discord.ext.commands.Bot を使う。
- 非同期IO でスケジューラーは aioschedule を使う。
- スケジューラーのジョブを実行するループは、
A) discord.ext.tasks.loop を使って run_pending を定期的に実行する。
B) asyncio の create_task を使う。(要: asyncio を使った非同期プログラミング)
(B) の方が効率の良いコードを組めますが、
簡単な方法で済ませるなら (A) の方法で 毎秒実行する等。
python
1import aioschedule
2from discord.ext import commands, tasks
3
4bot = commands.Bot(command_prefix="!")
5
6@bot.command()
7async def schedule(ctx, arg1, arg2):
8 # !schedule 0:00 "メッセージ"
9 async def job():
10 await ctx.send(arg2)
11 aioschedule.every().day.at(arg1).do(job)
12
13@tasks.loop(seconds=1)
14async def scheduler_loop():
15 await aioschedule.run_pending()
16scheduler_loop.start()
17
18bot.run(BOT_TOKEN)
schedule を使いたい場合。注意点: モジュール名とコマンド名が被ります。
コードは差分のみ
python
1import schedule
2
3@bot.command(name="schedule")
4async def schedule_command(ctx, arg1, arg2):
5 loop = asyncio.get_event_loop()
6 def job():
7 loop.create_task(ctx.send(arg2))
8 schedule.every().day.at(arg1).do(job)
9
10@tasks.loop(seconds=1)
11async def scheduler_loop():
12 schedule.run_pending()
13scheduler_loop.start()
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。