spacecommands 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +519 -0
- package/dist/Command.js +384 -0
- package/dist/CommandHandler.js +339 -0
- package/dist/FeatureHandler.js +89 -0
- package/dist/SlashCommands.js +220 -0
- package/dist/command-checks/channel-specific.js +30 -0
- package/dist/command-checks/guild-only-check.js +24 -0
- package/dist/command-checks/has-entitlement.js +52 -0
- package/dist/command-checks/has-permissions.js +39 -0
- package/dist/command-checks/has-roles.js +69 -0
- package/dist/command-checks/has-valid-arguments.js +54 -0
- package/dist/command-checks/in-cooldown.js +42 -0
- package/dist/command-checks/is-enabled.js +31 -0
- package/dist/command-checks/is-not-test-only.js +8 -0
- package/dist/command-checks/owner-only-check.js +22 -0
- package/dist/commands/channelonly.js +88 -0
- package/dist/commands/command.js +87 -0
- package/dist/commands/help/!ReactionListener.js +217 -0
- package/dist/commands/help/!get-first-embed.js +57 -0
- package/dist/commands/help/help.js +97 -0
- package/dist/commands/language.js +52 -0
- package/dist/commands/prefix.js +42 -0
- package/dist/commands/requiredrole.js +61 -0
- package/dist/commands/slash.js +102 -0
- package/dist/enums/CommandErrors.js +12 -0
- package/dist/enums/Events.js +9 -0
- package/dist/features/message-upsert.js +15 -0
- package/dist/get-all-files.js +25 -0
- package/dist/handlers/AutoModHandler.js +316 -0
- package/dist/handlers/ComponentHandler.js +110 -0
- package/dist/handlers/ContextMenuHandler.js +113 -0
- package/dist/handlers/EntitlementHandler.js +193 -0
- package/dist/handlers/ModalHandler.js +71 -0
- package/dist/handlers/PollHandler.js +230 -0
- package/dist/index.js +339 -0
- package/dist/message-handler.js +118 -0
- package/dist/models/channel-commands.js +49 -0
- package/dist/models/cooldown.js +51 -0
- package/dist/models/disabled-commands.js +45 -0
- package/dist/models/languages.js +46 -0
- package/dist/models/prefixes.js +46 -0
- package/dist/models/required-roles.js +49 -0
- package/dist/mongo.js +25 -0
- package/dist/permissions.js +39 -0
- package/dist/utils/ComponentBuilder.js +144 -0
- package/dist/utils/InteractionCollector.js +80 -0
- package/messages.json +391 -0
- package/package.json +72 -0
- package/typings.d.ts +276 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 SpaceCommands Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
# SpaceCommands
|
|
2
|
+
|
|
3
|
+
SpaceCommands is a modern, feature-rich Discord.js command handler library. Built on Discord.js v14, it provides an easy-to-use framework for creating Discord bots with slash commands, permissions, cooldowns, and more.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✨ **Modern Discord.js v14** - Built for the latest Discord features
|
|
8
|
+
- 🎯 **Slash Commands** - Full support for Discord's slash commands with autocomplete
|
|
9
|
+
- 📝 **Prefix Commands** - Traditional message-based commands
|
|
10
|
+
- 🔒 **Permission System** - Role and permission-based command restrictions
|
|
11
|
+
- ⏱️ **Cooldown System** - Per-user and global cooldowns with MongoDB persistence
|
|
12
|
+
- 🌍 **Multi-Language Support** - Built-in internationalization
|
|
13
|
+
- 🎨 **Category System** - Organize commands with custom categories
|
|
14
|
+
- 🗄️ **MongoDB Integration** - Optional database support for persistence
|
|
15
|
+
- 📦 **TypeScript Support** - Full TypeScript support with type definitions
|
|
16
|
+
- 🎮 **Interactive Components** - Buttons, select menus, and modals
|
|
17
|
+
- 📋 **Context Menus** - User and message context menu commands
|
|
18
|
+
- 💎 **Premium Features** - Discord entitlement and monetization support
|
|
19
|
+
- 🛠️ **Component Utilities** - Simplified builders and interaction collectors
|
|
20
|
+
- 📊 **Poll Support** - Native Discord polls with result tracking
|
|
21
|
+
- 🛡️ **AutoMod Integration** - Full AutoMod rule creation and management
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
**NPM**
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install spacecommands
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Yarn**
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
yarn add spacecommands
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick Start
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
const { Client, IntentsBitField } = require('discord.js');
|
|
41
|
+
const SpaceCommands = require('spacecommands');
|
|
42
|
+
const path = require('path');
|
|
43
|
+
|
|
44
|
+
const client = new Client({
|
|
45
|
+
intents: [
|
|
46
|
+
IntentsBitField.Flags.Guilds,
|
|
47
|
+
IntentsBitField.Flags.GuildMessages,
|
|
48
|
+
IntentsBitField.Flags.MessageContent,
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
client.on('ready', () => {
|
|
53
|
+
new SpaceCommands(client, {
|
|
54
|
+
commandsDir: path.join(__dirname, 'commands'),
|
|
55
|
+
featuresDir: path.join(__dirname, 'features'),
|
|
56
|
+
testServers: ['YOUR_TEST_SERVER_ID'],
|
|
57
|
+
botOwners: ['YOUR_USER_ID'],
|
|
58
|
+
mongoUri: process.env.MONGO_URI, // Optional
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
client.login(process.env.BOT_TOKEN);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Creating Commands
|
|
66
|
+
|
|
67
|
+
### Slash Command Example
|
|
68
|
+
|
|
69
|
+
```javascript
|
|
70
|
+
module.exports = {
|
|
71
|
+
category: 'Utility',
|
|
72
|
+
description: 'Ping command',
|
|
73
|
+
|
|
74
|
+
slash: true, // or 'both' for slash and prefix
|
|
75
|
+
|
|
76
|
+
callback: ({ interaction }) => {
|
|
77
|
+
return 'Pong!';
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Prefix Command Example
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
module.exports = {
|
|
86
|
+
category: 'Utility',
|
|
87
|
+
description: 'Ping command',
|
|
88
|
+
|
|
89
|
+
aliases: ['pong'],
|
|
90
|
+
|
|
91
|
+
callback: ({ message }) => {
|
|
92
|
+
return 'Pong!';
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Configuration Options
|
|
98
|
+
|
|
99
|
+
| Option | Type | Description | Default |
|
|
100
|
+
|--------|------|-------------|---------|
|
|
101
|
+
| `commandsDir` | string | Absolute path to commands directory | Required |
|
|
102
|
+
| `featuresDir` | string | Absolute path to features directory | Optional |
|
|
103
|
+
| `mongoUri` | string | MongoDB connection URI | Optional |
|
|
104
|
+
| `testServers` | string[] | Guild IDs for testing commands | [] |
|
|
105
|
+
| `botOwners` | string[] | User IDs of bot owners | [] |
|
|
106
|
+
| `defaultLanguage` | string | Default language for messages | 'english' |
|
|
107
|
+
| `ephemeral` | boolean | Slash commands reply ephemerally | true |
|
|
108
|
+
| `showWarns` | boolean | Show warning messages | true |
|
|
109
|
+
| `typeScript` | boolean | Enable TypeScript support | false |
|
|
110
|
+
|
|
111
|
+
## Command Options
|
|
112
|
+
|
|
113
|
+
### Basic Options
|
|
114
|
+
- `category` - Command category for organization
|
|
115
|
+
- `description` - Command description (required for slash commands)
|
|
116
|
+
- `aliases` / `names` - Alternative command names
|
|
117
|
+
- `slash` - Enable as slash command (true, false, or 'both')
|
|
118
|
+
|
|
119
|
+
### Permissions & Access
|
|
120
|
+
- `permissions` / `requiredPermissions` - Required Discord permissions
|
|
121
|
+
- `requireRoles` - Require specific roles
|
|
122
|
+
- `ownerOnly` - Restrict to bot owners only
|
|
123
|
+
- `guildOnly` - Disable in DMs
|
|
124
|
+
- `testOnly` - Only available in test servers
|
|
125
|
+
|
|
126
|
+
### Arguments
|
|
127
|
+
- `minArgs` - Minimum required arguments
|
|
128
|
+
- `maxArgs` - Maximum allowed arguments
|
|
129
|
+
- `expectedArgs` - Argument format string
|
|
130
|
+
- `syntaxError` - Custom error messages per language
|
|
131
|
+
|
|
132
|
+
### Advanced
|
|
133
|
+
- `cooldown` - Per-user cooldown (e.g., "5s", "1m")
|
|
134
|
+
- `globalCooldown` - Global cooldown (minimum 1m)
|
|
135
|
+
- `hidden` - Hide from help command
|
|
136
|
+
- `options` - Slash command options array
|
|
137
|
+
|
|
138
|
+
## Interactive Components
|
|
139
|
+
|
|
140
|
+
SpaceCommands provides full support for Discord's interactive components including buttons, select menus, and modals.
|
|
141
|
+
|
|
142
|
+
### Button Handlers
|
|
143
|
+
|
|
144
|
+
Register button handlers to respond to button clicks:
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
// In your bot initialization
|
|
148
|
+
const instance = new SpaceCommands(client, { ... });
|
|
149
|
+
|
|
150
|
+
// Register a button handler
|
|
151
|
+
instance.componentHandler.registerButtonHandler({
|
|
152
|
+
customId: 'my-button',
|
|
153
|
+
callback: async (interaction, instance) => {
|
|
154
|
+
await interaction.reply('Button clicked!');
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Use regex for dynamic button IDs
|
|
159
|
+
instance.componentHandler.registerButtonHandler({
|
|
160
|
+
customId: /^page-\d+$/,
|
|
161
|
+
callback: async (interaction, instance) => {
|
|
162
|
+
const pageNum = interaction.customId.split('-')[1];
|
|
163
|
+
await interaction.reply(`Showing page ${pageNum}`);
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Select Menu Handlers
|
|
169
|
+
|
|
170
|
+
Handle all types of select menus (string, user, role, channel, mentionable):
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
instance.componentHandler.registerSelectMenuHandler({
|
|
174
|
+
customId: 'role-select',
|
|
175
|
+
callback: async (interaction, instance) => {
|
|
176
|
+
const selectedRoles = interaction.values;
|
|
177
|
+
await interaction.reply(`Selected: ${selectedRoles.join(', ')}`);
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Component Builders
|
|
183
|
+
|
|
184
|
+
Use the simplified component builder utilities:
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
const { ComponentUtils } = require('spacecommands');
|
|
188
|
+
|
|
189
|
+
// Create a button
|
|
190
|
+
const button = ComponentUtils.createButton(
|
|
191
|
+
'my-button',
|
|
192
|
+
'Click Me',
|
|
193
|
+
ButtonStyle.Primary,
|
|
194
|
+
{ emoji: '👋' }
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
// Create a select menu
|
|
198
|
+
const select = ComponentUtils.createStringSelect(
|
|
199
|
+
'my-select',
|
|
200
|
+
'Choose an option',
|
|
201
|
+
[
|
|
202
|
+
{ label: 'Option 1', value: 'opt1' },
|
|
203
|
+
{ label: 'Option 2', value: 'opt2' },
|
|
204
|
+
]
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
// Create an action row
|
|
208
|
+
const row = ComponentUtils.createActionRow(button);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Modals
|
|
212
|
+
|
|
213
|
+
Create and handle modal forms for user input:
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
const { ComponentUtils } = require('spacecommands');
|
|
217
|
+
const { TextInputStyle } = require('discord.js');
|
|
218
|
+
|
|
219
|
+
// Create a modal
|
|
220
|
+
const modal = ComponentUtils.createModal(
|
|
221
|
+
'feedback-modal',
|
|
222
|
+
'Submit Feedback',
|
|
223
|
+
ComponentUtils.createTextInputRow(
|
|
224
|
+
'feedback-text',
|
|
225
|
+
'Your Feedback',
|
|
226
|
+
TextInputStyle.Paragraph,
|
|
227
|
+
{ placeholder: 'Tell us what you think...' }
|
|
228
|
+
)
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
// Show the modal
|
|
232
|
+
await interaction.showModal(modal);
|
|
233
|
+
|
|
234
|
+
// Register a modal handler
|
|
235
|
+
instance.modalHandler.registerModalHandler({
|
|
236
|
+
customId: 'feedback-modal',
|
|
237
|
+
callback: async (interaction, instance) => {
|
|
238
|
+
const feedback = interaction.fields.getTextInputValue('feedback-text');
|
|
239
|
+
await interaction.reply(`Thanks for your feedback: ${feedback}`);
|
|
240
|
+
},
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Context Menu Commands
|
|
245
|
+
|
|
246
|
+
Add user and message context menu commands (right-click menus):
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
instance.contextMenuHandler.registerContextMenu({
|
|
250
|
+
name: 'Get User Info',
|
|
251
|
+
type: ApplicationCommandType.User,
|
|
252
|
+
callback: async (interaction, instance) => {
|
|
253
|
+
const user = interaction.targetUser;
|
|
254
|
+
await interaction.reply(`User: ${user.tag}`);
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
instance.contextMenuHandler.registerContextMenu({
|
|
259
|
+
name: 'Quote Message',
|
|
260
|
+
type: ApplicationCommandType.Message,
|
|
261
|
+
callback: async (interaction, instance) => {
|
|
262
|
+
const message = interaction.targetMessage;
|
|
263
|
+
await interaction.reply(`"${message.content}" - ${message.author.tag}`);
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Autocomplete
|
|
269
|
+
|
|
270
|
+
Add autocomplete suggestions to slash command options:
|
|
271
|
+
|
|
272
|
+
```javascript
|
|
273
|
+
instance.slashCommands.registerAutocomplete('search', async (interaction) => {
|
|
274
|
+
const focusedValue = interaction.options.getFocused();
|
|
275
|
+
const choices = ['apple', 'banana', 'cherry', 'date'];
|
|
276
|
+
|
|
277
|
+
const filtered = choices.filter(choice =>
|
|
278
|
+
choice.startsWith(focusedValue.toLowerCase())
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
await interaction.respond(
|
|
282
|
+
filtered.map(choice => ({ name: choice, value: choice }))
|
|
283
|
+
);
|
|
284
|
+
});
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
## Premium Features
|
|
288
|
+
|
|
289
|
+
Monetize your bot with Discord's entitlement system:
|
|
290
|
+
|
|
291
|
+
### Register SKUs
|
|
292
|
+
|
|
293
|
+
```javascript
|
|
294
|
+
instance.entitlementHandler.registerSKU({
|
|
295
|
+
skuId: '1234567890',
|
|
296
|
+
name: 'Premium Tier',
|
|
297
|
+
description: 'Access to premium features',
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Premium-Only Commands
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
module.exports = {
|
|
305
|
+
category: 'Premium',
|
|
306
|
+
description: 'Premium-only command',
|
|
307
|
+
|
|
308
|
+
// Require specific entitlement
|
|
309
|
+
requiredEntitlements: ['1234567890'],
|
|
310
|
+
|
|
311
|
+
// OR require any active entitlement
|
|
312
|
+
premiumOnly: true,
|
|
313
|
+
|
|
314
|
+
callback: ({ interaction }) => {
|
|
315
|
+
return 'Welcome, premium user!';
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Check Entitlements Programmatically
|
|
321
|
+
|
|
322
|
+
```javascript
|
|
323
|
+
const { hasEntitlement } = await instance.entitlementHandler.hasEntitlement(
|
|
324
|
+
user.id,
|
|
325
|
+
'sku-id'
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
if (hasEntitlement) {
|
|
329
|
+
// Grant premium features
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Interaction Collectors
|
|
334
|
+
|
|
335
|
+
Easily collect component interactions:
|
|
336
|
+
|
|
337
|
+
```javascript
|
|
338
|
+
const { InteractionCollectorUtils } = require('spacecommands');
|
|
339
|
+
|
|
340
|
+
// Await a button click
|
|
341
|
+
const button = await InteractionCollectorUtils.awaitButton(
|
|
342
|
+
message,
|
|
343
|
+
(i) => i.user.id === interaction.user.id,
|
|
344
|
+
30000 // 30 second timeout
|
|
345
|
+
);
|
|
346
|
+
|
|
347
|
+
if (button) {
|
|
348
|
+
await button.reply('Button clicked!');
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Create a select menu collector
|
|
352
|
+
const collector = InteractionCollectorUtils.createSelectMenuCollector(
|
|
353
|
+
message,
|
|
354
|
+
(i) => i.user.id === interaction.user.id,
|
|
355
|
+
{ time: 60000 }
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
collector.on('collect', async (i) => {
|
|
359
|
+
await i.reply(`Selected: ${i.values.join(', ')}`);
|
|
360
|
+
});
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## Polls
|
|
364
|
+
|
|
365
|
+
Create and manage Discord's native polls:
|
|
366
|
+
|
|
367
|
+
```javascript
|
|
368
|
+
// Access the poll handler
|
|
369
|
+
const pollHandler = instance.pollHandler;
|
|
370
|
+
|
|
371
|
+
// Get a poll from a message
|
|
372
|
+
const poll = message.poll;
|
|
373
|
+
|
|
374
|
+
if (poll) {
|
|
375
|
+
// Get poll results
|
|
376
|
+
const results = await pollHandler.getPollResults(poll);
|
|
377
|
+
|
|
378
|
+
// Get winning answer(s)
|
|
379
|
+
const winners = pollHandler.getWinningAnswers(poll);
|
|
380
|
+
console.log(`Winning answer: ${winners[0].text}`);
|
|
381
|
+
|
|
382
|
+
// Get poll statistics
|
|
383
|
+
const stats = pollHandler.getPollStats(poll);
|
|
384
|
+
console.log(`Total votes: ${stats.totalVotes}`);
|
|
385
|
+
|
|
386
|
+
// Get formatted results
|
|
387
|
+
const formatted = await pollHandler.getFormattedResults(poll);
|
|
388
|
+
await message.channel.send(formatted);
|
|
389
|
+
|
|
390
|
+
// Check if a user voted
|
|
391
|
+
const hasVoted = await pollHandler.hasUserVoted(poll, userId);
|
|
392
|
+
|
|
393
|
+
// Get user's votes
|
|
394
|
+
const userVotes = await pollHandler.getUserVotes(poll, userId);
|
|
395
|
+
|
|
396
|
+
// End poll early
|
|
397
|
+
await pollHandler.endPoll(poll);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Register handler for when a poll ends
|
|
401
|
+
pollHandler.registerPollEndHandler({
|
|
402
|
+
pollId: /poll-.+/, // Regex or specific message ID
|
|
403
|
+
callback: async (poll, instance) => {
|
|
404
|
+
const results = await instance.pollHandler.getFormattedResults(poll);
|
|
405
|
+
await poll.message.channel.send(`Poll ended!\n${results}`);
|
|
406
|
+
},
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
// Fetch a poll from a message ID
|
|
410
|
+
const fetchedPoll = await pollHandler.fetchPoll(messageId, channelId);
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## AutoMod
|
|
414
|
+
|
|
415
|
+
Manage Discord's AutoMod rules programmatically:
|
|
416
|
+
|
|
417
|
+
```javascript
|
|
418
|
+
const { AutoModerationRuleEventType, AutoModerationActionType } = require('discord.js');
|
|
419
|
+
|
|
420
|
+
// Access the AutoMod handler
|
|
421
|
+
const autoModHandler = instance.autoModHandler;
|
|
422
|
+
|
|
423
|
+
// Create a keyword filter rule
|
|
424
|
+
const keywordRule = await autoModHandler.createKeywordRule(
|
|
425
|
+
guild,
|
|
426
|
+
'No Profanity',
|
|
427
|
+
['badword1', 'badword2'],
|
|
428
|
+
[
|
|
429
|
+
{
|
|
430
|
+
type: AutoModerationActionType.BlockMessage,
|
|
431
|
+
metadata: { customMessage: 'Please keep chat family-friendly!' }
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
type: AutoModerationActionType.Timeout,
|
|
435
|
+
metadata: { durationSeconds: 60 }
|
|
436
|
+
}
|
|
437
|
+
],
|
|
438
|
+
{
|
|
439
|
+
allowList: ['allowed-phrase'],
|
|
440
|
+
exemptRoles: ['moderator-role-id'],
|
|
441
|
+
exemptChannels: ['staff-channel-id']
|
|
442
|
+
}
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
// Create a spam rule
|
|
446
|
+
const spamRule = await autoModHandler.createSpamRule(
|
|
447
|
+
guild,
|
|
448
|
+
'Anti-Spam',
|
|
449
|
+
[{ type: AutoModerationActionType.BlockMessage }]
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
// Create a mention spam rule
|
|
453
|
+
const mentionRule = await autoModHandler.createMentionSpamRule(
|
|
454
|
+
guild,
|
|
455
|
+
'Mention Limit',
|
|
456
|
+
5, // Maximum 5 mentions
|
|
457
|
+
[{ type: AutoModerationActionType.BlockMessage }],
|
|
458
|
+
{ raidProtection: true }
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
// Create a regex pattern rule
|
|
462
|
+
const regexRule = await autoModHandler.createRegexRule(
|
|
463
|
+
guild,
|
|
464
|
+
'Link Blocker',
|
|
465
|
+
['(https?://)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})'],
|
|
466
|
+
[{ type: AutoModerationActionType.BlockMessage }]
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
// Create a preset keyword rule
|
|
470
|
+
const { AutoModerationRuleKeywordPresetType } = require('discord.js');
|
|
471
|
+
const presetRule = await autoModHandler.createPresetRule(
|
|
472
|
+
guild,
|
|
473
|
+
'Block Profanity',
|
|
474
|
+
[AutoModerationRuleKeywordPresetType.Profanity],
|
|
475
|
+
[{ type: AutoModerationActionType.BlockMessage }]
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
// Register handler for AutoMod actions
|
|
479
|
+
autoModHandler.registerActionHandler({
|
|
480
|
+
ruleId: 'specific-rule-id', // Optional: specific rule or regex
|
|
481
|
+
callback: async (execution, instance) => {
|
|
482
|
+
console.log(`AutoMod triggered by ${execution.userId}`);
|
|
483
|
+
console.log(`Rule: ${execution.ruleId}`);
|
|
484
|
+
console.log(`Action: ${execution.action.type}`);
|
|
485
|
+
|
|
486
|
+
// Log to a channel
|
|
487
|
+
const logChannel = execution.guild.channels.cache.get('log-channel-id');
|
|
488
|
+
if (logChannel) {
|
|
489
|
+
await logChannel.send(`AutoMod: User <@${execution.userId}> triggered rule ${execution.ruleTriggerType}`);
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// Fetch all AutoMod rules for a guild
|
|
495
|
+
const rules = await autoModHandler.fetchGuildRules(guild);
|
|
496
|
+
|
|
497
|
+
// Update an existing rule
|
|
498
|
+
await autoModHandler.updateRule(guild, ruleId, {
|
|
499
|
+
enabled: false, // Disable the rule
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
// Delete a rule
|
|
503
|
+
await autoModHandler.deleteRule(guild, ruleId);
|
|
504
|
+
|
|
505
|
+
// Clear cache
|
|
506
|
+
autoModHandler.clearGuildCache(guildId);
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
## Documentation
|
|
510
|
+
|
|
511
|
+
For detailed documentation, examples, and guides, visit our [GitHub repository](https://github.com/VicToMeyeZR/SpaceCommands).
|
|
512
|
+
|
|
513
|
+
## Support
|
|
514
|
+
|
|
515
|
+
If you need help or have questions, please open an issue on our [GitHub repository](https://github.com/VicToMeyeZR/SpaceCommands/issues).
|
|
516
|
+
|
|
517
|
+
## License
|
|
518
|
+
|
|
519
|
+
MIT License - see LICENSE file for details.
|