当前位置: 首页 > 知识库问答 >
问题:

Python:通过齿轮和后台任务向不和谐中的特定通道发送消息

尉迟边浩
2023-03-14

我有一个Discord Python bot,我正在尝试运行一个后台任务,该任务将持续每隔X秒向一个通道发送一条消息—无需任何命令。当前有任意5秒的测试时间。

这是有问题的齿轮文件(为了效率而删除了进口和诸如此类的东西)

class TestCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.mytask.start()

    @tasks.loop(seconds=5.0)
    async def mytask(self):
        channel = client.get_channel(my channel id here)
        await channel.send("Test")

def setup(bot):
    bot.add_cog(TestCog(bot))

我有一种感觉,这是因为self参数是唯一传递的参数,但我在阅读API文档时有点困惑,不知道在这里到底要做什么。

我尝试了client而不是bot,我尝试了定义discord。Client()(但就我所读的内容而言,我不应该使用我一直试图避免的东西。

在其他使用实际命令的COG中,我将其设置为如下所示:

    @commands.command(name='test')
    async def check(self, ctx):
        if ctx.channel.name == 'channel name':
            await ctx.send("Response message")

这让我相信我传递的参数是错误的。我明白,因为我正在通过ctx,我可以抓住频道名称,但我不太确定如何做到这一点。当试图传递ctx参数时,我没有得到任何错误,但是由于明显的原因,消息不会发送。

我到底错过了什么?谢谢你的帮助!

共有2个答案

庄新翰
2023-03-14

您可以使用将任务添加到异步IO循环中。环创建任务(mytask(arguments)),在启动bot之前调用该任务。在这里阅读有关asyncio的所有内容

您可以使用async def myment(参数)像普通命令一样定义任务,但是省略ctx作为ctx基本上是您通常会得到的用于调用函数的命令的所有上下文。取而代之的是,您将希望使用通道id手动获取通道对象与通道=bot.get_channel(id),然后您可以做等待channel.send(您的消息)发送消息到所述通道。

要使其循环,只需使用而Trueasyncio循环即可。睡眠(延迟)来计时。这可能会导致计时不准确,因为您必须等待消息发送的时间,因此我建议使用clock=asyncio启动计时任务。在函数前创建_任务(asyncio.sleep(delay))并在函数后使用等待时钟捕捉该任务

现在,如果您希望它在每个间隔的某个时间运行,而不仅仅是在启动函数时的某个设置间隔,那么您需要延迟函数的启动,以匹配您设置的时间。您可以使用divmod(time.time(),interval)执行此操作,它返回商和剩余时间以及您的间隔,剩余时间是自上次间隔开始以来的时间。如果要在间隔开始时启动函数,可以使用wait asyncio。Hibernate(间隔剩余)使函数Hibernate到下一个间隔开始。如果你想在这个时间间隔内设定一个时间,你需要把它分成两部分,一部分是关于你设定的时间是否已经过去,另一部分是关于它是否还没有到来。

if remainder < set_time: 
    await asyncio.sleep(set_time - remainder)
else:
    await asyncio.sleep(interval + set_time - remainder)

现在,如果您将所有这些添加到一个函数中,您会得到如下内容(这是我在一个bot中使用的一段代码:

async def reminder(channel, interval, set_time, message):
    await bot.wait_until_ready()
    channel = bot.get_channel(channel)
    quotient, remainder = divmod(time.time(), interval)
    if remainder < set_time:
        await asyncio.sleep(set_time-remainder)
    else:
        await asyncio.sleep(set_time + interval - remainder)
    while True:
        clock = asyncio.create_task(asyncio.sleep(interval))
        await channel.send(message)
        quotient, remainder = divmod(time.time(), interval)
        if remainder-set_time > 1:
            clock.cancel()
            await asyncio.sleep(interval-1)
        await clock

bot.loop.create_task(reminder(774262090801479740, 3600, 3300, "This is the 55th minute of the hour"))
bot.run(TOKEN)

(我知道这不能百分之百地回答问题,但正如您所说,您尝试了botclient这两种解决方案,该解决方案应该适合您)

经和洽
2023-03-14

不和谐。客户端对象没有get\u channel()方法。您必须使用不协调。公会对象:

await client.get_guild(guild_id_here).get_channel(channel_id_here).send("Test")

阅读文档。

 类似资料:
  • 我一直在四处寻找,似乎找不到我用Typescript制作的不和谐机器人的这个问题的答案。我的所有命令都放在它们自己的文件夹中,每个命令都有一个单独的文件。有助于保持井井有条。 我见过有人说 但这给了我并且 实际上,每当有人运行重启命令时,我会尝试在每个文本频道(从列表中给出)发送一条机器人消息,因为不管出于什么原因,人们总是重启机器人。我把它实现为一件有趣的事情,如果有人需要使用它,我会时不时地以

  • 正如标题中提到的,我正在尝试使用我使用discord构建的discord bot向特定频道发送消息。js和Node。js。我正在使用以下代码将消息发送到特定频道:

  • 我做了很多关于如何阻止一个频道使用命令的研究,比如Rythm的黑名单,但是我没有找到,有人能帮我吗?

  • 我最近开始尝试开发一个discord机器人。我以前使用过c,但这是我第一次使用python,所以我对它还是相当陌生。在了解cogs之后,我尝试将其实现到代码中。我制作了一个包含ping命令的简单cog,但是当我尝试运行它时,我得到一个错误,说“客户机”没有被识别。这是cog文件中的代码: 这是主程序的代码。py文件: 我试着把运行正常,但当我尝试在discord上运行ping命令时,控制台中出现错

  • 我在Discord.py上做了一个机器人,我试图设置我想用参数发送消息的频道。代码是这样的: 当我键入通道id而不是arg1时,它可以工作,但是当我键入命令时,不和谐(!发送282772187812)它不工作,我得到这个错误:discord.ext.commands.errors.命令InvokeError:命令引发了一个异常:属性错误:'NoneType'对象没有属性'发送' 提前谢谢。