Discord
8/12/2023
Discord Ping Pong Bot
用 Go 写一个 Discord Bot
Intro
在数字时代,聊天机器人在互动、娱乐和工作场景中扮演着越来越重要的角色。
Discord,作为一款广受欢迎的社交平台,不仅仅是玩游戏的好地方,还是互相交流、分享兴趣爱好的社群网络。 而在这个丰富多彩的生态系统中,编写一个 Discord 机器人,不仅能够为服务器增添趣味和实用性,还能让我们更好地理解编程和自动化的魅力。
Discord,作为一款广受欢迎的社交平台,不仅仅是玩游戏的好地方,还是互相交流、分享兴趣爱好的社群网络。 而在这个丰富多彩的生态系统中,编写一个 Discord 机器人,不仅能够为服务器增添趣味和实用性,还能让我们更好地理解编程和自动化的魅力。
在这篇博文中,我使用 DiscordGo 构建了一个简单的 Ping Pong Bot,详细记录了从 Bot 的创建到代码的编写和测试整个过程。
我将其分为如下三个部分:
- 准备阶段
- 创建 Bot App
- 创建 Discord Server
- 将 Bot 添加到 Server
- 编写代码
- 初始化项目并安装环境
- 编写业务代码
- 测试 Bot
在准备阶段,我创建了一个 Discord Bot App 和一个测试用的 Discord Server,然后将 Bot 添加到 Server 中。
在编写代码阶段,我使用 DiscordGo 编写了一个简单的 Ping Pong Bot,如果用户在频道中输入 ping,bot 将在频道中回复 Pong。
在测试阶段,我在频道中测试了 Bot 的功能。
在编写代码阶段,我使用 DiscordGo 编写了一个简单的 Ping Pong Bot,如果用户在频道中输入 ping,bot 将在频道中回复 Pong。
在测试阶段,我在频道中测试了 Bot 的功能。
Create a New Discord App
创建一个新的 Bot App,是我们要做的第一件事。
-
点击头像旁边的 New Application
-
输入应用名称,点击 Create

Create a New App
Configure Ping Pong Bot
为了 Bot 能正常的收发消息,我们需要对其进行一些必要的配置,在 sidebar 中点击 Bot,这里列出了 bot 的相关配置
这里我们需要完成以下两项配置
这里我们需要完成以下两项配置
- disable PUBLIC BOT : 关闭公共 bot,我们的 bot 是私有的
- enable MESSAGE CONTENT INTENT,为了能正常收到消息,将此配置打开

Configure Bot
Add Your Own Server
接着,我们打开 Discord 客户端,添加一个服务器,这个服务器会用来测试 Ping Pong Bot 是否正常工作
在 sidebar 中点击 + 号,填入自己的信息,完成创建即可
在 sidebar 中点击 + 号,填入自己的信息,完成创建即可

Create Server
Configure Required Permissions and Generate Invite Link
在服务器创建完毕之后,我们需要把机器人邀请到服务器中
回到 Discord Developer Portal,在 sidebar 中点击 OAuth2 -> URL Generator
回到 Discord Developer Portal,在 sidebar 中点击 OAuth2 -> URL Generator
在这个界面中,我们需要配置 Bot 的权限
- SCOPES:
- Bot
- BOT PERMISSIONS:
- Send Messages
- Read Message History
- Read Messages / View Channels

Generate Invite Link
选择完毕之后, URL 会自动在下方的输入框中,打开这个 URL,
点击 Authorize 按钮,即可将我们的机器人添加到服务器中

Invite Bot
进入我们的服务器,即可看到 Bot 已经成功被添加到服务器中 🎉

Test App Server
Get Token
至此,我们创建好了我们的 bot 和测试服务器,并且已经把 bot 添加到了服务器中。
在正式开始编码之前,我们先获取一下 Bot 的 token 在 Discord Developer Portal 点击 Bot -> Reset Token,之后会显示出新的 token,复制下来,稍后将其写入代码,用于验证身份
在正式开始编码之前,我们先获取一下 Bot 的 token 在 Discord Developer Portal 点击 Bot -> Reset Token,之后会显示出新的 token,复制下来,稍后将其写入代码,用于验证身份

Get Token
Coding
OK,完成了所有准备工作,接下来我们开始编码,让我们的机器人能正常工作
首先创建一个 Go 项目,执行如下命令,安装依赖
go get github.com/bwmarrin/discordgo 首先编写 Bot 结构体
在
在
NewBot 方法中创建 discord session,在 Start 方法中将 session 打开package discord
import (
"github.com/bwmarrin/discordgo"
"strings"
)
type Bot struct {
session *discordgo.Session
token string
}
func NewBot(token string) *Bot {
bot := &Bot{
token: token,
session: createSession(token),
}
return bot
}
func (bot *Bot) Start() {
session := bot.session
if err := session.Open(); err != nil {
panic(err)
}
defer session.Close()
fmt.Println("Bot running...")
bot.holdOn()
}
func (bot *Bot) holdOn() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
<- c
}
func createSession(token string) *discordgo.Session {
session, err := discordgo.New(token)
if err != nil {
panic(err)
}
return session
}
为了避免程序直接关闭,我们使用
holdOn 方法阻塞程序,在 holdOn 方法中我创建了一个 channel,让程序等待一个 os.Interrupt 信号再继续向下执行上述代码完成了 Bot 的启动流程,现在我们向其中添加处理消息的函数(
EventHandler)func (bot *Bot) Start() {
session := bot.session
session.AddHandler(handler) // 添加 EventHandler
if err := session.Open(); err != nil {
panic(err)
}
defer session.Close()
fmt.Println("Bot running...")
bot.holdOn()
} 我们在 Start 方法中添加一行
这会把消息处理函数添加到 session 中,当有消息发送过来时,session 会调用 handler 函数处理消息。
session.AddHandler(handler)这会把消息处理函数添加到 session 中,当有消息发送过来时,session 会调用 handler 函数处理消息。
接着,我们在 handler 函数中编写具体的 ping pong 逻辑
handler 函数接受两个参数
handler 函数接受两个参数
*discordgo.Session:bot 实例的 session 属性*discordgo.MessageCreate:传递了消息的相关信息,包括消息内容、发送者、提及等信息。
DiscordGo 会自动地根据 handler 的参数类型判断我们要监听的事件类型,比如这里我们传入的是
*discordgo.MessageCreate,那么 bot 就会监听 MessageCreate 事件。Discord Gateway Doc 中列出了所有可以监听的事件。
除此之外,不要忘记 bot 只需回复他感兴趣的消息,因此我们判断一下哪些消息需要回复。
这里我们把 bot 自己的消息忽略,并且只回复提及自己的消息,我们将具体的逻辑写入
shouldReply 方法中,并在 handler 方法中调用进行判断。package discord
import (
"strings"
"github.com/bwmarrin/discordgo"
)
func handler(session *discordgo.Session, message *discordgo.MessageCreate) {
if shouldReply(session.State.User.ID, message) {
switch {
case strings.Contains(message.Content, "ping"):
_, err := session.ChannelMessageSend(message.ChannelID, "pong")
if err != nil {
println(err.Error())
}
case strings.Contains(message.Content, "pong"):
_, err := session.ChannelMessageSend(message.ChannelID, "ping")
if err != nil {
println(err.Error())
}
}
}
}
// shouldReply 判断是否需要回复
func shouldReply(botId string, message *discordgo.MessageCreate) bool {
// ignore messages from the bot itself
if message.Author.ID == botId {
return false
}
// ignore messages that don't mention the bot
for _, mentionedUser := range message.Mentions {
if mentionedUser.ID == botId {
return true
}
}
return false
} OK,目前,我们已经把 EventHandler 添加到了 bot 中,现在让我们编写 main.go,启动我们的 bot
把 bot 的 token 拷贝过来用于验证身份,然后启动程序即可
package main
import "dev/hylas/discord-bot/discord"
const token = "${your-token}"
func main() {
bot := discord.NewBot("Bot " + token)
bot.Start()
} Test Bot
打开 Discord 客户端,进入我们创建的服务器
输入 @Ping Pong Bot ping 和 @Ping Pong Bot pong
输入 @Ping Pong Bot ping 和 @Ping Pong Bot pong

Test Bot
Author: Hylas Publication Date: 8/12/2023
Licensed under CC BY-NC 3.0