Files
website/docs/guide/walkthrough/plugins.md
2023-06-28 10:34:30 -05:00

158 lines
4.6 KiB
Markdown

---
sidebar_position: 5
---
# Plugins
<p>As of now, modules seem a little underwhelming. It appears that sern doesn't have all the features of a standard handler,
which manages permissions, categorizes, cool-downs, publishes application commands, role permissions, etc.</p>
<p>Many important parts that manage access and help streamline command creation to make are apparently absent.
Below is an example of an event plugin, one of the types of plugins.</p>
Typescript:
```typescript
export function serenOnly(): EventPlugin<CommandType.Both> {
return {
type: PluginType.Event,
async execute([ctx, args], controller) {
if (ctx.user.id !== "182326315813306368") {
await ctx.reply({content: "You cannot use this command"})
return controller.stop()
}
return controller.next();
}
}
}
```
Javascript:
```javascript
export function serenOnly() {
return {
type: PluginType.Event,
async execute([ctx, args], controller) {
if (ctx.user.id !== "182326315813306368") {
await ctx.reply({content: "You cannot use this command"})
return controller.stop()
}
return controller.next();
}
}
}
```
<br /> As part of being extensibile, plugins make sern just as powerful, if not more powerful than
standard handlers.
Plugins modify and add new behavior to standard modules.
<br /> At the moment, there are two types of plugins:
- Init Plugins
- Control Plugins
## Init Plugins
All modules are registered into sern's system. Init plugins modify how commands are loaded.
or do some kind of preprocessing before loaded.
### The controller object
```typescript
export interface Controller {
next: () => Ok<void>;
stop: () => Err<void>;
}
```
An instance of the above object is passed into every plugin. <br />
This controls whether a module is stored into sern. <br />
Typescript:
```typescript
export function inDir(dir : string) : CommandPlugin<CommandType.Both> {
return {
type: PluginType.Init,
async execute({ absPath, module }) {
if(path.dirname(absPath) !== dir) {
console.log(+new Date(), `${module.name} is not in the correct directory!`);
return controller.stop()
}
console.log(+new Date(), `${module.name} is in the correct directory!`);
return controller.next(); //continue
}
}
}
```
Javascript:
```javascript
export function inDir(dir : string) {
return {
type: PluginType.Init,
async execute({ absPath, module }) {
if(path.dirname(absPath) !== dir) {
console.log(+new Date(), `${module.name} is not in the correct directory!`);
return controller.stop()
}
console.log(+new Date(), `${module.name} is in the correct directory!`);
return controller.next(); //continue
}
}
}
```
Above, this simple plugin logs that the module has been loaded along with a timestamp. <br />
Again, it is up to **you** to define plugin logic! The possibilities to customize your bots are endless.
:::tip
Init Plugins are good for ensuring the shape, maintaining location, and preprocessing commands.
:::
## Event Plugins
![control-plugins](../../../static/img/eventplugins.drawio.svg) <br />
- An event is emitted by discord.js.
- This event is passed to all plugins (**in order!!**),
- If all are successful,
The command is executed. Calling `controller.stop()` notifies sern that this command should not be run,
and this event is ignored.
<p>So, what does a command module look like with plugins?</p>
Typescript:
```typescript
import { commandModule, CommandType } from '@sern/handler';
export default commandModule({
type: CommandType.Both,
plugins: [
inDir("other"),
serenOnly()
],
description: 'A ping command',
//alias : [],
execute: async (ctx, args) => {
await ctx.reply({ content: 'Pong 🏓' });
},
});
```
Javascript:
```typescript
const { commandModule, CommandType } = require('@sern/handler');
exports.default = commandModule({
type: CommandType.Both,
plugins: [
inDir("other"),
serenOnly() //The plugins in this section applied to this module!
],
description: 'A ping command',
//alias : [],
execute: async (ctx, args) => {
await ctx.reply({ content: 'Pong 🏓' });
},
});
```
Can you predict the behavior of this command?
- Before loading into sern, this command module will check if this module is in the correct directory `other`.
- Before an event occurs, this command module will check if the user has the id `182326315813306368`.
:::tip
Event Plugins are good for filtering, preconditions, parsing.
:::
If all plugins return `controller.next()`, this command replies `Pong 🏓`