【问题标题】:discord.py send channel message at specific timediscord.py 在特定时间发送频道消息
【发布时间】:2020-10-22 21:50:29
【问题描述】:

我希望我的不和谐 python 机器人每天在频道中发送特定消息 2 次。首先是欧洲/柏林时间的 12 点,然后是 18 点(或仅从服务器时间开始)。

我是怎么做到的?我尝试了很多方法,但我找不到方法。

【问题讨论】:

    标签: python-3.x discord.py


    【解决方案1】:

    您可以使用APSchedulerCron 将您的消息安排在特定时间发送,例如12:00 AM

    文档:APSchedulerCron

    这是一个例子:

    #async scheduler so it does not block other events
    from apscheduler.schedulers.asyncio import AsyncIOScheduler
    from apscheduler.triggers.cron import CronTrigger
    from discord.ext import commands
    import discord
    
    bot = commands.Bot(command_prefix="!")
    
    async def func():
        await bot.wait_until_ready()
        c = bot.get_channel(channel_id)
        await c.send("Your Message")
    
    @bot.event
    async def on_ready():
        print("Ready")
    
        #initializing scheduler
        scheduler = AsyncIOScheduler()
    
        #sends "Your Message" at 12PM and 18PM (Local Time)
        scheduler.add_job(func, CronTrigger(hour="12, 18", minute="0", second="0")) 
    
        #starting the scheduler
        scheduler.start()
    

    【讨论】:

    • 如果不和谐机器人在网络中断后尝试重新连接,我发现上面这段代码有一点警告。它再次执行on_ready() 导致再次添加func 作业。因此,添加作业的次数与长时间运行的机器人中出现网络中断的次数一样多。
    • 为此,您可以使用on_connect和on_disconnect,您可以删除on_disconnect上的所有作业并在on_connect上注册作业,因为on_ready由于原因可以多次调用
    • 我刚刚将所有内容从on_ready() 移到了外部,例如初始化调度程序并在命令前缀设置下方添加作业以及在bot.run('TOKEN') 之前启动调度程序。我希望没问题,不会造成任何重大问题。
    • 是的,也可以
    【解决方案2】:

    @Just for fun 答案的略微修改版本。我在从discord.loop.create_task() 调用的task() 函数下携带scheduler 和(我调整了cron 条目)。


    解决办法:

    #!/usr/bin/env python3
    
    import logging
    import os
    from pathlib import Path
    
    import discord
    from apscheduler.schedulers.asyncio import AsyncIOScheduler
    from broker._utils.tools import get_dt_time
    from dotenv import load_dotenv
    
    # In case to disable logging
    logging.getLogger("apscheduler.executors.default").propagate = False
    
    class Discord_Bot:
        def __init__(self):
            dotenv_path = Path(".env_secret")
            load_dotenv(dotenv_path=dotenv_path)
            self.client = discord.Client()
            self.TOKEN = os.getenv("TOKEN")
            self.channel_id = int(os.getenv("CHANNEL_ALPY"))
            try:
                self.client.loop.create_task(self.task())
                self.client.loop.run_until_complete(self.client.start(self.TOKEN))
            except SystemExit:
                pass
                # handle_exit()
            except KeyboardInterrupt:
                # handle_exit()
                self.client.loop.close()
                print("Program ended.")
    
        async def task(self):
            scheduler = AsyncIOScheduler()
            scheduler.add_job(self.send_message, "cron", hour="12")
            scheduler.add_job(self.send_message, "cron", hour="18")
            # For test purposes
            scheduler.add_job(self.send_message, "cron", minute="*")  
            scheduler.start()
    
        async def send_message(self, msg=""):
            await self.client.wait_until_ready()
            channel = self.client.get_channel(self.channel_id)
            if not msg:
                msg = f"Tick! The time is: {get_dt_time().strftime('%Y-%m-%d %H:%M:%S')}"
    
            await channel.send(msg)
    
    
    _discord = Discord_Bot()
    

    示例输出:

    [2021-08-01 14:52:40         base.py:445 -               add_job()] Adding job tentatively -- it will be properly scheduled when the scheduler starts
    [2021-08-01 14:52:40         base.py:445 -               add_job()] Adding job tentatively -- it will be properly scheduled when the scheduler starts
    [2021-08-01 14:52:40         base.py:445 -               add_job()] Adding job tentatively -- it will be properly scheduled when the scheduler starts
    [2021-08-01 14:52:40         base.py:886 -         _real_add_job()] Added job "Discord_Bot.send_message" to job store "default"
    [2021-08-01 14:52:40         base.py:886 -         _real_add_job()] Added job "Discord_Bot.send_message" to job store "default"
    [2021-08-01 14:52:40         base.py:886 -         _real_add_job()] Added job "Discord_Bot.send_message" to job store "default"
    [2021-08-01 14:52:40         base.py:171 -                 start()] Scheduler started
    [2021-08-01 14:52:40       client.py:510 -                 login()] logging in using static token
    [2021-08-01 14:52:42      gateway.py:403 -              identify()] Shard ID None has sent the IDENTIFY payload.
    [2021-08-01 14:52:42      gateway.py:494 -      received_message()] Shard ID None has connected to Gateway: ["gateway-prd-main-jqb3",{"micros":37874,"calls":["discord-sessions-green-prd-2-83",{"micros":36893,"calls":["start_session",{"micros":33555,"calls":["api-prd-main-lx4l",{"micros":30479,"calls":["get_user",{"micros":2553},"add_authorized_ip",{"micros":2438},"get_guilds",{"micros":5864},"coros_wait",{"micros":1}]}]},"guilds_connect",{"micros":1,"calls":[]},"presence_connect",{"micros":2743,"calls":[]}]}]}] (Session ID: ff6cc313c16950abadccfab95a02d3a5).
    [2021-08-01 14:53:00     base_py3.py:28 -     run_coroutine_job()] Running job "Discord_Bot.send_message (trigger: cron[minute='*'], next run at: 2021-08-01 14:54:00 UTC)" (scheduled at 2021-08-01 14:53:00+00:00)
    [2021-08-01 14:53:00     base_py3.py:41 -     run_coroutine_job()] Job "Discord_Bot.send_message (trigger: cron[minute='*'], next run at: 2021-08-01 14:54:00 UTC)" executed successfully
    

    【讨论】:

      猜你喜欢
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      相关资源
      最近更新 更多