The Notifications feature lets server members subscribe and unsubscribe from notification roles entirely by themselves — no moderator action required. All interaction is ephemeral, so only the member using the command can see the UI.
How it works
Run /notifications
Any server member runs /notifications. The bot responds with an ephemeral multi-select dropdown listing every available notification role.
Pick your roles
Select or deselect roles in the dropdown. The roles you currently hold are pre-selected. You can choose any combination, including none.
Changes apply immediately
When you confirm the selection the bot adds and removes roles in parallel. The message updates to reflect the new state.
Which roles appear
Only roles whose name starts with the 🔔 prefix are shown. This lets server administrators control which roles appear in the dropdown by simply naming them with the bell emoji.
const notificationRoles = Effect.fnUntraced(function* (guildId: string) {
const roles = yield* rolesCache.getForParent(guildId)
return Array.fromIterable(roles.values()).filter((role) =>
role.name.startsWith("🔔 "),
)
})
The notification message
The message function builds the UI component tree that is sent (or updated) in response to the command and each subsequent selection:
const message = Effect.fn("Notifications.message")(function* (
ix: Discord.APIInteraction,
userRoles?: Array<string>,
) {
const guildId = ix.guild_id
if (!guildId) {
return UI.components(
[UI.textDisplay("This command can only be used in a server.")],
{ ephemeral: true },
)
}
const roles = yield* notificationRoles(guildId)
if (roles.length === 0) {
return UI.components(
[UI.textDisplay("No notification roles found in this server.")],
{ ephemeral: true },
)
}
userRoles = userRoles ?? ix.member!.roles
return UI.components(
[
UI.textDisplay("Select the notifications you want to receive:"),
UI.row([
UI.select({
custom_id: "notifications_role",
placeholder: "No notifications selected",
min_values: 0,
max_values: roles.length,
options: roles.map((role) => ({
label: role.name,
value: role.id,
default: userRoles.includes(role.id),
})),
}),
]),
],
{ ephemeral: true },
)
})
The entire response is ephemeral — other members never see which roles you selected.
Setting up notification roles
To make a role appear in the /notifications dropdown, rename it so its name starts with 🔔 (bell emoji followed by a space). For example:
🔔 Releases
🔔 RFCs
🔔 Community calls
Roles without the prefix are ignored entirely.