Files
erika/docs/integrations/leaderboard-bot.md
T

2.0 KiB
Raw Blame History

Leaderboard bot integration

The Discord bot owns all writes to user_levels and voice_time. The website only subscribes to notifications and then reads the committed database state.

Redis channel

Publish leaderboard notifications to exactly:

erika:sse:leaderboards

The bot and website use the same Redis deployment. Do not add Redis credentials to source code or event payloads.

Event envelopes

XP changes use this exact JSON envelope:

{"event":"xp","data":{}}

Voice-time changes use the affected Discord channel ID:

{"event":"vc","data":{"channelId":"123456789012345678"}}

No additional envelope or data fields are accepted. channelId is a Discord snowflake represented as a decimal string.

Publish ordering

  1. Start and complete the bot’s database transaction.
  2. Confirm that the transaction committed successfully.
  3. Publish the corresponding Redis event or events.

Never publish before commit, from a rollback path, or from a finally block. The notification tells an open website page to read the database again, so publishing before commit can produce a stale refresh.

Event cardinality

  • Publish one XP event when one transaction changes XP data.
  • Publish one VC event per affected channel when one transaction changes voice time.
  • When one transaction changes both XP and voice time, publish one XP event and one VC event for each affected channel.
  • For a bulk transaction, deduplicate affected scopes and channel IDs. Publish per affected scope/channel, never per user.

Example: a bulk transaction changes XP for 200 users and voice time in channels 111 and 222. After commit, publish three events: one XP event, one VC event for 111, and one VC event for 222.

Error handling

Publishing is best-effort. Log Redis failures with enough context to identify the event scope, but do not roll back or report a successfully committed database transaction as failed. Open pages recover on SSE reconnection or the next navigation.