-
Notifications
You must be signed in to change notification settings - Fork 0
Staff Roles
SquishyBot manages 7 staff roles in Discord and a request flow that lets members ask for one of them, with admin approval. The bot grants the linked Discord role on approval — admins don't have to add it by hand.
| Role | bot_settings key | customId slug |
|---|---|---|
| Tier 1 | staff.role.tier_1 |
tier_1 |
| Tier 2 | staff.role.tier_2 |
tier_2 |
| Tier 3 | staff.role.tier_3 |
tier_3 |
| Help Desk | staff.role.help_desk |
help_desk |
| Onsites | staff.role.onsites |
onsites |
| Security | staff.role.security |
security |
| Leadership | staff.role.leadership |
leadership |
The canonical registry lives in src/services/staffRoles.ts and is shared between the /sudo → Settings → Staff Roles sub-panel and the commands/staff.ts request flow.
A nested panel under /sudo → Settings. For every slot, the panel shows one status line:
| Marker | Meaning |
|---|---|
| ✅ | Linked in bot_settings and the role exists in Discord |
| Linked, but the saved role ID no longer exists in Discord (stale) | |
| 🔗 | Not linked, but a Discord role with the matching name exists |
| ❌ | Not linked + no Discord role with that name |
-
🛠 Provision & link — idempotent. For each of the 7 slots:
- If the slot is already linked and the role still exists, leave it alone.
- Else, look for an existing Discord role by name; if found, link it into
bot_settings. - Else, create the role (
hoist: true,mentionable: false, no permissions, no color). - After all 7 are resolved, bulk-set positions so the slots sit one above the highest existing game role position, in this order: Tier 1 → Tier 2 → Tier 3 → Help Desk → Onsites → Security → Leadership (Leadership ends up on top).
The button reports back what was created vs. linked vs. already OK in an ephemeral follow-up.
-
♻️ Clear links — wipes the seven
bot_settingskeys. The Discord roles themselves are untouched, and Provision & link will re-link them by name on the next click.
The request entry point is /settings → Staff Role (the Staff Requests section of /help explains the flow and points members there). The flow:
-
/settings → Staff Role→ Request a Staff Role (settings:staff_role→open_staff_request) → bot replies ephemerally with a Components V2 picker listing the 7 staff roles by label. -
staff:role_pickstring-select → bot opens a small modalstaff:request:{slug}with two fields:- Real / preferred name (optional)
- Why are you requesting this role? (optional, paragraph)
-
staff:request:{slug}modal submit → bot inserts astaff_approvalsrow with:{ "role_key": "staff.role.help_desk", "role_label": "Help Desk", "real_name": "...", "reason": "..." }and posts an approval card in the configured staff approvals thread (
STAFF_APPROVAL_THREAD_ID, also overridable via/sudo → Settings → Channels → Staff approval thread). The card is preceded by a separate ping message toSTAFF_APPROVAL_PING_USER_ID(the role label is included in the ping content so reviewers see what's being asked for at a glance). -
staff:approve:{id}button (sudo only) → bot:- Marks the row
approved. - Resolves
role_key→getSetting()→ Discord role ID →Roleobject. - Fetches the requester as a
GuildMemberand callsmember.roles.add()with a reason string"staff request approved by {reviewer}". - Edits the approval card to show the outcome (
🎖️ Granted X to @user/ℹ️ already had X/⚠️ unlinked/⚠️ <discord error>), removes the buttons, and DMs the requester the same outcome line.
- Marks the row
-
staff:deny:{id}button (sudo only) → marks the rowdenied, edits the card with the Deny styling, and DMs the requester.
| Situation | What happens |
|---|---|
STAFF_APPROVAL_THREAD_ID unset |
Submit replies "Staff approval thread is not configured. Ask an admin to set STAFF_APPROVAL_THREAD_ID." |
Picked role's bot_settings key has no value |
Approval still flips to approved, but the card shows ⚠️ Role X is not linked yet. Run /sudo → Settings → Staff Roles → Provision & link first, then re-grant manually.
|
| Linked role ID was deleted in Discord | ⚠️ Linked role for X (id ...) no longer exists in Discord. |
| Requester left the server before approval | ⚠️ Could not fetch <@id> — they may have left the server. |
| Bot lacks Manage Roles, or the role is above the bot's top role | ⚠️ Failed to grant X: <discord error>. |
Legacy approval row (no role_key, e.g. created before the redesign) |
Card renders all the original free-text fields and DM is sent, but no role is granted automatically. The note _⚠️ Legacy request — no role was granted automatically. Add the role manually._ appears on the card. |
staff_approvals is unchanged from the legacy flow:
| Column | Notes |
|---|---|
id |
uuid |
guild_id |
text |
user_id |
requester |
requested_data |
jsonb — new flow stores { role_key, role_label, real_name, reason }; legacy rows still have { category, department, tier, real_name, reason }
|
approval_msg_id |
message ID of the card in the approvals thread |
status |
pending / approved / denied
|
reviewed_by |
reviewer's user ID |
review_note |
currently unused |
created_at / reviewed_at
|
timestamps |