https://github.com/r6stats/valkord-discord
Micro framework for building Discord bots with TypesScript
https://github.com/r6stats/valkord-discord
bot discord discord-bot discordjs framework typescript valkord
Last synced: 11 months ago
JSON representation
Micro framework for building Discord bots with TypesScript
- Host: GitHub
- URL: https://github.com/r6stats/valkord-discord
- Owner: R6Stats
- License: gpl-3.0
- Created: 2018-08-23T20:04:40.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2022-12-06T11:28:05.000Z (over 3 years ago)
- Last Synced: 2024-11-20T09:29:03.964Z (over 1 year ago)
- Topics: bot, discord, discord-bot, discordjs, framework, typescript, valkord
- Language: TypeScript
- Homepage:
- Size: 727 KB
- Stars: 4
- Watchers: 6
- Forks: 7
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Valkord (valk-discord)
[](https://discord.gg/pUdraS3)
[](https://www.npmjs.com/package/@r6stats/valkord)
[](https://david-dm.org/r6stats/valkord-discord)
[](https://david-dm.org/r6stats/valkord-discord)
Valkord is a micro framework for building Discord bots with [discordjs](https://discord.js.org/#/) and [TypeScript](https://www.typescriptlang.org/). Valkord uses a [Modular](https://en.wikipedia.org/wiki/Modular_design) component loading system, allowing you to develop or use 3rd party modules in your bot. Modules consist of commands, listeners and other classes that can be customized on a case-by-case basis.
## Installing
To use Valkord to develop your own bot, you'll need to install it in your project alongside discord.js.
```bash
npm install @r6stats/valkord discord.js --save
```
## Creating a Module
In order to create your own module, you'll want to extend the `ValkordModule` class and define the components that make up your module. You can also optionally add add a custom config for loading variables from the user's `.env` file.
cd
```ts
// my.module.ts
import { ClientCommand, Constructor, ValkordModule } from '@r6stats/valkord'
import { MyModuleConfig } from './my.module-config'
import { PingCommand } from './commands'
export class MyModule extends ValkordModule {
public getName = (): string => 'MyStuff'
public getConfig = (): Constructor | null => MyModuleConfig // or return null
public getCommands = (): Constructor[] => {
PingCommand,
}
}
```
```ts
// my.module-config.ts
import { ValkordConfig } from '@r6stats/valkord'
export interface MyModuleConfigOptions {
my_config_value: string
}
export class MyModuleConfig extends ValkordConfig {
public load = (): MyModuleConfigOptions => ({
my_config_value: env('MY_CONFIG_VALUE')
})
}
```
```ts
// index.ts
export * from './my.module-config'
export * from './my.module'
```
The referenced command class makes use of the `ValkordCommand` class built into Valkord, which is extensible and allows for custom command handling as well as built in support for aliases, help messages and more.
```ts
import { ValkordCommand, CommandContext, Injectable } from '@r6stats/valkord'
import { Message } from 'discord.js'
@Injectable()
export class PingCommand extends ValkordCommand {
public readonly command = 'ping'
public readonly name = 'Ping'
public async handle (ctx: CommandContext): Promise {
return ctx.reply('Pong!')
}
}
```
Thanks to Valkord's incredibly simple [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection) implementation, you can also create your own service (among others) classes that can auomatically be resolved from Valkord's built in container.
Take for example, the `TimeService` class:
```ts
import R6StatsAPI, { GenericStatsResponse, OperatorStatsResponse } from '@r6stats/node'
import { ConfigService, OnModuleBoot, Injectable } from '@r6stats/valkord'
@Injectable()
export class TimeService {
public async getTime (): Promise {
return new Date()
}
}
```
You can now reference the `TimeService` from any class where the `@Injectable()` decorator is present, more importantly in the commands.
```ts
import { ValkordCommand, CommandContext, Injectable } from '@r6stats/valkord'
import { Message } from 'discord.js'
@Injectable()
export class TimeCommand extends ValkordCommand {
public readonly command = 'time'
public readonly name = 'Time'
private readonly time: TimeService
public constructor (time: TimeService) {
this.time = time
}
public async handle (ctx: CommandContext): Promise {
return ctx.reply(this.time.getTime())
}
}
```
## Creating a Deployable Bot
Regardless or whether or not you want to build your own modules, you'll have no problem running the bot in production.
You'll simply need to create a TypeScript or JavaScript file named `index.js` (or whatever you prefer) and instantiate your bot:
```ts
import { ValkordClient, ValkordFactory } from '@r6stats/valkord'
// optionally import your custom module, or any 3rd party modules
import MyModule from 'my-valkord-module'
export class MyClient extends ValkordClient {
}
const run = async () => {
// instatiate the client from the Container
const client = await ValkordFactory.create(MyClient)
// load any modules of your choosing
const loader = client.getModuleLoader()
loader.load(MyModule)
// connect!
await client.connect()
}
run()
```
### Sharded Bot
Larger Discord bots may require sharding, typically suggested for any bots in more than 2000 guilds. Read more about sharding [here](https://discordjs.guide/sharding/). In order to enable sharding in Valkord, a second file is necessary to create shards of the client.
The new `index` file (TypeScript or JavaScript) will create an instance of the `ValkordManager` which will handle spawning the bot's shards. No changes to the client class are necessary.
```ts
// index.ts
import { ValkordFactory } from '@r6stats/valkord'
import * as path from 'path'
export const run = async (): Promise => {
// the path should refer to the file containing your ValkordClient instance
await ValkordFactory.createManaged(path.join(__dirname, './client.ts'))
}
run()
```
The total number of shards and the range of shards to create can be configured in the `.env` file.
```js
TOTAL_SHARDS=3 // total number of shards, if running more than one instance of the manager
SHARD_RANGE=0-2 // zero-based range of shards to run on this instance, starting at 0, last shard # should be one less than the total
```