Skip to content

Bot Owner

Jason Tucker edited this page May 12, 2026 · 3 revisions

Bot Owner Permissions

Some /sudo features (hub server-wide lockdown, future feature flags + force-clear-caches, etc.) require bot owner authority — a stricter level than sudo. Sudo can edit settings; bot owners can pull kill switches.

Resolution

src/services/botOwner.ts resolves bot-owner status dynamically:

  1. Reads client.application.owner. When the bot belongs to a Team on the Discord dev portal, this is a Team (not a User), and Team.members enumerates everyone with access.
  2. Team Admins and Developers count as bot owners. Read-only members do not.
  3. The team's own ownerId is always included regardless of their TeamMember role.
  4. BOT_OWNER_ID env is always added as a fallback so the bot keeps working before a Team is set up.

The resolved ID set is cached for 60 s, pre-warmed on READY, and logged so misconfiguration is obvious:

🟢 Bot owners (3): 117501528641634310, 484484232199012352, 539266131651854336

If no owners resolve, the bot logs a warning:

🟡 Bot owners: none resolved. Set BOT_OWNER_ID env or assign Admins/Developers on the Discord dev portal Team.

Setting up a Team

To use the team-based path:

  1. Open the Discord dev portal and the SquishyBot application.
  2. Under Teams, create or attach a team for the bot.
  3. Add team members and assign Admin or Developer roles to anyone you want to grant bot-owner authority.
  4. Restart the bot (or wait up to 60 s for the cache to refresh).
  5. Verify in the startup log that the resolved IDs match what you expect.

API

import { isBotOwner, getBotOwnerIds, invalidateBotOwnerCache } from '../services/botOwner'

// Gate a bot-owner-only action
if (!await isBotOwner(client, userId)) {
  await interaction.reply({ content: '❌ Bot-owner-only.', ephemeral: true })
  return
}

// Get the full set (e.g. for fan-out DMs)
const ids = await getBotOwnerIds(client)

invalidateBotOwnerCache() forces the next call to re-fetch from Discord — useful right after editing team membership.

Current bot-owner-only surfaces

Surface Function
/report Approve / Reject buttons Only bot owners can approve or reject reports
/sudo → Hub Channels → 🚨 Lockdown → Lock all (15 m / 1 h / 4 h) Server-wide hub kill switch
/sudo → Hub Channels → 🚨 Lockdown → Unlock all Lift server-wide lockdown
/sudo → Settings → Debug → Feature flags Per-feature runtime kill switches
/sudo → Settings → Debug → Force-clear caches Reload settings / games / social feeds / bot-owner cache
/sudo → Settings → Debug → Orphan resource scan → Clean up orphan rows Delete fully-orphaned DB rows

Debug sub-panel

/sudo → Settings → Debug is visible to any sudo but the action buttons gate on isBotOwner(). Three things live here:

  1. Feature flags — Each toggle gates a feature path at runtime:
    Flag Gates
    feature.auto_voice handleHubJoin (existing auto-channels keep working when off)
    feature.auto_threads messageCreate maybeAutoThread
    feature.social_poller social/poller runPoll
    feature.presence_renames presenceUpdate
    feature.birthday_pings birthdayScheduler runForDate
    feature.color_roles reserved for #38; default OFF
  2. Force-clear caches — One button calls loadSettings, loadGames, loadSocialFeeds, and invalidateBotOwnerCache. Equivalent to a hot reload of the cache layer without a process restart.
  3. Orphan resource scan — Walks auto_channels, hub_channels, auto_thread_channels, games, archived_channels and reports rows whose Discord channels/roles are no longer in guild.channels.cache / guild.roles.cache. Cleanup deletes rows where every reference is gone; partial-orphan rows (e.g. a game whose ping_role_id is missing but channel still exists) are left intact so they can be edited via the Games panel.

Planned additions (see Feature Roadmap / GH project board):

  • Unlimited social-feed throttle (issue #29; non-owners capped at 3)
  • Sudo /report triage view (issue #24; bot-owner gated)

Clone this wiki locally