/[sudobot]/trunk/docs/app/(docs)/extensions/creating-extensions-for-v9/page.mdx
ViewVC logotype

Annotation of /trunk/docs/app/(docs)/extensions/creating-extensions-for-v9/page.mdx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 575 - (hide annotations)
Mon Jul 29 17:59:26 2024 UTC (8 months ago) by rakinar2
File size: 9288 byte(s)
chore: add trunk
1 rakinar2 575 ---
2     title: Creating Extensions for SudoBot v9
3     short_name: Creating Extensions for SudoBot v9
4     ---
5    
6     import Callout from "@/components/Alerts/Callout";
7    
8     # Creating Extensions for SudoBot v9
9    
10     SudoBot has support for extensions, and it was introduced in version 6.17. Extensions can extend the bot's feature, by adding commands, event listeners, services and a lot more stuff. You can install/uninstall/disable extensions, or create your own to make the bot behave exactly how you want. Extensions can be written using JavaScript and TypeScript.
11    
12     In this article, you'll learn how SudoBot's extension system works.
13    
14     ## The extensions directory
15    
16     To start using extensions, you need to create a root directory where extensions will be installed.
17     In this guide, we'll name the directory `installed_extensions/`. To create a directory named `installed_extensions/` in the main project root, run the following:
18    
19     ```bash
20     mkdir installed_extensions
21     ```
22    
23     Every installed extension goes inside this directory.
24    
25     Now to tell SudoBot where to look for extensions, add the `EXTENSIONS_DIRECTORY` environment variable to your `.env` file:
26    
27     ```bash
28     # Path to the extensions root directory
29     EXTENSIONS_DIRECTORY=/example/path/to/extensions/directory
30     ```
31    
32     Each installed extension has a directory associated with it inside the `installed_extensions/` directory. Inside of that inner directory, there is a special file `extension.json` which contains meta information about the extension, and how to build it.
33    
34     The `extension.json` file looks something like this:
35    
36     ```json5
37     {
38     main: "./build/index.js" /* The entry point. */,
39     commands: "./build/commands" /* Commands directory. The bot will load commands from this directory. */,
40     events: "./build/events" /* Event handlers directory. The bot will load event handlers from this directory. */,
41     language: "typescript" /* The language being used for this extension. Can be either "javascript" or "typescript". */,
42     main_directory: "./build" /* The main directory where the entry point is located. */,
43     build_command: "npm run build" /* Command to build the extension. In this case `npm run build` invokes `tsc`. */,
44     }
45     ```
46    
47     ## Creating your first SudoBot extension
48    
49     To get started, first create a directory named `installed_extensions` inside the project root. In that directory, create another directory for your extension. The name of this directory usually should be your extension's name. In this example, we'll name the extension "hello".
50    
51     Then inside your extension's directory, create the `extension.json` file, and the `src/` directory. Inside `src`, create `events` and `commands` directories. The final directory tree should look something like this:
52    
53     ```
54     + sudobot/ [project root]
55     + installed_extensions/
56     + hello/
57     + src/
58     + commands/
59     + events/
60     - extension.json
61     ```
62    
63     Now add the following to your `extension.json` file:
64    
65     ```json
66     {
67     "main": "./build/index.js",
68     "commands": "./build/commands",
69     "events": "./build/events",
70     "language": "typescript",
71     "main_directory": "./build",
72     "build_command": "npm run build"
73     }
74     ```
75    
76     We'll be using TypeScript to write the extension in this example. If you'd like to use JavaScript instead, you can set `language` to `javascript` and you don't need to specify a build command, and your main directory will be the directory where you put your JavaScript files (usually `src/`). You should also adjust the paths to point to that directory (rather than `build/` which is used in this example).
77    
78     #### Setting up TypeScript and Dependencies
79    
80     First, run `npm init` to initialize your extension project. This will ask you a few questions and create a `package.json` file. Then run:
81    
82     ```bash
83     npm install --save ../.. # Path to the sudobot project root
84     ```
85    
86     <Callout type="info">
87     Remember **this is a really important step** to make sure your extension can
88     access SudoBot's core utilities to initialize itself. If you don't link
89     SudoBot with your extension, it will fail to import the necessary files.
90     </Callout>
91    
92     Then we can go ahead and install the dependencies and also set up TypeScript.
93    
94     ```shell
95     npm install module-alias
96     npm install -D typescript @types/node
97     npx tsc --init
98     ```
99    
100     This will add `typescript` as a dev dependency and also create the `tsconfig.json` file which contains the configuration for the TypeScript compiler.
101    
102     Now open up `tsconfig.json` file, and add the following (you can tweak these options if you want):
103    
104     ```json
105     {
106     "compilerOptions": {
107     "target": "ES2021",
108     "module": "commonjs",
109     "rootDir": "./src",
110     "baseUrl": "./",
111     "paths": {
112     "@sudobot/*": ["node_modules/sudobot/build/out/main/typescript/*"],
113     "@framework/*": [
114     "node_modules/sudobot/build/out/framework/typescript/*"
115     ]
116     },
117     "resolveJsonModule": true,
118     "outDir": "./build",
119     "newLine": "lf",
120     "noEmitHelpers": true,
121     "noEmitOnError": true,
122     "allowSyntheticDefaultImports": true,
123     "esModuleInterop": true,
124     "forceConsistentCasingInFileNames": true,
125     "strict": true,
126     "skipLibCheck": true
127     },
128     "exclude": ["./tests", "./build"]
129     }
130     ```
131    
132     This sets up the `@sudobot` and `@framework` import aliases for TypeScript, specifies the source root and build directory, and a few other things that are needed.
133    
134     <Callout type="info">
135     Remember to build the bot beforehand! As you can see, this alias points to
136     the `build` directory which is created when you build the bot.
137     </Callout>
138    
139     Then open up `package.json` file and add the following inside the root object:
140    
141     ```json
142     "_moduleAliases": {
143     "@framework": "node_modules/sudobot/build/out/framework/typescript",
144     "@sudobot": "node_modules/sudobot/build/out/main/typescript"
145     },
146     "scripts": {
147     "build": "tsc"
148     }
149     ```
150    
151     You might be thinking, why do we need to add the module aliases twice? It's because TypeScript doesn't actually deal with these module aliases, it just checks the types and imports. In runtime, we need another way to resolve these imports. We use `module-alias` for that.
152    
153     #### The entry point
154    
155     We need to create the entry point now! Make a file `src/index.ts` and put the following code inside of that file:
156    
157     ```typescript
158     import "module-alias/register";
159     import { Extension } from "@sudobot/core/Extension";
160    
161     class HelloExtension extends Extension {
162     // ...
163     }
164    
165     export default HelloExtension;
166     ```
167    
168     That's actually all we need inside this file.
169    
170     #### Adding commands to the extension
171    
172     Alright, let's add a command to the extension! Create a file `src/commands/HelloCommand.ts` and inside of that file, put the following code:
173    
174     ```typescript
175     import { Command, type CommandMessage } from "@framework/commands/Command";
176     import type Context from "@framework/commands/Context";
177    
178     class HelloCommand extends Command {
179     public override readonly name = "hello";
180     public override readonly description = "A simple hello-world command.";
181    
182     public override async execute(context: Context<CommandMessage>) {
183     await context.reply("Hello world, from the hello extension!");
184     }
185     }
186    
187     export default HelloCommand;
188     ```
189    
190     This command just responds to the user with "Hello world, from the hello extension!".
191    
192     #### Adding event listeners to the extension
193    
194     Now, let's add an event listener to the extension! Create a file `src/events/MessageCreateEventListener.ts` and inside of that file, put the following code:
195    
196     ```typescript
197     import EventListener from "@framework/events/EventListener";
198     import { Events } from "@framework/types/ClientEvents";
199     import type { Message } from "discord.js";
200    
201     class MessageCreateEventListener extends EventListener<Events.MessageCreate> {
202     public override readonly name = Events.MessageCreate;
203    
204     public override async execute(message: Message<boolean>): Promise<void> {
205     if (message.author.bot) {
206     return;
207     }
208    
209     if (message.content === "ping") {
210     await message.reply("Pong, from the hello extension!");
211     }
212     }
213     }
214    
215     export default MessageCreateEventListener;
216     ```
217    
218     This event listener listens to `MessageCreate` event, and whenever someone sends a message with content "ping", it will reply to them.
219    
220     #### Building the extension
221    
222     Building your newly created extension involves the same procedures as any other TypeScript project.
223     Install the dependencies and run the TypeScript compiler from the extension's directory (installed_extensions/hello):
224    
225     ```bash
226     npm install -D
227     npm run build
228     ```
229    
230     If using [Bun](https://bun.sh):
231    
232     ```bash
233     bun install -D
234     bun run build
235     ```
236    
237     This will take a little bit time. After that, you're ready to go. You can now start the bot from the main project root (assuming you've build it already):
238    
239     ```bash
240     npm start
241     ```
242    
243     And then if everything was configured correctly, the `hello` command will be loaded and can be executed on any server.
244    
245     Congratulations, you've just built an extension for SudoBot!
246    
247     ### Help and Support
248    
249     If you need help with anything, feel free to create a discussion topic at the [GitHub repo](https://github.com/onesoft-sudo/sudobot). You can also contact via email at [[email protected]](mailto:[email protected]), or join our [Discord Server](https://discord.gg/892GWhTzgs).

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26