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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 599 - (show annotations)
Wed Aug 7 14:51:05 2024 UTC (7 months, 3 weeks ago) by rakinar2
File size: 9349 byte(s)
docs: update pages to include instructions for bun users
1 ---
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 built it already):
238
239 ```bash
240 npm start
241 ```
242
243 Or using Bun (no build step required):
244
245 ```bash
246 bun dev
247 ```
248
249 And then if everything was configured correctly, the `hello` command will be loaded and can be executed on any server.
250
251 Congratulations, you've just built an extension for SudoBot!
252
253 ### Help and Support
254
255 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