Only this pageAll pages
Powered by GitBook
1 of 17

English

Loading...

Guides

Linux guides

Loading...

Loading...

Fundamentals

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Extras

Loading...

Loading...

Loading...

What is WildBeast?

WildBeast is a wheels-attached Discord bot - meaning the heavy lifting is already done for you, making WildBeast easy to modify and extend to perfectly fit your use case.

Getting Started

Ready to get your hands dirty? Pick one of these guides to get started with WildBeast.

Fundamentals: Dive a little deeper

Looking to write your own commands, or other custom features? Look below for our advanced guides.

This documentation focusses on self-hosting and extending WildBeast. If you don't feel like hosting your own instance, we host a publicly available version of WildBeast known as which you can invite to your own server.

WildBot
Linux guides
Commands
Buttons

Options

Add selectable options to your commands

Options are the primary way to take user input for slash commands, they're type-checked on Discord's side, so type safety is guaranteed!

In practise

import { Interaction } from 'detritus-client'
import { ApplicationCommandOptionTypes } from 'detritus-client/lib/constants'

import { BaseSlashCommand } from '../base'

export interface CommandArgs {
  dice?: number
  sides?: number
}

export default class DiceCommand extends BaseSlashCommand {
  description = 'Roll some dice'
  name = 'dice'

  constructor () {
    super({
      options: [
        {
          type: ApplicationCommandOptionTypes.INTEGER,
          name: 'dice',
          description: 'The number of dice to roll (default: 1)',
          required: false
        },
        {
          type: ApplicationCommandOptionTypes.INTEGER,
          name: 'sides',
          description: 'The number of sides on the dice (default: 6)',
          required: false
        }
      ]
    })
  }

  async run (context: Interaction.InteractionContext, args: CommandArgs): Promise<void> {
    const { dice, sides } = args
    const diceCount = dice ?? 1
    const diceSides = sides ?? 6

    let total = 0
    for (let i = 0; i < diceCount; i++) {
      total += Math.floor(Math.random() * diceSides) + 1
    }

    await context.editOrRespond(`${context.user.username} rolled ${diceCount}d${diceSides} and got ${total}`)
  }
}

Commands

Write your own custom commands

Custom commands is an advanced feature and requires knowledge of programming.

Support for doing this will not be provided in addition to what is listed on these pages.

We won't go into some of the more advanced ways to control command flow that's included with Detritus' system, such as onBeforeRun, built-in ratelimiting, and permission checks.

There are 3 types of commands, slash commands and 2 types of context menu commands. Documentation for each type is provided below.

Under the hood, WildBeast's command system is an extension of the system from .

For more info on this, please see the , and the instead.

Detritus
Detritus Documentation
Detritus Examples
Slash commands
Context menu actions

Slash commands

Slash commands are the primary way to interact with bots

Creating commands

A finished command looks like this:

import { Interaction } from 'detritus-client'
import { BaseSlashCommand } from '../base'

export default class PingCommand extends BaseSlashCommand {
  constructor () {
    super({
      description: 'Ping',
      name: 'ping'
    })
  }

  async run (context: Interaction.InteractionContext): Promise<void> {
    await context.editOrRespond(context, 'Pong!')
  }
}

There are a few things to note with regard to how commands are constructed:

  • All commands are new classes that extend a base class, in this example the command is a plain slash command.

  • The resulting command is exported as the default export.

  • The constructor with a super call is used to set properties of the class instead of directly assigning them, this avoids incompatibilities with Detritus.

In practice

When restarting WildBeast, your newly created command will automatically be registered as a global command, and will be available within a few hours.

Rather want a guild-based command instead of a global one? Add guild IDs to the constructor of your command:

constructor () {
  super({
    description: 'Ping',
    name: 'ping',
    guildIds: ['110462143152803840']
  })
}

What's next?

There are more things you can do with commands, like adding options, creating subcommands, and adding buttons and select menus.

Reminder: Check the for more advanced settings.

Detritus Documentation
Subcommands
Options
Buttons

Setup

Instructions to run WildBeast on Linux

The basics

Any modern Linux distribution will work, however the commands described here only work on Debian based distributions.

For safety reasons, please don't run WildBeast with the root account.

We need a few prerequisites:

    • You need sudo or doas privileges, or access to the root account

  • A text editor. We're going to use nano, but you can use anything you'd like.

Installation

Installing Node.js

  1. Run the following code in your terminal:

    curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
  2. Install Node.js with the following command:

    sudo apt-get install -y nodejs

Installing Postgres

Postgres is available to install by default on Ubuntu, just run the following code in your terminal:

sudo apt install postgresql postgresql-contrib

We need to do some extra steps to prepare Postgres for use:

  1. Create a new user for WildBeast to use:

    sudo -u postgres createuser --interactive

    The new user does not need to be a superuser, and can be called whatever you want.

  2. Finally, create a new database:

    sudo -u postgres createdb wildbeast

    (We used wildbeast here as the database user, change it if you used something else in the previous step)

Setting up

Getting the code

Clone the code and install the required modules:

git clone https://github.com/TheSharks/WildBeast.git
cd ./WildBeast
npm install

Setting the options

Open the example configuration file in nano and enter your details:

nano .env.example

When you're done, save the file as .env

Starting the database

Before we can start, we need to initialize the database. Run the following code:

npm run-script migrations:up

Testing it out!

Now for the fun part, testing to see if it worked!

Start WildBeast for the first time with the following command:

npm start

You should see something similar to the following if everything went well

19:11:41 [info] Gateway: Client ready

19:11:41 [info] Gateway - shard 0: Gateway ready

Test if your bot works by running the /ping command

Slash commands can take a while to appear.

Next steps

Good to know: For the purpose of this guide, we'll use .

If you don't know how to create a new user on Linux, please see

A computer running any

If you want to run WildBeast 24/7, you should get a

(Not a fan of curl <url> | bash -? You can do this too.)

Don't have your bot in your server yet? Check

Ubuntu 20.04
DigitalOcean's guide on making new sudo-enabled users
supported version of Ubuntu
VPS
Git
manually
this guide.
Running as a service for autostart

Buttons

Add buttons for easy follow ups

Buttons are a simple way to create follow ups after a slash command has finished.

In practise

import { Interaction } from 'detritus-client'
import { ComponentContext, Components, Embed } from 'detritus-client/lib/utils'
import fetch from 'node-fetch'

import { BaseSlashCommand } from '../base'

export default class RandomCatCommand extends BaseSlashCommand {
  name = 'cat'
  description = 'Sends a random cat image'

  async run (context: Interaction.InteractionContext | ComponentContext): Promise<void> {
    const components = new Components({
      timeout: 5 * (60 * 1000),
      onTimeout: async () => await context.editOrRespond({ components: [] })
    })
    components.addButton({
      emoji: '🔃',
      run: async (componentContext: ComponentContext) => {
        await this.run(componentContext)
      }
    })
    const { fact } = await (await fetch('https://catfact.ninja/fact')).json()
    const embed = new Embed()
      .setDescription(fact)
      .setImage(`https://cataas.com/cat?${context.interaction.id}`) // cache busting
      .setFooter('Powered by cataas.com')
    await context.editOrRespond({
      embed,
      components
    })
  }
}

Subcommands

Nest multiple separate commands under one base command

Subcommands are a great way to nest seperate commands under one base command, each subcommand is their own seperate command and can be called as such.

In practise

import { Interaction } from 'detritus-client'
import { BaseSlashCommand, BaseCommandOption } from '../base'

export default class PingCommand extends BaseSlashCommand {
  constructor () {
    super({
      name: 'ping',
      // With subcommands, the description doesn't matter,
      // since it doesn't get shown to end users.
      description: '',
      options: [
        new PongCommand()
      ]
    })
  }
  // The base command should not have a run(), it never gets called
}

export class PongCommand extends BaseCommandOption {
  constructor () {
    super({
      name: 'pong'
      description: 'Pong!'
    })
  }
  
  async run (context: Interaction.InteractionContext): Promise<void> {
    await context.editOrRespond(context, 'Pong!')
  }
}

We're continuing off the example from the page

Slash commands

Running as a service

Using systemd, run WildBeast as a service for automatic (re)starting

Good to know: This guide uses systemd, we're assuming this is present on your system.

If you're using Ubuntu 20.04, you're already using systemd.

Making a new service

Start creating a new service:

sudo nano /etc/systemd/system/wildbeast.service

Copy and paste the following example:

[Unit]
After=network.target network-online.target
Requires=network.target network-online.target
StartLimitBurst=3
StartLimitIntervalSec=0

[Service]
WorkingDirectory=/REPLACE THIS
Type=simple
Restart=on-failure
RestartSec=1
User=REPLACE THIS
ExecStart=/usr/bin/env npm start

[Install]
WantedBy=multi-user.target

Pay attention to the REPLACE THIS, as you might've guessed you need to replace these values.

  • WorkingDirectory - The folder where you saved WildBeast

    For example: /home/wildbeast/WildBeast

  • User - The user that's going to run WildBeast

Controlling the service

Starting

sudo systemctl start wildbeast.service

Stopping

sudo systemctl stop wildbeast.service

Start on boot

sudo systemctl enable wildbeast.service

To undo:

sudo systemctl disable wildbeast.service

Restarting

sudo systemctl restart wildbeast.service

Do NOT use root, for safety.

create a new user

Context menu actions

Add commands to context menus shown on right-click for users and messages

There are 2 types of context menu actions, depending on what the end user is opening the context menu on.

VPS recommendations

Need to run WildBeast 24/7? Get a cheap VPS.

Need to run WildBeast 24/7? Get a cheap VPS. We recommend any of the below.

Cheap Finland and Germany-based VPSes.

The gold standard. Locations available worldwide.

Incredibly cheap but powerful VPSes, owned by online.net, based in France and The Netherlands.

A hosting solution made by Discord bot developers, aimed at a lower price range, starting from $2.49.

Cheap VPSes, used by many people. France and Canadian locations available.

US-based VPS provider, locations available worldwide.

US-based VPS provider, locations available worldwide.

Jobs

Jobs are a simple way to run code asynchronously on a set schedule, or whenever you need to.

Basic setup

A job either extends the Job class, or the ScheduledJob class, a scheduled job will run on a set time schedule and a normal job runs when called

Jobs are indexed and required based on their name either in context of the client, or in context of the cluster, a cluster job is called only once and a client job is called for each client that the cluster holds.

Cluster jobs should be named job-name.cluster.ts Client jobs should be named job-name.client.ts

In practise

Scheduled jobs work like this:

While regular jobs work like this:

import { Interaction } from 'detritus-client'
import { MessageFlags } from 'detritus-client/lib/constants'

import { BaseContextMenuUserCommand, ContextMenuUserArgs } from '../../base'

export default class InformationCommand extends BaseContextMenuUserCommand {
  name = 'Avatar'

  async run (context: Interaction.InteractionContext, args: ContextMenuUserArgs): Promise<void> {
    await context.editOrRespond({
      embed: {
        description: `${args.user.mention}'s avatar`,
        image: {
          url: `${args.user.avatarUrl}?size=512`
        }
      },
      flags: MessageFlags.EPHEMERAL
    })
  }
}
import { Interaction } from 'detritus-client'
import { MessageFlags } from 'detritus-client/lib/constants'

import { BaseContextMenuMessageCommand, ContextMenuMessageArgs } from '../../base'

export default class InformationCommand extends BaseContextMenuMessageCommand {
  name = 'Message ID'

  async run (context: Interaction.InteractionContext, args: ContextMenuMessageArgs): Promise<void> {
    await context.editOrRespond({
      embed: {
        description: `Message ID: ${args.message.id}`
      },
      flags: MessageFlags.EPHEMERAL
    })
  }
}

Hetzner
DigitalOcean
Scaleway
Xenyth
OVH
Linode
Vultr
import { ScheduledJob } from './base'

const job = new ScheduledJob('a_scheduled_job', 1000, async () => {
  // do some work every second
})

job.start()

export default job
import { Job } from './base'

const job = new Job('a_job', async () => {
  // do some work
})

export default job

// elsewhere in the code:
import { jobs } from '../cache'
const job = jobs.get('a_job')

job?.run()

Creating a bot account

This page will describe, in detail, how to obtain a token for your bot.

  1. Click "New Application" on the top right of the page

  2. Think of a name for your bot, and click "Create"

  3. Navigate to the "Bot" tab

  4. Click "Add Bot" on the left of the page

  5. Click "Yes, do it!"

  6. Optionally, set an avatar and change the username, and click "Save".

  7. Select the "Copy" button to copy your bot's token.

Navigate to your (you might need to login for this)

Applications Page

Adding your bot to your server

This page will show you how to invite your bot to your servers.

  1. Scroll down to the OAuth2 URL Generator and check the "applications.commands" and "bot" scopes

  2. Copy the link it generates and open it in a new tab, choosing what server you want to add it to, and hit "Authorize"

Don’t see the server you want to add the bot to? You need to have the ”Manage Server” permission in the server for it to show up.

Don’t have a bot account yet? Check out for instructions how to make one.

Once you have created a bot account, navigate to the OAuth2 page of your application

this page