#Schedule Bot Message command

1 messages · Page 1 of 1 (latest)

quiet elbow
#

Hi, I'm looking to make a command that'll schedule a message to be sent by the bot sometimes in the future. Was wondering if there's something to do such thing.

My first thought was to store the message in the database along with the send_date (year, month, day, hour, minute) and have a function that runs each minute and checks if there's any message to be sent in that minute.
I could go even further to optimise it and have it go every 24h and check if there's any message to be sent in the current day, if yes then add it to a queue and every minute I'd just check that queue.

Another alternative, but this one might be a bit over my programming skills, would be to create some "Task Factory", to which I can pass a date and time and it'll create a task to be launched at the exact date I'm saying; am not entirely sure how I'd make it and if it's worth the trouble.

Has anyone implemented something similar and what was your solution idea to the problem?

#

Found this, might help with what I need, I'll try an implementation and come back later if it worked: https://stackoverflow.com/a/21392114

quiet elbow
#

For anyone looking for a solution, that Scheduler actually worked and it does exactly what I need. Here's an example on how to use it:

from apscheduler.schedulers.asyncio import AsyncIOScheduler
from datetime import datetime

scheduler = AsyncIOScheduler()

async def send_announcement(self, ctx):
        await ctx.respond(content=f"Test", ephemeral=True)

@command(name="send")
async def send(self, ctx, date: Option(str, description="When to send the message (EST time). FORMAT: YYYY-MM-DD HH:mm")):
  date = datetime.strptime(date, '%Y-%m-%d %H:%M')
  await ctx.respond(content=f"Message scheduled for {date}.", ephemeral=True)
  job = scheduler.add_job(send_announcement, 'date', run_date=date, args=[ctx])

Might need a few modifications, I adapted my code to something more generic, outside a cog.

#

I'd say it's much better than the tasks loop or asyncio sleep; in any case what anyone going this way might want to consider, is have all jobs stored somewhere on creation and deleted upon completion, in case the bot goes down. I myself am storing them in a DB

tawny ember
#

The concept behind this bot was that servers can schedule events that allow people to queue or sign up, and then the events automatically start at the scheduled time.

#

Perhaps that clarifies some of what’s going on. Could easily be adapted.

quiet elbow
# tawny ember https://codeshare.io/Pd3VmQ

I mean, the asyncio task loop was my first thought, but it's not really a nice thing to do when there are many scheduled events. It's the reason I wanted to figure out something different, to avoid running loops that can execute in a longer time than they're being called in, eating all machine's memory.
Also am not sure if that note is still valid, but not being able to have multiple schedules at once might be annoying (unless it was a choice you've made).
And I'd say the Scheduler option is pretty easy to implement and understand, providing much clearer code too, yours might need some refactoring to be easier to read (might also affect time execution).

tawny ember
#

Yep, the solution you found is probably preferable. That being said, it is not magical. It is looping in the background checking if its time to run the scheduled task.

#

But it does make the code cleaner, and less prone to bugs.

#

As for loops that can execute in a longer time than being called, not an issue. Just do asyncio.create_task. Unless your code is blocking in a lengthy way, in which case no scheduler can save you from that.