簡體   English   中英

Python:通過 cog 和后台任務將消息發送到 Discord 中的特定通道

[英]Python: Send message to specific channel in Discord via cog and background task

我有一個 Discord Python 機器人,我正在嘗試運行一個后台任務,該任務將每隔 X 秒不斷地向頻道發送一條消息 - 不需要命令。 目前有任意 5 秒用於測試目的。

這是有問題的 cog 文件(為提高效率而刪除了導入和其他內容)

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() (但就我所閱讀的內容而言,我不應該使用我一直試圖避免的那個。

在其他使用實際命令的 cogs 中,我將其設置如下:

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

這就是讓我相信我傳遞的參數是錯誤的。 我明白,因為我正在傳遞 ctx 我可以獲取頻道名稱,但我不太確定如何僅使用 self. 嘗試傳遞 ctx 參數時,我沒有收到任何錯誤,但由於明顯的原因,消息沒有發送。

我到底在這里想念什么? 我很感激任何幫助!

discord.Client object 沒有get_channel()方法。 您必須使用discord.Guild object 代替:

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

閱讀文檔

您可以使用.loop.create_task(mytask(arguments))將任務添加到異步循環中,您將在啟動機器人之前調用該任務。 在此處閱讀有關 asyncio 的所有信息

您將任務定義為使用async def mytask(argument)的普通命令,但是忽略 ctx,因為 ctx 基本上是您通常會獲得的有關用於調用 function 的命令的所有上下文。 相反,您需要使用頻道 id 手動獲取頻道 object 與channel = bot.get_channel(id) ,然后您可以執行await channel.send("Your message")向所述頻道發送消息。

要讓它循環,只需使用帶有asyncio.sleep(delay)while True循環來計時。 由於您必須等待消息發送,這可能會導致計時不准確,因此我建議您在 function 前面使用clock = asyncio.create_task(asyncio.sleep(delay))開始計時任務並抓住它在您的 function 與await clock之后

現在,如果您希望它在每個間隔的某個時間運行,而不僅僅是從您啟動 function 時開始的設定間隔,您需要延遲 function 的啟動以匹配您設置的時間。 您可以使用divmod(time.time(), interval)來執行此操作,它返回商和剩余時間以及間隔,剩余時間是自上次間隔開始以來的時間。 如果您想在間隔開始時啟動 function,您可以使用await asyncio.sleep(interval-remainder)使 function 休眠直到下一個間隔開始。 如果您想在該時間間隔內設置一個時間,您需要將其分成兩部分,一個用於您設定的時間已過,另一個用於您的設置時間尚未到來。

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

現在,如果您將所有這些添加到一個 function 中,您會得到類似這樣的內容(這是我在我的機器人中使用的一段代碼:

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)

(我知道這不是 100% 回答問題,但正如你所說,你嘗試了botclient ,這個解決方案應該適合你)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM