Discord.py Bot 每天在特定时间运行功能

问题描述 投票:0回答:6

我正在使用discord.py 创建一个discord 机器人,我需要每天在特定时间执行某些操作。我看到了这个答案:如何在discord.py rewrite中进行循环?到目前为止我一直在使用它。

当我在 heroku 免费计划上托管我的机器人时,问题就开始了。 Heroku 上的服务器每天至少重置一次,这会弄乱计时器,如该帖子所示。

我还看到了schedule图书馆。问题在于它似乎使用了无限循环。这不会阻止我在 24 小时内运行其他任何操作吗?除了每 24 小时发送一次消息之外,机器人还需要能够随时响应命令。

即使服务器重置,如何每天在特定时间执行操作?预先感谢您!

python heroku discord.py scheduler
6个回答
8
投票

您可以编写一个函数在不同的线程上定期运行,并检查是否是发送消息的正确时间,如下例所示:

from datetime import datetime
import threading


def checkTime():
    # This function runs periodically every 1 second
    threading.Timer(1, checkTime).start()

    now = datetime.now()

    current_time = now.strftime("%H:%M:%S")
    print("Current Time =", current_time)

    if(current_time == '02:11:00'):  # check if matches with the desired time
        print('sending message')


checkTime()

4
投票

我知道我迟到了,但这可能对未来的用户有帮助。
有一个名为

APScheduler
的库,可用于通过设置 cron 作业来运行函数(除了 cron 之外,还有其他方法。阅读更多)。

一个小例子如下:

import discord
from discord.ext import commands

from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger

class Scheduler(commands.Cog):
    """Schedule commands."""
    def __init__(self, bot):
        self.bot = bot

        # Initialize session
        self.session = aiohttp.ClientSession()
    
    # Scheduled events
    async def schedule_func(self):

    def schedule(self):
        # Initialize scheduler
        schedule_log = logging.getLogger("apscheduler")
        schedule_log.setLevel(logging.WARNING)

        job_defaults = {
            "coalesce": True,
            "max_instances": 5,
            "misfire_grace_time": 15,
            "replace_existing": True,
        }

        scheduler = AsyncIOScheduler(job_defaults = job_defaults, 
                          logger = schedule_log)

        # Add jobs to scheduler
        scheduler.add_job(self.schedule_func, CronTrigger.from_crontab("0 * * * *")) 
        # Every hour

并在我们的

main.py
文件中添加此内容(显然是在导入
schedule_jobs.py
文件之后):

# Start scheduled commands
scheduler = schedule_jobs.Scheduler(bot).schedule()
scheduler.start()

2
投票

heroku 免费计划是 Linux。因此,cron将让您在特定时间运行事物,而/etc/init.d/将让您在启动时运行事物。了解您的操作系统是一件好事。


1
投票

您是否考虑过使用多线程来运行您的程序?您可以让一个线程等待您想要的时间,而另一个线程则运行程序的其余部分。 以下是一些可帮助您入门的文档:Python 线程简介线程文档


0
投票

您可以使用discord.ext.tasks

import datetime

import pytz
from discord.ext import commands, tasks

time = datetime.time(hour=9, minute=40, tzinfo=pytz.timezone("Europe/Prague"))


class DailyAction(commands.Cog):
    def __init__(self, bot) -> None:
        self.bot = bot
        self.my_task.start()

    @tasks.loop(time=time)
    async def my_task(self) -> None:
        print("This should trigger everyday at 9:40 AM (CET)")


async def setup(bot) -> None:
    await bot.add_cog(DailyAction(bot))

查看文档了解更多详细信息。

Heroku 也有自己的调度程序,此答案中的更多信息


-1
投票

您可以有一个无限循环并使用 asyncio.sleep() 函数。这允许您从脚本中的任何位置处理命令并且仍然等待时间。这是一个小例子:

import asyncio

while True:
    await asyncio.sleep(60)
    print(1)

@client.command()
async def command(ctx):
    pass

脚本每分钟都会打印 1,只要有人执行该命令,它就会执行。

© www.soinside.com 2019 - 2024. All rights reserved.