You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This gives clear startup/online status messages while keeping logs simple for non-technical operators.
183
183
If port `3000` is busy, the bot tries the next available ports automatically (up to `PORT_RETRY_ATTEMPTS`).
184
184
185
+
### Running in multiple servers (optional)
186
+
187
+
Most users run TitanBot on a **single server** with `GUILD_ID` set (default tutorial setup). If you want slash commands to work in **every server** the bot is invited to, opt in with:
188
+
189
+
```env
190
+
MULTI_GUILD=true
191
+
```
192
+
193
+
Notes for multi-server mode:
194
+
-`GUILD_ID` is not used for command registration when `MULTI_GUILD=true` (you can leave it set or remove it)
195
+
- Global slash commands may take up to about an hour to propagate on first deploy
196
+
- Each server still has **isolated** config, economy, tickets, leveling, and other data
197
+
- In the [Discord Developer Portal](https://discord.com/developers/applications), ensure your bot is not restricted to a single guild if you plan to invite it elsewhere
198
+
- Generate an OAuth2 invite URL from the [Discord Developer Portal](https://discord.com/developers/applications) (OAuth2 → URL Generator, scopes: `bot` and `applications.commands`)
199
+
185
200
4.**Setup PostgreSQL Database** (Optional but recommended)
embeds: [errorEmbed('This command can only be used in a server.')],
108
-
flags: ["Ephemeral"],
109
-
});
106
+
returnawaitreplyUserError(interaction,{type: ErrorTypes.UNKNOWN,message: 'This command can only be used in a server.'});
110
107
}
111
108
112
109
const{ options, guild, member }=interaction;
@@ -140,10 +137,7 @@ export default {
140
137
asyncfunctionhandleSetup(interaction){
141
138
142
139
if(interaction.deferred||interaction.replied){
143
-
returnInteractionHelper.safeReply(interaction,{
144
-
embeds: [errorEmbed('This interaction has already been processed. Please try the command again.')],
145
-
flags: ["Ephemeral"],
146
-
});
140
+
returnawaitreplyUserError(interaction,{type: ErrorTypes.UNKNOWN,message: 'This interaction has already been processed. Please try the command again.'});
147
141
}
148
142
149
143
constmodal=newModalBuilder()
@@ -226,10 +220,7 @@ async function handleSetup(interaction) {
226
220
constroleId=selectedRoles.first()?.id;
227
221
228
222
if(!roleId){
229
-
awaitsubmitted.reply({
230
-
embeds: [errorEmbed('No Role Selected','You must select a role for the application.')],
231
-
flags: ['Ephemeral'],
232
-
});
223
+
awaitreplyUserError(submitted,{type: ErrorTypes.USER_INPUT,message: 'You must select a role for the application.'});
233
224
return;
234
225
}
235
226
@@ -241,19 +232,13 @@ async function handleSetup(interaction) {
"No applications found and no application roles configured.\n"+
575
-
"Use `/app-admin roles add` to configure application roles first."
576
-
),
577
-
],
578
-
flags: ["Ephemeral"],
579
-
});
545
+
returnawaitreplyUserError(interaction,{type: ErrorTypes.CONFIGURATION,message: '"No applications found and no application roles configured.\\n" +\n "Use `/app-admin roles add` to configure application roles first."'});
580
546
}
581
547
}
582
548
@@ -624,10 +590,7 @@ export async function handleApplicationReviewModal(interaction) {
`You already have a pending application. Please wait for it to be reviewed.`,
314
-
),
315
-
],
316
-
flags: ["Ephemeral"],
317
-
});
291
+
returnawaitreplyUserError(interaction,{type: ErrorTypes.UNKNOWN,message: 'You already have a pending application. Please wait for it to be reviewed.'});
0 commit comments