bolt

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 1, 2026 License: MIT Imports: 10 Imported by: 0

README

bolt

A fast discordgo wrapper for bootstrapping Discord bots.

Usage

Prerequisites

Bolt requires a Discord bot token to run, the token must be set as an environment variable labeled "DISCORD_TOKEN"

Example
package main

import (
	"fmt"
	"strings"
	"time"

	"code.jakeyoungdev.com/jake/bolt"
	_ "github.com/joho/godotenv/autoload"
)

/*
A basic example of a bot with two commands and a general message handler for non-command messages. The bot uses a
verbose log level which will log everything for debugging purposes, and registers Discord Intents for message and admin
related permissions. This allows the bot to parse messages, send them, delete them, etc. as well as timeout and mute users.

This example registers three commands:

1. .ping - a basic ping/pong command that can be run by anyone at any time
2. .wait - a dummy command that replies "okay" it can only be run by users with the "user" role and can only be ran once every 25 seconds
3. .timeout - a admin command that can only be run by users with an "admin" role, this command will timeout any mentioned users for 5 minutes

A message handler is also registered in this example, message handlers are used to handle messages that do not contain a command. This enables
auto-moderation from the bot without manual intervention. The example message handler does two arbitrary things to demo functionality:

1. Checks the message content for the phrase "swear word" and, if found, times the user out for 5 minutes
2. Checks the message for the phrase "im going to yell in VoiceChat" and mutes the message author until Unmute is called on them
*/

func main() {
	b, err := bolt.New()

	if err != nil {
		panic(err)
	}

	b.AddCommands(
		bolt.Command{
			Trigger: "ping",
			Payload: func(c *bolt.Context) error {
				return c.Respond("pong")
			},
		},
		bolt.Command{
			Trigger: "wait",
			Payload: func(c *bolt.Context) error {
				return c.Respond("okay")
			},
			Timeout: time.Second * 25,
			Roles:   []string{"user"},
		},
		bolt.Command{
			Trigger: "timeout",
			Payload: func(c *bolt.Context) error {
				if len(c.Message.Mentions) > 0 {
					count := 0
					for _, m := range c.Message.Mentions {
						err := c.Timeout(m.ID, time.Now().Add(time.Minute*5))
						if err != nil {
							return err
						}
						count++
					}

					return c.Respond(fmt.Sprintf("timed out %d users\n", count))
				}
				return nil
			},
			Roles: []string{"admin"},
		},
	)

	b.AddMessageHandler(func(c *bolt.Context) error {
		if strings.Contains(c.Message.Content, "swear word") {
			return c.Timeout(c.Message.Author.ID, time.Now().Add(time.Hour*1))
		}

		if c.Message.Content == "im going to yell in VoiceChat" {
			return c.Mute(c.Message.Author.ID)
		}
		return nil
	})

	err = b.Start()
	if err != nil {
		panic(err)
	}
}

Development

bolt is in early development and may encounter breaking changes until a full v1 rollout, I will do my best to communicate these changes. Use a tagged version to avoid any surprises with live code in main

Documentation

Index

Constants

View Source
const (
	//the name of the environment variable that should contain the token for the bot, it is
	//required for bolt to run
	TOKEN_ENV_VAR = "DISCORD_TOKEN"

	//bot default command indicator, if messages begin with this substring they are processed
	//through the command handler instead of the generic message handler
	DEFAULT_INDICATOR = "."
	//max amount of concurrent goroutines that bolt can use for events. A lower amount
	//may lower the resource usage of bolt but may cause a delay in event handling
	DEFAULT_MAX_GOROUTINES = 250

	//minimum intents for bots to function, intents can be changed with options
	DEFAULT_INTENTS = dg.IntentGuilds |
		dg.IntentGuildMembers |
		dg.IntentGuildPresences |
		dg.IntentMessageContent |
		dg.IntentsGuildMessages |
		dg.IntentGuildMessageReactions
)
View Source
const (
	// the max length allowed for basic messages, if the message content exceeds this amount
	// then messages are split unto chunks of max size
	MSG_MAX_LENGTH = 2000
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Author added in v0.6.0

type Author struct {
	Name  string
	ID    string
	Roles []string
}

Author contains basic information about message authors

type Bolt

type Bolt interface {
	Start() error
	AddCommands(cmd ...Command)
	AddMessageHandler(p Payload)
	// contains filtered or unexported methods
}

func New

func New(opts ...Option) (Bolt, error)

New creates a new bolt instance and applies any supplied options

type Command

type Command struct {
	//the trigger phrase for the command, this field cannot include the command indicator. If the command is .ping
	//Trigger should be "ping"
	Trigger string
	//handler function to run when command is detected
	Payload Payload
	//the amount of time that must pass before a command can be run again
	Timeout time.Duration

	//the roles that are allowed to execute this command, the command author must have at least one of these roles
	//in order to use the command
	Roles []string
	// contains filtered or unexported fields
}

Command represents a bolt command in its entirety

type Context added in v0.6.0

type Context struct {
	Message *Message
	// contains filtered or unexported fields
}

Context is the struct passed to message and command handlers, it contains all needed message data as well as some methods to make interaction with the message as easy as possible

func (*Context) ClearTimeout added in v0.6.0

func (c *Context) ClearTimeout(userId string) error

ClearTimeout clears existing user timeouts, allowing them access again

func (*Context) Delete added in v0.6.0

func (c *Context) Delete() error

Delete removes the message from the current channel

func (*Context) Mute added in v0.6.0

func (c *Context) Mute(userId string) error

Mute handles muting a user from Voice Chat, this mute stays until it is Unmute()'d

func (*Context) React added in v0.6.0

func (c *Context) React(emoji Reaction) error

React applies the reaction to the message

func (*Context) Respond added in v0.6.0

func (c *Context) Respond(res string) error

Respond sends a response to the message, handling chunking if the message exceeds max length

func (*Context) Timeout added in v0.6.0

func (c *Context) Timeout(userId string, duration time.Time) error

Timeout creates a user timeout for the supplied userID that lasts until duration is exceeded or the timeout is cleared

func (*Context) Unmute added in v0.6.0

func (c *Context) Unmute(userId string) error

Unmute removes a mute on the user, allowing them vc access again

type LogLevel added in v0.3.0

type LogLevel int
const (
	LogLevelAll LogLevel = iota //log all messages, and errors
	LogLevelCmd LogLevel = iota //log only commands and responses, and errors
	LogLevelErr LogLevel = iota //log only errors
)

type Message

type Message struct {
	Author Author
	//current message ID
	ID string
	//message content split on whitespace to allow for easy argument parsing with commands
	Words []string
	//entire message content unchanged
	Content string
	//channel message was sent in, name and ID
	Channel   string
	ChannelID string
	//guild message was sent in, name and ID
	Server   string
	ServerID string
	//message extras
	Attachments []MessageAttachment //any attachments bound to the message
	Mentions    []*dg.User          //users mention in the message with @
}

Message contains all needed data to handle message events

type MessageAttachment added in v0.4.0

type MessageAttachment struct {
	ID           string
	URL          string
	ProxyURL     string
	Filename     string
	ContentType  string
	Width        int
	Height       int
	Size         int
	DurationSecs float64
}

type Option

type Option func(b *bolt)

func WithIndicator

func WithIndicator(i string) Option

WithIndicator sets the substring that must be present at the beginning of a message to trigger a command, for example "." or "!"

func WithIntents added in v0.6.0

func WithIntents(intents ...dg.Intent) Option

WithIntents provides an option to use custom intents for the bot. Bolt comes preconfigured with the basic intents needed to run a bot but those are completely overwritten by any supplied here

func WithLogLevel added in v0.3.0

func WithLogLevel(lvl LogLevel) Option

WithLogLevel adjusts bolt logging verbosity

func WithMaxGoroutines added in v0.6.0

func WithMaxGoroutines(max int) Option

WithMaxGoroutines limits the amount of handler routines the bot is able to spawn at the same time. A lower value may cause higher latency but may reduce resources needed to run bolt

type Payload

type Payload func(c *Context) error

command and message payload function type

type Reaction added in v0.4.0

type Reaction string
const (
	ReactionThumbsUp          Reaction = "👍"
	ReactionThumbsDown        Reaction = "👎"
	ReactionHundred           Reaction = "💯"
	ReactionHeart             Reaction = "❤️"
	ReactionPinkHeart         Reaction = "🩷"
	ReactionOrangeHeart       Reaction = "🧡"
	ReactionYellowHeart       Reaction = "💛"
	ReactionGreenHeart        Reaction = "💚"
	ReactionBlueHeart         Reaction = "💙"
	ReactionBlackHeart        Reaction = "🖤"
	ReactionPointUp           Reaction = "☝️"
	ReactionPointDown         Reaction = "👇"
	ReactionHotdog            Reaction = "🌭"
	ReactionDog               Reaction = "🐶"
	ReactionCat               Reaction = "🐱"
	ReactionMonkey            Reaction = "🐒"
	ReactionGiraffe           Reaction = "🦒"
	ReactionDuck              Reaction = "🦆"
	ReactionGoose             Reaction = "🪿"
	ReactionWatermelon        Reaction = "🍉"
	ReactionHoney             Reaction = "🍯"
	ReactionSandwich          Reaction = "🥪"
	ReactionPepper            Reaction = "🌶️"
	ReactionNoPedestrians     Reaction = "🚷"
	ReactionExclamation       Reaction = "❗"
	ReactionDoubleExclamation Reaction = "‼️"
	ReactionSkull             Reaction = "💀"
	ReactionSpeakingHead      Reaction = "🗣️"
	ReactionGreenCheck        Reaction = "✅"
	ReactionDragon            Reaction = "🐉"
)

a few easy-to-use emojis, Discordgo/Discord API requires them to be saved like this. Some appear "broken" but do not play friendly when saved in-file

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL