Open Phanabani opened 3 years ago
Technical stuff:
discordpy's tasks run at set intervals. I want them to run at the same time every day (midnight UTC), so upon startup, we can run our daily task once, then schedule the next task run in (midnight - now) hours.
Actually, does it really matter what time the task runs? As long as we ensure a 24 hour interval, we should be able to cover all birthdays.
Our daily task should query the database for all birthdays within the next 24 hours. This should be a sorted list. We can then I don't trust how this function uses await discord.utils.sleep_until
each of them in order.datetime.now
, so I'll implement it myself using my utc_now
function.
I was considering storing the birthdays as a datetime converted to UTC in the database, but I think that's both inefficient in terms of space and added complexity because it would have to be recalculated whenever either the birthday date changes OR the timezone changes.
With this on-the-fly calculation of localized birthday datetimes, we just need to select dates which are either the current date or the next day (e.g. South Korea at 23:00 UTC is the next day), then we can convert their localized midnight to UTC and determine if they're within the next 24 hours. We don't need to check the previous day (e.g. Americas being several hours behind UTC) because we will have hit it already the previous day.
So, in summary:
Edit: I intended on doing this entire procedure in the database adapter, but I think it should only expose a get_birthdays
interface which does no post-processing and returns the data for a given day. We can handle the processing elsewhere.
Don't announce birthdays of users not in the guild anymore. This ties in to #39. Under normal circumstances, you'd expect the user to be deleted from the table, but we're considering allowing them to leave their data in Sandpiper in case they left the server temporarily for some reason.
Enable/disable sending their birthday notification Setting to display age in notif? Maybe this could be controlled by age privacy
I'm reconsidering these two issues. I think it's most logical to have the privacy settings control what data gets accessed by the birthday alerts module. For example:
However, is it intuitive that having your age as public means it will be announced? It doesn't seem so, and I think many people might not enjoy having their age displayed like this. The solution I was already thinking about is to add a NEW setting for displaying age, but that seems redundant/extraneous along with the privacy.
We could instead give more explicit hints to the user about what's going on when they set their data. For example, here's a diagram of possible a command flow:
Birthday privacy == private
Birthday privacy == public
Age privacy == private
Age privacy == public
Birthday privacy == private
Birthday privacy == public
Birthday privacy == private
Birthday privacy == public
Age privacy == private
Age privacy == public
I think this is a state machine. It probably doesn't need to be more complicated than a few nested conditionals but maybe look into that.
Define custom birthday messages in config!
Handle user adding their birthday or editing birthday privacy within 24 hours of it starting.
Role to allow changing guild settings?Just check admin perms