Sooner or later your bot needs to do something without being asked: post a daily message, clear an old channel, check an external service. All the libraries make this easy, and all three of the usual mistakes are about what happens when the bot is not running.
The tools
| Approach | Good for |
|---|---|
| The library's own task loop | Anything on a fixed interval. It starts and stops with the bot. |
| A cron-style scheduler | «Every day at nine» rather than «every 24 hours». |
| A panel schedule running a command | Things that should happen even if the bot process is unhealthy. |
The three mistakes
- Assuming an interval is a clock
«Every 86400 seconds» drifts: it counts from when the bot started, so a restart at 3 p.m. moves your 9 a.m. post to 3 p.m. forever. If the time matters, use a scheduler that knows about times, not intervals.
- Not knowing which timezone you are in
A server does not necessarily run in your local time. «Nine in the morning» is nine somewhere; check where, and set it explicitly rather than discovering it in the morning.
- Losing the run that happened while it was down
A bot that was restarting at nine simply misses nine. If a task must not be skipped, record the last successful run and check on startup whether one is owed.
A cleanup job that deletes messages one at a time, or an announcement that posts to fifty channels in a tight loop, hits the limits described in the rate-limit article. Batch where the API allows it, and space out what you cannot batch — the task is not urgent, so let it be slow.
«Daily task completed at 09:00» is one line and it answers «did it run?» instantly, forever. Without it, the only evidence a task ran is whether its effect is visible, which is not the same thing at all.
Set the task to a minute from now, watch it fire, then restart the bot and confirm it still fires on schedule rather than one minute after startup.