【问题标题】:Pass context to background task discord.py将上下文传递给后台任务 discord.py
【发布时间】:2018-10-28 08:53:57
【问题描述】:

discord 上的服务器所有者要求我为他的机器人添加自定义货币系统(机器人仅在此服务器上)。为了鼓励活动,我们没有使用样片系统,而是我的想法是每 7 分钟弹出一条带有图像的消息,用户必须向图像添加“反应”。为了方便和控制输入,我想为我的图像添加一个反应,这样用户只需点击反应,它就会添加数量。

排除了所有这些上下文,这是作为后台任务的问题。我不知道如何将上下文传递给反应!

async def my_background_task():
    await bot.wait_until_ready()
    counter = 0
    channel = discord.Object(id='446782521070321664')
    while not bot.is_closed:
        counter += 1
        with open('vbuck.png', 'rb') as f:
            await bot.send_file(channel, f) #sends a png of a vbuck
            await bot.add_reaction(discord.message,'<:vbuck:441740047897591809>') #This is the Reaction part 
    await asyncio.sleep(420) # task runs every 7 min seconds
bot.loop.create_task(my_background_task())

如果您能给我一些很棒的建议,并且如果您觉得代码和解释更加慷慨,我将不胜感激,我正在从这个项目中学习 python。

【问题讨论】:

    标签: python python-3.x discord discord.py


    【解决方案1】:

    如果我正确理解了这个问题,您实际上希望等待用户对您发布的文件做出反应,然后根据该反应奖励他们。我假设您使用的是 discord.py 1.0 或更高版本。

    据我所知,后台任务本身不能被交给任何上下文 - 因为它不像特定上下文中的评论那样被调用。 但是,API (https://discordpy.readthedocs.io/en/rewrite/api.html#discord.on_reaction_add) 声明有一个侦听器来监听消息的反应,这意味着您可以简单地使用

    @bot.event
    async def on_reaction_add(reaction, user):
        #here do some checks on reaction.message and to check that it is actually
        #the correct message being reacted too and avoid multiple reactions of one user.
    

    API 还会告诉您可以对消息进行哪些检查。当你让机器人发布消息时,你可以给消息一个特定的签名(像time.time() 这样的时间戳似乎足够好),然后访问reaction.message.content 并将其与当前时间进行比较。为此,我会将您的后台任务修改为以下内容:

    async def my_background_task():
        await bot.wait_until_ready()
        counter = 0
        channel = bot.get_channel(id='446782521070321664')
    
        while not bot.is_closed:
            counter += 1
            mess = "maybe a timestamp"
            e = discord.Embed()
            e.set_image(url = "some cool image maybe randomly chosen, please no vbucks")
            await channel.send(mess, embed = e) #sends a message with embed picture
            await asyncio.sleep(420) # task runs every 7 min
    

    然后消息内容将只是message

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      您需要保存send_file 返回的Message 对象(已发送的消息)。然后您可以使用Client.wait_for_reaction 中的Message 对象等待响应。

      async def task():
          await bot.wait_until_ready()
          channel = discord.Object(id='446782521070321664')
          vbuck = discord.utils.get(bot.get_all_emojis(), name='vbuck')
          check = lambda reaction, user: user != bot.user
          while not bot.is_closed:
              msg = await bot.send_file(channel, 'vbuck.png') #sends a png of a vbuck
              await bot.add_reaction(msg, vbuck) 
              for _ in range(7*60):
                  res = await bot.wait_for_reaction(message=msg, emoji=vbuck, check=check, timeout=1)
                  if res:
                      # res.user reacted to the message
      

      【讨论】:

      • 如果您正在使用 Client 类,那就太好了(我认为它不适用于 Bot 类,是吗?)。同样作为信息:在 1.0+ 中,wait_for_reaction 现在是 client.wait_for('reaction_add', ...) 并且使用方式略有不同
      • @Banana 哪一部分不适用于BotBotClient 的子类,我还没有找到任何地方Client 可以做Bot 做不到的事情。
      • 你说得对,我不知道它是Client的子类,我一定是瞎了:(
      猜你喜欢
      • 2014-03-12
      • 1970-01-01
      • 2019-09-19
      • 2023-03-26
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2021-03-19
      • 2021-11-22
      相关资源
      最近更新 更多