88/100 Dias de Golang - Bot para discord
Table of Contents
#
Bot para discord
Vamos criar um bot para discord usando Golang. Quero focar na parte somente de criar as funções para o bot, a parte de configuração dele no discord você pode procurar em outros lugares, vou deixa uma lista aqui:
A única coisa que você precisa dessa etapa é o token gerado pelo discord.
A ideia é fazer dois posts, um mostrando o primeiro comando e outro organizando o projeto e deixando ele mais “profissional”.
Nesse primeiro, vamos configurar o projeto, instalar libs e criar um comando ping
.
Veja a estrutura que usaremos de pastas:
discord-bot-go/
├── cmd/
│ └── bot/
│ └── main.go
├── config/
│ └── config.go
├── internal/
│ ├── bot/
│ │ ├── client.go
│ │ └── handlers.go
├── go.mod
└── .env
No .env
devemos adicionar o token fornecido pelo discord
DISCORD_BOT_TOKEN=seu_token_aqui
Vamos iniciar criando o arquivo config.go
a função dele é carregar o token do arquivo .env
, iremos usar a lib godotenv
package config
import (
"log"
"os"
"github.com/joho/godotenv"
)
func LoadToken() string {
err := godotenv.Load()
if err != nil {
log.Fatal("Erro ao carregar .env")
}
token := os.Getenv("DISCORD_BOT_TOKEN")
if token == "" {
log.Fatal("Token não encontrado no .env")
}
return token
}
Dentro do arquivo internal/bot/client.go
temos a estrutura inicial de conexão do bot. Iremos usar a biblioteca discordgo.
package bot
import (
"log"
"os"
"os/signal"
"syscall"
"github.com/bwmarrin/discordgo"
)
func Start(token string) {
dg, err := discordgo.New("Bot " + token)
if err != nil {
log.Fatalf("Erro ao criar sessão do Discord: %v", err)
}
dg.AddHandler(messageCreate)
err = dg.Open()
if err != nil {
log.Fatalf("Erro ao abrir conexão com Discord: %v", err)
}
log.Println("Bot está online. Pressione CTRL+C para sair.")
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-stop
dg.Close()
}
Na linha:
dg.AddHandler(messageCreate)
Fazemos o registro da função que irá tratar as mensagens. Mas a parte legal desse código são essas 3 linhas:
stop := make(chan os.Signal, 1)
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
<-stop
Essa estrutura é usada para capturar sinais do sistema operacional e encerrar a aplicação de forma controlada. Primeiro, é criado um canal chamado stop
que receberá valores do tipo os.Signal
. Em seguida, a função signal.Notify
registra esse canal para escutar sinais específicos como SIGINT
(geralmente enviado ao pressionar Ctrl+C), SIGTERM
(usado para encerramento gracioso em servidores), e os.Interrupt
. A linha <-stop
bloqueia a execução do programa até que algum desses sinais seja recebido.
No arquivo internal/bot/handlers.go
iremos definir as funções de cada comando. No nosso caso uma bem simples, o usuário envia !ping
e retornamos Pong
.
package bot
import (
"strings"
"github.com/bwmarrin/discordgo"
)
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
if m.Author.Bot {
return
}
content := strings.ToLower(m.Content)
if content == "!ping" {
s.ChannelMessageSend(m.ChannelID, "Pong")
}
}
E nosso arquivo cmd/bot/main.go
temos a “conexão” entre as partes.
package main
import (
"discord-bot-go/config"
"discord-bot-go/internal/bot"
)
func main() {
token := config.LoadToken()
bot.Start(token)
}
Antes de executar, lembrar de instalar as bibliotecas com:
go mod tidy
E para executar:
go run cmd/bot/main.go