-
Notifications
You must be signed in to change notification settings - Fork 0
Bot Owner
Jason Tucker edited this page Jun 5, 2026
·
3 revisions
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.
src/services/botOwner.ts resolves bot-owner status dynamically:
- Reads
client.application.owner. When the bot belongs to a Team on the Discord dev portal, this is aTeam(not aUser), andTeam.membersenumerates everyone with access. - Team Admins and Developers count as bot owners. Read-only members do not.
- The team's own
ownerIdis always included regardless of their TeamMember role. -
BOT_OWNER_IDenv 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.
To use the team-based path:
- Open the Discord dev portal and the SquishyBot application.
- Under Teams, create or attach a team for the bot.
- Add team members and assign Admin or Developer roles to anyone you want to grant bot-owner authority.
- Restart the bot (or wait up to 60 s for the cache to refresh).
- Verify in the startup log that the resolved IDs match what you expect.
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.
| 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 |
/sudo → Settings → Debug is visible to any sudo but the action buttons gate on isBotOwner(). Three things live here:
-
Feature flags — Each toggle gates a feature path at runtime:
Flag Gates feature.auto_voicehandleHubJoin(existing auto-channels keep working when off)feature.auto_threadsmessageCreate maybeAutoThreadfeature.social_pollersocial/poller runPollfeature.presence_renamespresenceUpdatefeature.birthday_pingsbirthdayScheduler runForDatefeature.auto_role_on_joinguildMemberAddauto-role apply; default OFF (#36)feature.color_roles/colorpicker; default OFF (#38) -
Force-clear caches — One button calls
loadSettings,loadGames,loadSocialFeeds, andinvalidateBotOwnerCache. Equivalent to a hot reload of the cache layer without a process restart. -
Orphan resource scan — Walks
auto_channels,hub_channels,auto_thread_channels,games,archived_channelsand reports rows whose Discord channels/roles are no longer inguild.channels.cache/guild.roles.cache. Cleanup deletes rows where every reference is gone; partial-orphan rows (e.g. a game whoseping_role_idis 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
/reporttriage view (issue #24; bot-owner gated)