Only this pageAll pages
Powered by GitBook
1 of 17

English

Loading...

Guides

Loading...

Loading...

Loading...

Fundamentals

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Extras

Loading...

Loading...

Loading...

Linux guides

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.

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 WildBot which you can invite to your own server.

Getting Started

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

Linux guides

Fundamentals: Dive a little deeper

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

Commands
Buttons

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.

Hetzner

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.

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

DigitalOcean
Scaleway
Xenyth
OVH
Linode
Vultr
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}`)
  }
}

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:

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

Creating a bot account

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

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

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

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

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()
We're continuing off the example from the Slash commands page

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!')
  }
}
  • Navigate to the "Bot" tab

  • Click "Add Bot" on the left of the page

  • Click "Yes, do it!"

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

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

  • Applications Page

    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
        })
      }
    }
    

    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:

    Copy and paste the following example:

    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

    Controlling the service

    Starting

    Stopping

    Start on boot

    To undo:

    Restarting

    Adding your bot to your server

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

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

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

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

    3. 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.

    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.

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

    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.

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

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

    Detritus
    Detritus Documentation
    Detritus Examples
    Slash commands
    Context menu actions
  • User - The user that's going to run WildBeast

    Do NOT use root, create a new user for safety.

  • sudo nano /etc/systemd/system/wildbeast.service
    [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
    sudo systemctl start wildbeast.service
    sudo systemctl stop wildbeast.service
    sudo systemctl enable wildbeast.service
    sudo systemctl disable wildbeast.service
    sudo systemctl restart wildbeast.service

    Setup

    Instructions to run WildBeast on Linux

    The basics

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

    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.

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

    We need a few prerequisites:

    • A computer running any

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

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

    Installation

    Installing Node.js

    1. Run the following code in your terminal:

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

    2. Install Node.js with the following command:

    Installing Postgres

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

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

    1. Create a new user for WildBeast to use:

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

    2. Finally, create a new database:

      (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:

    Setting the options

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

    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:

    Testing it out!

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

    Start WildBeast for the first time with the following command:

    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.

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

    Next steps

    Slash commands

    Slash commands are the primary way to interact with bots

    Creating commands

    Reminder: Check the Detritus Documentation for more advanced settings.

    A finished command looks like this:

    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:

    What's next?

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

  • Git

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

  • DigitalOcean's guide on making new sudo-enabled users
    supported version of Ubuntu
    VPS
    manually
    this guide.
    Running as a service for autostart
    Subcommands
    Options
    Buttons
    curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
    sudo apt-get install -y nodejs
    sudo apt install postgresql postgresql-contrib
    sudo -u postgres createuser --interactive
    sudo -u postgres createdb wildbeast
    git clone https://github.com/TheSharks/WildBeast.git
    cd ./WildBeast
    npm install
    nano .env.example
    npm run-script migrations:up
    npm start
    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!')
      }
    }
    
    constructor () {
      super({
        description: 'Ping',
        name: 'ping',
        guildIds: ['110462143152803840']
      })
    }

    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.

    import { Interaction } from 'detritus-client'
    import { MessageFlags } from 'detritus-client/lib/constants'
    
    import { BaseContextMenuUserCommand, ContextMenuUserArgs } from '../../base'
    
    export default class InformationCommand extends BaseContextMenuUserCommand
    
    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
        })
      }
    }
    
    {
    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
    })
    }
    }