fix(discord): de-dupe allowed_mentions roles/users to avoid silent 400#5
Merged
Merged
Conversation
When two plans share one Discord role (e.g. Claude Standard + Premium both mapped to @claude), the billing-opened notice built allowed_mentions.roles with the role id twice. Discord treats roles/users as unique sets and 400s on duplicate snowflakes; createChannelMessage swallows non-2xx as null, so the notice silently never sent. De-dupe both arrays via Set. Also hardens the overdue users array against the same latent bug. Adds regression tests.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When two plans share the same Discord role id (e.g. Claude Standard and Claude Premium both mapped to a single
@Clauderole), the billing-opened notice silently failed to send.Root cause
sendBillingOpenedbuilds onelinesentry per active plan, then maps each line'srole_idintoallowed_mentions.roleswithout de-duping:Discord treats
allowed_mentions.roles/.usersas unique sets and returns HTTP 400 Invalid Form Body (code 50035) on duplicate snowflakes.createChannelMessagemaps any non-2xx response tonull(if (!res.ok) return null), so the failure is completely silent — the notice just never appears, no log, no throw.Affects both the cron auto-open path and admin
/發起繳費. The overdue path (sendOverdue) usesusersgrouped per-member so it's not hit today, but shares the same un-deduped shape.Fix
De-dupe both arrays with
Set:rolesinsendBillingOpened(the actual bug)usersinsendOverdue(defensive — kills the latent twin)Per-plan display is unchanged: the content still renders one mention line per plan (the role is still only pinged once).
Tests
allowed_mentions.rolesis["claude"](not["claude","claude"]), and the content still shows the mention on both plan lines.usersde-duped.