2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

discord.pyでTaskに引数を渡す

Last updated at Posted at 2020-01-06

注意

既にアナウンスされている通り、discord.pyは2021年8月下旬ころ、以降のサポートを停止する旨発表されております。
もし本記事を参考にして不具合が生じた場合、ライブラリのサポート終了による影響である可能性もあります。
詳しくは the_future_of_dpy.md をご覧ください。

前提

  • discord.py 1.3.0
  • python 3.6

注意

この記事に出てくるコードは説明用に記載しているため、実運用を想定したものではありません。
用途に合わせて適切に書き換えてくださいね。

やりたいこと

Taskに引数を渡したい

なぜやりたいか

基本的に定期実行するTaskはbotの起動時に開始することが多いと思う。
ただ、時には、コマンドなどで開始タイミングや送信先チャンネルなどを制御したいことがある。
例えば、 「今から30分間だけ5分ごとに指定のチャンネルで時報をメンションしてほしい」 みたいな。

ところが、現状discord.pyのドキュメント内には、Task (https://discordpy.readthedocs.io/ja/latest/ext/tasks/index.html) が引数をとるような例がない。

方法

まずは、定期実行したいTaskに普通に引数を追加しておく。
例えば上記を例にして、コマンドが入力されたチャンネル内でコマンドを送信した人にメンションを送る場合を考える。
この場合だと、コマンド入力時のContextを引数として受け取っておけば、チャンネルも送信者も特定できそうだ。

from discord.ext import tasks, commands

class MyCog(commands.Cog):
    def __init__(self):
        pass

    def cog_unload(self):
        self.reminder.cancel()

    @tasks.loop(minutes=5.0, count=6)
    async def reminder(self, ctx, content):
       await ctx.send("<@{0}> {1}".format(ctx.author.id, content))

こんな感じでreminderを定義しておけば、後はこれを起動すればいい感じにリマインドが飛んでくれるだろう。
では、この引数ctxを渡すにはどうすればよいか。

Taskの引数はstart()に渡す

タイトル通り。task開始時に使うstart()に渡せばよい。start()に渡した*args**kawrgsは、そのまま該当Taskの引数として渡される。
なので、例えば以下のようなreminderコマンドを定義すればよい。

from discord.ext import tasks, commands

class MyCog(commands.Cog):
    def __init__(self):
        pass

    def cog_unload(self):
        self.reminder.cancel()

    @tasks.loop(minutes=5.0, count=6)
    async def reminder(self, ctx, content):
       await ctx.send("<@{0}> {1}".format(ctx.author.id, content))

    @commands.command()
    async def set_reminder(self, ctx, content):
        self.reminder.start(ctx, content) # ここ大事
        await ctx.send("リマインダをセットしました")

これで、set_reminderコマンドをチャットに送れば、5分ごとにあらかじめ指定した内容がメンションされる。
ポイントはself.reminder.start(ctx, content)で、start()に渡す引数が、そのstart()によって起動されるTaskの引数にそのままわたることさえ押さえておけばOK。

注意

最初にも書いたようにこのコードそのものは実運用を想定していません。
set_reminderを入力後30分以内にほかの人がまたset_reminder打ったらどうなるねんとか興味は尽きませんね。

あくまでTaskに引数を渡す説明を行うための疑似コードであることをご承知ください。
(とはいえ、文法ミスのような致命的な間違いがあれば教えてください)

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?