如何创建 Discord 机器人

2025年3月25日 | 阅读 17 分钟

Discord 拥有强大的可编程机器人支持,是一个著名的实时聊天应用程序。在 Discord 上,机器人很常见,并且提供各种服务,例如娱乐、游戏、网络搜索、金融处理和版主支持。Toptal 自由职业软件工程师兼聊天机器人程序员 Randall Schmidt 在本文中讨论了 Discord 中机器人的界面和 API,并提供了 Discord 机器人教程。

Discord 最著名的机器人之一 Rythm 的创建者 ImBursting 分享了他创建和管理其庞大基础设施和代码库的见解。

什么是 Discord?

Discord 是一个实时通信网站,它将自己描述为“游戏玩家的一体化文本和语音聊天”。凭借其吸引人的设计、易用性和丰富的功能,Discord 发展迅速,即使对于不太关心电子游戏的人们来说也越来越受欢迎。其用户群在 2018 年至 2022 年间从 5600 万人增长到超过 1.5 亿人。

Discord 最吸引人的方面之一是其机器人使用。Discord 对可定制机器人提供强大支持,这些机器人可增强用户参与度并使 Discord 与外部世界连接。在 Discord 上,机器人很常见,并提供各种服务,例如娱乐、游戏、网络搜索、金融处理和版主支持。

在进入我们将构建基本 JavaScript Discord 机器人的课程之前,在本 Discord 机器人编程教程中,我们将探索 Discord UI 以及其用于机器人的 REST 和 WebSocket API。最后,Discord 最著名的机器人之一的创建者将分享他构建和管理其庞大网络和代码库的经验。

Discord 的用户界面

在深入技术细节之前,了解用户如何与 Discord 互动以及应用程序在他们看来是什么样的至关重要。(虽然这显然是无形的,但理论上它以与机器人显示自己的方式类似的方式显示自己。)机器人使用与官方 Discord 应用相同的 API。Discord 服务条款禁止这一点,尽管理论上可以在普通用户账户中通过最少的修改来运行机器人。机器人必须在机器人账户中运行。

下面显示了基于 Chrome 浏览器的 Discord 程序截图

How to Create A Discord BOT

Discord 的 Web 界面

注意:Discord 的 Web 界面(使用 Electron 打包)与桌面程序基本相同。iOS 应用使用 React Native 构建。Android 应用使用原生 Java 构建。

我们来简化一下。

1. 服务器列表

我的服务器成员列表显示在最左侧。如果您熟悉 Slack,服务器类似于该平台上的工作区。它代表了一组用户,他们可以在某个服务器上通过一个或多个频道相互通信。拥有适当的权限,服务器的创建者、员工或用户可以管理它。服务器的标准、服务器频道的组织以及用户管理都由创建者和/或员工定义。

我的个人服务器列表顶部是 Discord API 服务器。这是一个与开发人员交流并获得帮助的好地方。之后是我命名为 Test 的服务器。稍后,当我们创建好机器人后,我们将在那里测试我们的机器人。在 Test 下面有一个创建新服务器的按钮。只需单击几下,任何人都可以启动一个服务器。

应注意的是,尽管 Discord 用户界面中使用“服务器”一词,但在开发人员文档和 API 中使用了“guild”一词。这两个词都可以使用。

2. 频道列表

再次显示了网络列表和当前正在浏览的服务器(在本例中为 Discord API 服务器)的频道。对用于对频道进行分类的类别数量没有限制。信息、通用和库是一些可在 Discord API 服务器上使用的类别,如所示。用户可以在每个频道中就特定主题进行交流,频道充当聊天室。我们当前正在观看的频道(“info”)的背景稍微亮一些。当发布新消息时,频道名称会显示为白色。

3. 查看频道

频道视图提供了人们正在讨论的主题的信息。显示了一条消息的预览,以及指向各种 Discord 机器人库帮助服务器的链接列表。由于配置原因,普通用户无法在此处发布消息。管理员使用这些频道作为公告板,用于发布重要信息,以便被看到而不被对话掩盖。

4. 用户列表

立即连接到此服务器的人员列表显示在最右侧。用户的名称颜色不同,并且他们被归入不同的组。由于他们扮演的角色,就会发生这种情况。角色概述了用户应被列入的类别(如果有)、其名称的颜色以及他们在服务器上的权限。如果一个用户有多个角色,结果取决于一些优先级计算(这种情况相当频繁)。@everyone 角色是每个用户拥有的最低限度。服务器员工指定并分配其他职责。

5. 文本输入

如果我被允许,我会使用此文本输入来编写和发送消息。我无法在此频道中键入,因为我无权在此处发送消息。

Discord API

WebSocket API 和 REST API 是构成 Discord API 的两个组件。总的来说,使用 WebSocket API 接收来自 Discord 的实时事件,而使用 REST API 在 Discord 中执行操作。

How to Create A Discord BOT

WebSocket API

WebSocket API 主要专注于接收 Discord 事件,例如消息创建、删除、账户踢出/封禁事件、用户授权更改等。另一方面,当机器人使用 WebSocket API 时,通信的空间较小。机器人使用 WebSocket API 来执行许多基本任务,包括连接到服务器、标识自己、保持心跳、管理语音通信等。Discord 的网关文档提供了更多信息。通过 REST API 执行其他活动。

根据事件的类型,来自 WebSocket API 的事件的负载包含信息。例如,一个标识消息作者的用户对象将随每个消息创建事件一起出现。然而,用户对象本身不包含所有用户相关数据。例如,不提供有关用户权限的详细信息。如果需要,您可以使用 REST API 请求更多详细信息,但出于下一节中讨论的原因,您通常应检索您使用早期事件的负载创建的缓存。以下事件,包括但不限于 Guild Creation、Guild Roles Updating 和 Channel Update,都提供了与用户权限相关的有效负载。

每个 WebSocket 连接,一个机器人最多允许在 2,500 个公会中。机器人能够出现在多个公会中需要实现分片并打开多个独立的 WebSocket 连接到 Discord。如果您的机器人只使用一个节点上的一个进程,那么这种额外的复杂性可能显得毫无意义。然而,如果您的机器人非常受欢迎,并且需要将其后端拆分到多个节点上,Discord 的分片功能会使其比其他方式容易得多。

REST API

大多数活动,包括发送文本、封禁或踢出用户以及更改用户权限,都是由机器人使用 Discord REST API 完成的。尽管也可以通过 REST API 检索信息,但机器人通常依赖 WebSocket API 事件并将它们收到的数据保存在缓存中。

为什么?有两个基本原因。例如,由于 REST API 的速率限制,反复查询它以获取用户信息无法扩展。大多数情况下,这也是多余的,因为 WebSocket API 提供了适当的数据,而您应该已经有了它的缓存。

但是,有几种例外情况,并且存在您可能需要不在缓存中的数据的情况。每当机器人首次连接到 WebSocket 网关时,每个公会都会收到一个 Guild Create 事件和一个 Ready 事件,允许机器人用最新的状态填充其缓存。对于人口稠密的公会,Guild Create 事件仅包含在线个人的信息。如果您的机器人需要获取有关离线用户的信息,您的缓存可能没有必要的数据。在这种情况下,请求 REST API 是有道理的。或者,如果您需要定期获取有关离线用户的数据,您可以选择通过发送 Request Guildmates opcode 来获取不活跃的公会成员,从而使用 WebSocket API。

您的应用程序中不存在与 WebSocket API 的连接是另一种例外。例如,假设您的机器人有一个在线仪表板,用户可以登录并修改其服务器上的设置。Web 仪表板可能无法使用 WebSocket API 连接以及 Discord 数据缓存,因为它可能运行在单独的进程中。它可能只需要偶尔进行几次 REST API 调用。在这种情况下,使用 REST API 来获取所需信息是合理的。

Wrapper API

虽然对技术栈的每一层都有基本了解总是一个明智的选择,但直接访问 Discord WebSocket 或 REST API 是耗时的、容易出错的、通常是不必要的,甚至是有害的。

Discord 提供了一个精心挑选的授权库列表,并警告说:

使用不合规的库或滥用 API 或导致高费率限制的专用实现可能会导致永久封禁。

Discord 正式审查过的库通常开发完善、文档齐全,并提供对 Discord API 的全面覆盖。机器人创建者通常不会出于好奇以外的任何原因创建自定义实现。

对于您喜欢的语言,可能有一个、两个或多个库。选择使用哪个可能会很困难。除了阅读相关文档外,您可能还想加入非官方的 Discord API 服务器,以了解每个库所支持的社区。

创建 Discord 机器人

让我们直接开始。为了监控 Ko-fi 的 Webhook,我们将创建一个托管在我们服务器上的 Discord 机器人。借助 Ko-fi,可以轻松地将捐款存入您的 PayPal 账户。由于在此处设置 Webhook 比 PayPal(需要商业账户)简单,因此它非常适合处理小额捐款或作为演示平台。

当用户捐赠 10 美元或更多时,他们会获得 Premium Member(高级会员)身份,这将改变其名称的颜色,并将其排在在线用户列表的顶部。我们将为此项目使用 Node.js 和 Eris Discord API 库。并非所有 JavaScript 库都像 Eris。相反,您可以使用 discord.js。无论您使用哪个库,代码都将非常相似。

另一个捐款处理平台 Patreon 提供了一个专用的 Discord 机器人,并允许将 Discord 角色设置为捐赠者福利。虽然会更简单,但我们计划实现类似的功能。

本教程的源代码可在 GitHub 上找到:https://github.com/mistval/premium bot。为了简洁起见,本文中的一些步骤省略了未修改的代码。如果您觉得可能遗漏了什么,请使用提供的链接访问 GitHub。

生成 Discord 机器人账户

在我们可以开始编写代码之前,需要一个机器人账户。在我们可以构建机器人账户之前,需要一个用户账户。有关如何建立用户账户的信息,请点击此处。然后,为了设置机器人账户,我们需要

1)在开发者门户中创建一个应用程序。

How to Create A Discord BOT

2)填写应用程序的基本信息(请注意此处显示的 CLIENT ID;我们稍后需要使用它)。

How to Create A Discord BOT

3)添加一个登录到应用程序的机器人用户。

How to Create A Discord BOT

4)启用 PUBLIC BOT(公开机器人)选项,然后记下显示的机器人令牌(我们稍后需要它)。如果您发现任何泄露,例如令牌出现在 Toptal 博客文章的图片中,请立即刷新您的机器人令牌。任何拥有机器人令牌的人都可以控制它,干扰您用户的体验,并可能给您和他们带来重大、持久的问题。

How to Create A Discord BOT

5)将机器人添加到您的试用公会。在浏览器中,用您要添加到公会的机器人的客户端 ID(之前已显示)填充给定的 URI。

How to Create A Discord BOT

机器人现在在测试公会中,按下“授权”后,我们可以在用户列表中看到。虽然目前不可用,但我们很快就会解决这个问题。

如何使用 Discord.py 库创建简单的 Discord 机器人

机器人的编程将使用 discord.py 包用 Python 编写。discord.py API 包装器有助于简化 Python Discord 机器人开发。

如何设置 Discord.py 并创建一个 Repl

任何代码编辑器都可以用来在您的计算机本地创建机器人。尽管在本课程中将使用 Repl.it,因为它将使每个人都能更容易地跟上。您可以使用 Repl.it,一个在线 IDE,在您的 Web 浏览器中使用。

首先访问 Repl.it,然后。在创建新的 Repl 时,将 Python 选择为语言。

只需在 main.py 的顶部添加 import discord 即可安装 discord.py 库。当您单击“运行”时,Repl.it 将自动安装此要求。

如果您更愿意在 MacOS 上远程编程机器人,请使用以下命令安装 discord.py

pip3 可能必须替换为 pip。如果您使用的是 Windows,请使用以下代码代替

如何为您的机器人创建 Discord 事件

事件的概念是 discord.py 软件的核心。事件似乎是您听到并做出反应的东西。例如,当发生一条消息时,您会收到一条关于该消息的事件,您可以做出回应。

创建一个响应特定消息的机器人。discord.py 的文档是这个简单机器人代码及其解释的来源。稍后,我们将为机器人添加更多功能。

将此代码包含在 main.py 中。(如果您愿意,可以重命名文件,但不能重命名为 discord.py。)我将很快详细解释此代码的作用。

您在 Discord 上创建机器人客户端时复制了一个令牌。为了保存令牌,我们现在将创建一个 .env 文件。如果您在本地运行代码,则不需要 .env 文件。只需用 os.getenv("TOKEN") 替换令牌即可。

.env 文件用于定义环境变量。在 Repl.it 上,您创建的大多数文件都可以被所有人访问,但 .env 文件只能由您看到。浏览公共 repl 的任何人都无法看到 .env 文件的内容。

因此,如果您在 Repl.it 上工作,请仅将令牌或密钥等机密信息放在 .env 文件中。

通过单击“添加文件”按钮创建具有 .env 扩展名的文件。

How to Create A Discord BOT

通过添加写着一行来包含您之前复制的真实令牌

现在让我们回顾一下您的 Discord 机器人代码中每行的功能。

第一行导入 discord.py 库。

第二行导入 OS 库,但它仅用于访问 .env 文件中的 TOKEN 值。如果未使用 .env 文件,则不需要此行。

然后我们创建一个用户实例。此处建立与 Discord 的链接。

可以使用 @user.event() 装饰器注册事件。由于此库是异步的,因此使用回调来完成任务。作为另一个事件的结果而被调用的函数称为回调。每当机器人准备开始运行时,此代码就会调用 on_ready() 事件。然后,当机器人收到消息时,将执行 on_message() 事件。

每当收到消息时,都会调用 on_message() 事件;但是,如果消息来自自身,我们不希望它产生任何影响。因此,如果 user.client 和 Message.author 匹配,则函数将简单地返回。

接下来,我们检查 Message.content 是否包含字符串“$hi”。在这种情况下,机器人会回复它所在的频道“Hi!”。

最后一行使用登录令牌启动机器人,配置完成后。令牌从 .env 文件中获取。

现在机器人代码已经可用,剩下要做的就是运行它。

运行机器人

现在,通过单击顶部的运行按钮在 Repl.it 中启动您的机器人。如果您在本地编写了代码,请在终端中输入以下命令来启动机器人

Python3 main.py 在不同平台上使用。

现在,在您的 Discord 频道中输入“$hii”。您的机器人应该会回复“Hii!”。

How to Create A Discord BOT

机器人的改进建议

现在机器人已经运行起来了,我们将对其进行改进。该程序之所以被称为 Inspiration Bot,是有原因的。每当有人给这个机器人发送带有悲伤或沮丧词语的消息时,机器人都会回复一条鼓舞人心的消息。

任何人都可以贡献鼓舞人心的消息供机器人使用,用户提供的消息将保存在 Repl.it 数据库中。

当聊天者输入“$inspire”短语时,机器人还将从 API 提供一个随机的励志名言。

我们首先介绍“$inspire”功能。

如何在机器人中包含励志名言

我们将通过 Zenquotes.io API 获取励志名言。需要导入更多 Python 模块,需要添加 get_text() 方法,并且需要更新我们的机器人代码,以便它可以使用新功能。

这是修改后的代码。我将在代码之后描述新组件。

requests 模块需要立即导入。此模块允许我们的代码向 API 发送 HTTP 请求以从中获取数据。json 模块有助于处理 API 提供的 JSON 格式数据。

get_text() 方法非常简单。为了从 API URL 获取数据,它首先使用 requests 模块。API 返回不可预测的励志名言。如果当前的 API 失败,可以轻松修改此方法以从新 API 获取名言。

然后,在函数中使用 json.loads() 方法将 API 的响应转换为 JSON。经过多次反复试验,我终于找到了如何将 JSON 名言转换为我需要的格式文件。该函数返回一个包含名言的字符串。

代码的最后修改部分在最后。以前,它查找以“$hi”开头的消息。现在它查找“$inspire”。它使用 text = get_text() 检索名言,并返回文本而不是返回“Hi!”。

您现在可以执行代码并进行测试。

如何在机器人中包含励志信息

现在功能已经开发完成,当用户发送包含“sad”一词的消息时,机器人将用积极的评论回复。

如何修改机器人以使用悲伤词语

为了让机器人听到悲伤的短语时做出反应,我们必须首先创建一个此类词语的 Python 列表。

在创建 client 变量后,添加以下行

sad_words = ["sad", "miserable", "unhappy", "angry", "depressed"]

随意用更多词语扩展列表。

如何在机器人中包含励志信息

现在将添加一系列励志信息供机器人使用。

在您准备好的 sad_words 列表之后,添加以下列表

和以前一样,随意用更多词语和短语扩展列表。我现在只使用三项,因为用户很快就可以上传其他励志名言供机器人使用。

回复消息的方法

现在我们已经构建了两个列表,我们必须修改我们的机器人以使用它们。由于机器人会随机选择励志信息,因此首先导入 random 模块。将 import random 添加到代码开头的导入声明中。

现在 sad_words 列表已更新,on_message() 函数现在将检查每条消息是否包含其中的任何词语。每当发现沮丧的词语时,机器人将随机给出一条励志信息。

此处提供了更新的代码

此时应测试机器人。现在您已经足够熟练,可以构建自己的机器人了。然后,我们将使用 Repl.it 数据库来学习高级功能和存储数据。

允许用户上传的消息

现在机器人已全面运行,让我们使其能够直接从 Discord 进行更新。当机器人注意到一个沮丧的词语时,用户应该可以选择提交更多积极的评论。

用户提交的消息将保存在 Repl.it 中已存在的数据库中。每个 repl 都包含此数据库,这是一个键值存储。

在其他导入声明之后,在代码开头添加 from replit import database。因此,我们将能够访问 Repl.it 数据库。

用户可以直接从 Discord 对话上传自己的消息供机器人使用。在我们添加新的指令之前,让我们构建两个辅助方法来将个性化消息添加到数据库并从中删除它们。当 get_text() 方法完成后,添加以下代码

可以将励志信息作为输入传递给 update_inspirations() 方法。

它首先确定数据库中是否有一个名为“inspirations”的键。如果是,它检索数据库中的励志列表,将其添加到列表中,然后在“inspirations”键下保存修改后的列表。

如果数据库尚不包含“inspirations”,则将新的励志消息作为列表的第一个元素插入,并生成一个名为该名称的新键。

delete_inspirations() 方法接受索引输入。

它访问数据库的“inspirations”键以获取励志列表。如果励志列表中的条目多于索引位置,则删除该列表中的条目。

最后,最新更新将被存储回数据库的“inspirations”键中。