Post

How to Write a Discord Bot in Go Using discordgo

How to Write a Discord Bot in Go Using discordgo

Discord bots are a fun and powerful way to interact with users in a Discord server. With the Go programming language (Golang), you can quickly write efficient and robust bots that can automate tasks, provide entertainment, or manage servers. In this article, we will guide you through the process of building a simple Discord bot using the popular Go library discordgo.

⚙️ Prerequisites

Before you get started, make sure you have the following:

  1. Go Installed: Ensure Go is installed on your system. You can download it from the official website: Go Downloads. Alternatively you can also use a devcontainer - e.g. mcr.microsoft.com/devcontainers/go:1-1.21-bookworm
  2. Discord Account: You need a Discord account and a server where you can test your bot.
  3. Bot Token: You will need a bot token to interact with Discord’s API. Follow these steps to create a bot on Discord:
    • Go to Discord Developer Portal.
    • Click New Application and give it a name.
    • In the Bot tab, click Add Bot and then Copy Token. You’ll need this token to authenticate your bot.
  4. Go Module Setup: You should have Go modules enabled for dependency management.

🛠️ Step 1: Set Up Your Go Project

  1. First, create a directory for your project:
    1
    2
    
    mkdir discord-bot
    cd discord-bot
    
  2. Initialize a Go module for the project:
    1
    
    go mod init discord-bot
    
  3. Install the discordgo library. This is the Go library used to interact with Discord’s API.
    1
    
    go get github.com/bwmarrin/discordgo
    

Now, your Go project is set up and ready to interact with Discord.


🧾 Step 2: Create the Bot Code

In your project folder, create a new Go file, main.go, and open it in your editor of choice.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/bwmarrin/discordgo"
)

func main() {
	// Get the bot token from environment variable (recommended)
	Token := os.Getenv("DISCORD_TOKEN")
	if Token == "" {
		fmt.Println("No token provided. Set the DISCORD_TOKEN environment variable.")
		return
	}

	// Create a new Discord session using the provided bot token.
	dg, err := discordgo.New("Bot " + Token)
	if err != nil {
		fmt.Println("error creating Discord session,", err)
		return
	}

	// Register the messageCreate function as a callback for the MessageCreate event.
	dg.AddMessageCreateHandler(messageCreate)

	// Open a websocket connection to Discord and begin listening.
	err = dg.Open()
	if err != nil {
		fmt.Println("error opening connection,", err)
		return
	}
	defer dg.Close()

	fmt.Println("Bot is now running. Press CTRL+C to exit.")
	select {}
}

// This function will be called every time a new message is created in the Discord server.
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
	// Ignore messages from the bot itself.
	if m.Author.ID == s.State.User.ID {
		return
	}

	// Respond to a simple command "!ping"
	if m.Content == "!ping" {
		s.ChannelMessageSend(m.ChannelID, "Pong!")
	}
}

📌 Explanation:

  • Bot Token: The bot’s token is fetched from the environment variable DISCORD_TOKEN. Make sure to set this token in your environment for security reasons (don’t hardcode it in the source code).
  • Creating a Session: The discordgo.New method creates a new session using your bot token, which allows the bot to communicate with Discord.
  • Message Handler: We use dg.AddMessageCreateHandler(messageCreate) to register a callback function that will be executed whenever a message is sent in any server the bot is a member of.
  • Responding to Commands: If a message contains !ping, the bot will respond with Pong!.

🔐 Step 3: Set the Discord Token

It’s a best practice to store sensitive information like bot tokens in environment variables. To do this, create a .env file (or set the environment variable directly in your shell).

  1. If you use a .env file, you can create one and add the token like this:
    1
    
    DISCORD_TOKEN=your-bot-token-here
    
  2. To load the .env file into your Go program, you’ll need a package like github.com/joho/godotenv (if you haven’t installed it, run go get github.com/joho/godotenv).

Then, modify your main.go to load the .env file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import (
	"fmt"
	"log"
	"os"
	"github.com/joho/godotenv"
	"github.com/bwmarrin/discordgo"
)

func init() {
	// Load environment variables from the .env file
	err := godotenv.Load()
	if err != nil {
		log.Fatal("Error loading .env file")
	}
}

Make sure your .env file is in the root directory of your project, and the bot will now use the environment variable for the token.


🚀 Step 4: Running the Bot

  1. Open a terminal and navigate to your project folder.

  2. Run your bot:
    1
    
    go run main.go
    

    If everything is set up correctly, you should see Bot is now running. Press CTRL+C to exit. in the terminal.

  3. Invite your bot to your Discord server:
    • In the Discord Developer Portal, go to your application and navigate to the OAuth2 tab.
    • Under OAuth2 URL Generator, select bot in the scopes section.
    • In the bot permissions section, choose the permissions your bot will need (for example, Send Messages, Read Messages).
    • Copy the generated URL, open it in your browser, and authorize your bot to join a server.
  4. Once the bot is online, type !ping in your server, and your bot should reply with Pong!.

🧩 Step 5: Adding More Features

Now that you have a basic bot set up, you can expand its functionality. Here are a few ideas to get you started:

💬 5.1 Respond to More Commands

You can add more commands by modifying the messageCreate function:

1
2
3
if m.Content == "!hello" {
	s.ChannelMessageSend(m.ChannelID, "Hello, world!")
}

🌈 5.2 Add Embed Messages

Embeds allow you to send rich content in messages:

1
2
3
4
5
6
7
8
if m.Content == "!embed" {
	embed := &discordgo.MessageEmbed{
		Title:       "Sample Embed",
		Description: "This is an embedded message!",
		Color:       0x00ff00, // Green color
	}
	s.ChannelMessageSendEmbed(m.ChannelID, embed)
}

📡 5.3 Use Other Events

You can also listen for other events, such as when the bot joins a server or when a user joins a voice channel. To do this, simply add more event handlers, like:

1
dg.AddGuildMemberAddHandler(guildMemberAdd)
1
2
3
func guildMemberAdd(s *discordgo.Session, m *discordgo.GuildMemberAdd) {
	s.ChannelMessageSend(m.GuildID, fmt.Sprintf("Welcome to the server, %s!", m.User.Username))
}

🌐 Step 6: Deploy Your Bot

Once you’re happy with your bot, you can deploy it to a server or cloud service to run it 24/7. Popular options include:

  • Heroku: Easy to use and provides free hosting for small bots.
  • AWS: More control and scalability, but requires some setup.
  • DigitalOcean: Affordable VPS hosting with good performance.
  • Uberspace.de: A nice German hosting provider where you also can host go bots.

Simply deploy your Go application to one of these platforms, set your environment variables, and your bot will be live 24/7.


🧠 Final Thoughts

In this article, you learned how to create a simple Discord bot in Go using the discordgo library. We covered setting up your development environment, writing the bot code, and adding basic features like responding to commands. We also explored some ideas for expanding your bot’s functionality.

With Go’s speed and simplicity and the discordgo library’s powerful features, you can create feature-rich and efficient Discord bots. Happy coding!

This post is licensed under CC BY 4.0 by the author.