feat(events): auto-sync AOTW Discord winner roles - #5205
Conversation
| $grant->update(['expires_at' => $current->active_until]); | ||
|
|
||
| continue; | ||
| } |
There was a problem hiding this comment.
What is this trying to do? I assumed it was trying to extend the grant if the user earned the new AotW within the first few minutes of the last one expiring, but the expires_at->isFuture() would be false for that case.
There was a problem hiding this comment.
The $grant->update() is there to handle the off-chance that an end date for an AOTW event achievement changes. This may be overly-defensive.
The continue within the conditional is there so we don't constantly remove and re-add roles a user should have during each sync attempt.
There was a problem hiding this comment.
I got the general idea that it's an update and ignore. I just wasn't sure why.
I think the only time the AotW has ever been extended was due to a server outage, but I don't see any reason to remove the code since you've already written it.
| $roleId, | ||
| shouldHaveRole: false, | ||
| reason: "AOTW winner removed: {$grant->user->display_name}", | ||
| ); |
There was a problem hiding this comment.
If the user does earn the new AotW within a few minutes of the old one expiring, the role will be revoked here, then immediately restored when the $winners loop is processed.
There was a problem hiding this comment.
That's true. I wasn't sure if that was worth fixing - it seems unlikely to happen often and I wasn't sure if it was worth the complexity trade-off to address.
There was a problem hiding this comment.
The AotW is supposed to take about 2 hours to earn, but there seems to be people who always start playing before the achievement is announced, so they get the AotW shortly after it is announced. This week it only took about 20 minutes:

I agree that it's probably not worth the effort if that's not what the other block was trying to address. Besides, sending the notification would further complicate any attempts to be smart about recycling the row.
There was a problem hiding this comment.
Yeah, I've seen it happen usually at least once a week and they to ping someone to re-add it, but this is because the bot adds it before it gets around to removing it.
Another concern was people joining the server after getting the achievement, and thus don't get the role since they missed the assign window, that's a separate issue to this, of course, but unsure if that was also addressed.
This PR allows the web server to sync the AOTW Winner role by reusing Discord API mechanisms we already have working for managing roles for muted users and handling display name changes.
A migration is included in this PR, which creates a
event_winner_discord_role_grantstable. This table is agnostic to the particular event in question, so it could in theory be reused for different events one day.The new table has an
expires_attimestamp field. When that date is surpassed, the role is wiped from all associated users. We cannot make a call to Discord's API that naively says "wipe Role X from all users in our server". This is part of the server intents that Discord no longer allows us to have. Instead, we need to use a lookup table and keep things in sync.When this change goes live, we need to manually remove the AOTW Winner role from everyone on the server so the lookup table can be properly synchronized. We also need to strongly encourage people not to manually assign the role, because it won't be auto-removed when appropriate (as it wont exist in our lookup table).
I've updated the server environments so they have the role ID ready to go.