发布于 2026-01-05 11 阅读
0

从零开始构建一个现代化的 Discord 机器人。学习基础知识。

从零开始构建一个现代化的 Discord 机器人。学习基础知识。

Discord 机器人可以帮助您与服务器成员互动,并管理服务器。Discord 机器人可以在服务器上发送消息、直接向用户发送私信 (DM)、封禁用户、提升和降级用户等等。

作为服务器所有者,您不可能一直都在监控服务器,但机器人可以,而且速度更快。

您可能不是服务器所有者,但您想为自己所属的服务器创建一个机器人,或者创建一个公共机器人(供其他服务器使用),本文将帮助您实现这一目标。

在深入代码之前,让我们先来看看 Discord 机器人是如何工作的。

本文
主要面向不了解 Discord 机器人工作原理及构建方法的初学者。如果您已经熟悉 Discord 机器人的构建,本文内容可能不会对您有所帮助。

虽然这是面向初学者的教程,但我希望你对NodeJS和npm有一定的了解。

Discord机器人的工作原理

如果你所在的服务器里有机器人,你可能已经注意到这些机器人与用户帐户非常相似。

他们通常使用类似机器人的头像,似乎总是在线,回复消息速度也很快。这些都很酷,但这一切是怎么实现的呢?

有一种专门用于自动化操作的用户类型,称为机器人账户。它们看起来与普通用户账户非常相似。

机器人帐户使用令牌(而不是用户名、密码)进行身份验证,该令牌使这些帐户能够完全访问所有 Discord API 路由。

所以基本上,

  1. 我们在 Discord 开发者网站上创建了一个机器人(更多详情即将公布)。
  2. 为机器人分配角色,即授予机器人权限。
  3. 为机器人创建 OAuth 范围(简单来说,就是一个用于身份验证的链接)
  4. 将机器人添加到我们的某个服务器
  5. 砰!机器人开始施展魔法,比如回复消息。

很简单。不过我必须提醒一下,在机器人开始运行之前,你需要连接到 Discord API 并登录机器人。以下是创建这个机器人的方法。

  1. 在 Discord 中创建机器人
  2. 为我们的机器人创建权限
  3. 生成 OAuth 链接并使用它来连接到我们的 Discord 服务器
  4. 然后,我们将在电脑上创建一个用于存放机器人的文件夹,并打开 VSCode。
  5. 安装一些依赖项,编写一些代码来连接到 Discord API
  6. 至此,我们的机器人已上线。

现在不明白也不用担心,后面会详细解释。

你可以用 Discord 机器人构建什么?

Discord 机器人种类繁多,从适合老公使用的简单机器人到功能强大的机器人,应有尽有。你可以用 Discord 机器人构建任何东西。以下是一些示例。

  • YouTube视频抓取器
  • 有趣的推文抓取器
  • 来自Reddit的表情包抓取器
  • 一场游戏
  • 带有日历的日程安排器
  • 音乐播放器和歌曲搜索器
  • 服务器管理器
  • 测验机器人

还有更多。这里还有一些Discord 机器人创意。

关于机器人

本文将介绍的机器人将非常基础,但它几乎包含了构建你自己的超级机器人所需的一切。

有了这个机器人,我们将能够回复消息(命令)、查看消息历史记录、发送私信。

所以请尽量跟上进度。我会在我的 Discord 服务器上进行这个项目。

如果你没有自己拥有或管理的服务器,你应该创建一个。

让我们创建第一个机器人

提醒一下,这是对本文的配套练习。所以,阅读时尽量跟着我做。

创建机器人

首先,我们需要在Discord开发者页面上创建机器人。要创建机器人,首先需要创建一个应用程序。

  1. 所以请前往https://discord.com/developers/applications,点击右上角的“创建新应用程序” 。
  2. 输入应用名称。你可以随意命名,但为了方便本教程,我将其命名为“Buddy”。

太棒了!你刚刚创建了你的第一个Discord应用程序。现在让我们来创建机器人。

  1. 点击左侧导航栏中的“机器人” 。
  2. 现在点击“添加机器人”
  3. 将会弹出一个对话框,只需点击蓝色按钮即可继续。

雅虎!一个野生机器人出现了!准备好赋予它生命了吗?

机器人权限和 OAuth

现在我们需要为这个机器人定义一些权限,但为此我们首先需要创建一个 OAuth 作用域。这很简单。

点击左侧导航栏中的OAuth2 。

这里你会看到一些复选框,其子标题为“范围”。

在中间一栏找到“bot”,勾选它。

定义权限

(仅当您在第一组复选框中勾选后)将显示名为“机器人权限”的子标题下的另一组复选框。

现在选择您希望机器人拥有的权限,为了本教程的演示,我们再次选择。

  1. 查看频道(这是必填项)。
  2. 发送消息。
  3. 嵌入链接。
  4. 管理消息。
  5. 查看消息历史记录。

这就是这个机器人所需的所有权限。

完成后,滚动回到第一组复选框(“范围”),复制下面的链接。

在浏览器中打开一个新标签页,粘贴该链接,接下来选择你想让机器人运行的服务器。然后点击“继续”

接下来,您将看到我们选择的权限列表,您可以直接点击“授权”继续,验证您是真人,这样就完成了。

如果你查看你邀请这个机器人加入的 Discord 服务器,你会发现机器人已经加入,但处于离线状态。现在是时候让它活跃起来了。

正在连接到 Discord API

我相信你的本地计算机上已经创建了一个文件夹。如果没有,请立即创建。

本教程将使用NodeJS。您也可以使用其他语言,例如Python,来构建Discord机器人。

建立我们的环境

文件夹已准备就绪,打开终端并运行npm init -y

要运行此程序,您的本地计算机需要安装 NodeJS 和 NPM(特别是 NodeJS 16.6.0 或更高版本)。

安装依赖项

我们只需要两个依赖项:- Discord.js:npm install discord.js- Nodemon(开发依赖项):npm install -D nodemon
运行以上命令安装依赖项。

Discord.js 允许我们在 NodeJS 中与 Discord API 进行交互。

Nodemon会在每次进行并保存新更改时重启应用程序。

继续

创建一个名为app.js的文件。你可以把它命名为任何名称,比如 bot.js 或 index.js。

打开package.json文件,并将main更改为你刚刚创建的文件名。

接下来,将这些 JSON 脚本复制到package.json文件中的 scripts 属性中。

  "scripts": {
    "app": "nodemon app",
    "start": "node app"
  },
Enter fullscreen mode Exit fullscreen mode

继续

创建一个名为config 的文件夹和一个名为default.js 的文件;我们将把我们的密钥存储在这里。

将以下内容复制到config/default.js 文件中

const config = {
  DISCORD_TOKEN: 'YOUR TOKEN HERE',
};
module.exports = config;
Enter fullscreen mode Exit fullscreen mode

请将“YOUR TOKEN HERE”替换为您的 Discord 令牌。

您可以在 Discord 开发者页面找到您的 Discord 令牌。点击您的应用,点击左侧导航栏中的“机器人” ,然后点击“复制”(靠近机器人头像)。

继续

在 config 文件夹中创建一个名为config.js 的文件。这样你就有了config/config.js 文件。在这个文件中,我们将包含所有的配置信息。

这些配置包括命令、前缀和意图。

  • 命令就是机器人会响应的指令。因此,每当用户在 Discord 服务器中输入命令时,机器人都会做出相应的响应。

  • 前缀(或多个前缀,可能有所不同)是命令前缀。对于这个机器人,我们只会使用一个前缀。前缀用于命令之前,例如 !get-meme。! 是前缀,而 get-meme 是命令。

你也可以直接调用 !get-meme 命令。

  • 意图是新增的功能,它用于指定你希望机器人根据其行为接收的事件。如果没有指定这些意图,Discord API 将抛出错误。

那么,我们开始吧。

构建一个 Discord 机器人

我们先让机器人上线。

转到config/config.js并导入 Intents。

const { Intents } = require('discord.js');
Enter fullscreen mode Exit fullscreen mode

请复制并粘贴以下代码。

const {
  DIRECT_MESSAGES,
  GUILD_MESSAGES,
  GUILDS,
} = Intents.FLAGS;
Enter fullscreen mode Exit fullscreen mode

这些是我们希望机器人拥有的权限,因此我们只是从“discord.js”提供的 Intents.FLAGS 中解构它。

创建一个名为“botIntents”的数组,并将上面的变量复制粘贴到其中,这样你就得到了类似这样的结果:

const botIntents = [
  DIRECT_MESSAGES,
  GUILD_MESSAGES,
  GUILDS,
];
Enter fullscreen mode Exit fullscreen mode

现在导出 botIntents

module.exports = { botIntents };
Enter fullscreen mode Exit fullscreen mode

在app.js导入以下内容

const { Client } = require('discord.js');
const { botIntents } = require('./config/config');
const config = require('./config/default');
Enter fullscreen mode Exit fullscreen mode

然后粘贴这段文字

const client = new Client({
  intents: botIntents,
  partials: ['CHANNEL', 'MESSAGE'],
});
Enter fullscreen mode Exit fullscreen mode

在这里,我们通过 'discord.js' 中的类创建一个新客户端Client,并传入一些属性。

第一个属性是 intents,也就是我们的 botIntents;最后一个属性是 partials,它是一个数组,用于让我们的机器人能够发送私信。如果您不需要此功能,可以移除该属性。

继续

现在我们有了 Discord API 的访问权限,我们可以监听事件了。

我们要监听的第一个事件是 onready。换句话说,就是机器人准备好上线的时候。

client.on('ready', () => {
  console.log('Logged in as ' + client.user.tag);
});
Enter fullscreen mode Exit fullscreen mode

当机器人准备上线时,我们只需将机器人的名称记录到控制台即可。

我们快完成了。在机器人上线之前,我们需要使用 Discord 令牌登录。

在app.js 文件底部复制粘贴以下内容

client.login(config.DISCORD_TOKEN);
Enter fullscreen mode Exit fullscreen mode

请注意,配置文件是一个保存我们 Discord 令牌的对象。

现在运行该应用程序,进入你的 Discord 服务器,你就会看到机器人在线。

虽然机器人已上线,但它无法发送或回复任何消息。所以我们接下来就来解决这个问题。

设置命令

我通常使用正则表达式来设置命令,并使用 switch 和 case 语句来检查使用了哪个命令。这就是机器人监听不同命令的方式。

但这个机器人很简单,所以我们也会尽量简化操作。

config/config.js 文件中,我们来注册一些命令。创建一个名为 `<command>` 的对象commands,并将以下内容粘贴到其中,例如:

const commands = {
  getName: 'get-name',
  tellJoke: 'tell-a-joke',
  sad: 'sad',
  lastMsgs: 'last-messages',
};
Enter fullscreen mode Exit fullscreen mode

所以,这些就是我们的机器人将要监听的命令。

在导出之前,创建一个变量并将其命名为prefix`$`,然后将其赋值为 `!`。您也可以使用任何其他前缀,例如 `$`。这样我们就有了 `$`。const prefix = '!';

分别将命令和前缀导出为命令和前缀。

app.js中,从config/config.js导入命令和前缀。只需将其添加commands, prefix到花括号周围即可botIntents

继续

将以下内容复制粘贴到app.js 文件中

client.on('messageCreate', (msg) => {
  if (msg.author.bot) return;
  if (!msg.content.startsWith(prefix)) return; // do nothing if command is not preceded with prefix

  const userCmd = msg.content.slice(prefix.length);

  if (userCmd === commands.getName) {
    msg.reply(msg.author.username);
  } else {
    msg.reply('I do not understand your command');
  }
});
Enter fullscreen mode Exit fullscreen mode

哇,这里发生的事情太多了。我们来逐一分析一下吧?

  • 我们监听了一个名为 的事件messageCreate,还有其他类似messageDeletemessageReactionAdd等的事件。请查看文档了解所有事件。
  • messageCreate事件返回一个包含消息信息的 msg 参数。
  • 接下来,我们检查消息是否来自机器人msg.author.bot。在这里,我们要确保忽略来自机器人的消息。
  • 此外,我们会忽略不包含我们声明的前缀(“!”)的消息。
  • 下一步是获取不带前缀的实际消息,这就是我们去掉前缀的原因。然后我们将其分配给 userCmd(即用户命令)。
  • 最后,我们检查了消息内容(现在去掉前缀)是否与我们的第一个命令(即 getName)相同。如果相同,则
  • 我们使用 (msg.author.username) 向用户回复了用户名。更多关于消息的信息,请参阅文档。如果回复内容不一致,请继续阅读。
  • 我们回复了另一条消息:“我不理解您的命令”。

保存更改。前往你的 Discord 服务器,输入任意一条带有前缀的消息,查看回复。现在输入“!get-name”,也查看回复。

你可以用一些技巧让消息更友好一些Your discord username is ${msg.author.username}。这在实际的聊天机器人中并不实用,因为它会返回用户的用户名。但至少它展示了哪些功能是可行的。

接下来,
要添加其余命令,我们只需else if在初始的 if 语句链中添加更多内容即可。像这样。

if (userCmd === commands.getName) {
  msg.reply(msg.author.username);
} else if (userCmd === commands.tellJoke) {
  msg.reply('HTML is a programming language'); // bad joke i guess, unless i don't have any jokes
} else if (userCmd === commands.sad) {
  msg.reply("Don't be sad! This is not the end of the road");
} else if (userCmd === commands.lastMsgs) {
  const reply = await getLastMsgs(msg);
  msg.reply(reply);
} else {
  msg.reply('I do not understand your command');
}
Enter fullscreen mode Exit fullscreen mode

为了获取最后一条消息,我们将在app.js中创建一个名为 `get_last_messages` 的函数getLastMsgs,并传入一个参数。

传统上,如果你的机器人监听的每个命令都有数量不明确的操作,为了便于阅读,通常建议将这些任务拆分成函数。

另外,你可以把这些函数放在同一个文件夹下的一个单独文件中,你可以把这个文件夹命名为“操作”之类的名称。

我不是说你现在就应该这么做,我只是说如果机器人有很多任务要做,这样做会更好。但这个机器人任务并不多。

这里有一个例子。虽然这个机器人项目被取消了,但它应该能让你了解拥有大量任务的机器人是如何构建的。

接下来,将
这段代码复制粘贴到getLastMsgs函数中(如果没有异步函数,可以创建一个),就像这样。

const getLastMsgs = async (msg) => {
  // fetching the last 10 messages
  const res = await msg.channel.messages.fetch({ limit: 10 });

  return 'Last ten messages';
};
Enter fullscreen mode Exit fullscreen mode

从技术上讲,我们传递的是收到的onmessageCreate事件消息的msg参数。因此,在当前接收命令的频道(可能是私信或服务器)中,将会获取最近的十条消息。

fetch 方法由Discord API提供,阅读本文后您应该了解一下。

结果是一个包含十条消息的数组,它不像传统数组那样可以通过索引访问每个元素。例如,如果要获取数组中的第一条消息,则必须使用相应的方法.first()

因此,可以这样访问第一条消息的内容:

res.first().content; // don't add this to the function, just a showcase
Enter fullscreen mode Exit fullscreen mode

另一个好处是,我们可以遍历数组中的每个元素。因此,returngetLastMsgs函数中的语句之前,添加以下内容:

const lastTenMsgs = messages.map((message) => {
  return message.content;
});
Enter fullscreen mode Exit fullscreen mode

forEach我们可以使用`or`循环遍历map,我们还可以访问filter`method` 方法。

现在将return语句更改为 lastTenMsgs。换句话说,你的函数应该如下所示:

const getLastMsgs = async (msg) => {
  // fetching the last 10 messages
  const res = await msg.channel.messages.fetch({ limit: 10 });

  const lastTenMsgs = res.map((message) => {
    return message.content;
  });

  return lastTenMsgs;
};
Enter fullscreen mode Exit fullscreen mode

async保存之前,记得在事件函数中传递该参数messageCreate。例如:

client.on('messageCreate', async (msg) => {});
Enter fullscreen mode Exit fullscreen mode

现在保存应用,并测试新命令。“!last-messages”命令会抛出一个数组,我们很快会修复这个问题。但现在,让我们先给机器人加点料吧。

首先要说明的是,并非所有消息都会被回复,而是机器人会创建一条新消息。我们用“!tell-a-joke”命令来实现这一点。

不要使用 msg.reply,而是这样做

msg.channel.send('HTML bla bla bla');
Enter fullscreen mode Exit fullscreen mode

当你仔细研读文档时,你会了解更多相关内容,文档写得很好。

另外,我们说过机器人应该能够发送私信。那么,让我们用“!last-messages”命令来实现这个功能。

不要使用 msg.reply,而是这样做

msg.author.send(reply);
Enter fullscreen mode Exit fullscreen mode

这并不能完全解决问题。我们现在就来解决这个问题。

最后,你肯定已经注意到 Discord 中的一些机器人发送/回复消息时,会在旁边添加颜色、粗体字,并像博客文章一样添加页眉和页脚。

其实这并不难做到。但在那之前,我应该先告诉你,你也可以用传统的方式将单词或文本加粗。

它几乎就像 Markdown 一样,但并非所有已知的 Markdown 语法都能使用。让我们把“!tell-a-joke”文本加粗。

msg.channel.send("**HTML** bla bla bla.\nI really don't have a joke");
Enter fullscreen mode Exit fullscreen mode

如果你测试一下这个命令,你会发现 HTML 现在变成了粗体,并且“我真的没有笑话”显示在新的一行上。

那么,我们就继续往下看吧。

为了使我们的消息看起来像一篇带有漂亮颜色的博客文章,让我们使用“!last-messages”命令来实现这一点。

app.js中,首先MessageEmbed从 'discord.js' 导入。这样你就有了

const { Client, MessageEmbed } = require('discord.js');
Enter fullscreen mode Exit fullscreen mode

getLastMsgs函数中,添加以下内容

const embeds = [];

lastTenMsgs.forEach((msg, index) => {
  const embed = new MessageEmbed()
    .setColor('ORANGE') // can be hex like #3caf50
    .setTitle(`Message ${index + 1}`)
    .setDescription(`${msg}`)
    .setFooter('Buddy says Hi');

  embeds.push(embed);
});
return embeds;
Enter fullscreen mode Exit fullscreen mode

我们只是创建了一个新的消息嵌入,并对其应用了一些方法。对于每条消息(共十条消息),我们都会创建一个嵌入,并将其添加到嵌入数组中,稍后我们会返回该数组。

这些方法setColor、等等都描述得相当清楚。点击此处setTitle了解更多关于嵌入的信息

现在,我们对“!last-messages”命令的回复将更改为

msg.author.send({ embeds: reply });
Enter fullscreen mode Exit fullscreen mode

我们需要让 Discord 知道这是一个嵌入式应用,这样它才能正常工作。

如果只有一个嵌入内容,你也应该确保将其包装在一个数组中,例如:

msg.author.send({ embed: [onlyEmbed] });
Enter fullscreen mode Exit fullscreen mode

现在保存更改并测试您的命令。错误消失了。现在一切都运行正常了。让我们发布机器人,让它永久在线吧!

我会使用 Heroku 的免费套餐。但问题是,我们的Heroku dyno在 30 分钟不活动后就会进入休眠状态。

解决这个问题的方法是使用 Uptime Robot。Uptime Robot 可以保证你的应用始终在线。不过,这样做也会带来一些副作用,所以通常来说,Heroku 的最佳替代方案是 Replit。

但无论如何,你仍然需要 Uptime 机器人来维持服务器运行,而且你需要一个服务器(而不是 Discord 服务器)。

所以,无论你使用 Replit 还是 Heroku,都需要先搭建一个服务器,然后将你的机器人连接到该服务器。那么,让我们在本地机器上创建一个服务器吧。

由于这是 NodeJS 项目,我们使用 'express'。使用以下命令安装 express npm i express:.

在根目录下创建一个名为server.js 的文件。在package.json文件中,将 main 函数改为 "server.js",并将 scripts 指向 "server.js" 而不是 "app.js"。

在server.js 文件粘贴以下内容;

const express = require('express');
const app = express();
const PORT = process.env.PORT || 5000;

app.get('/', (req, res) => {
  res.send('Buddy bot is running');
});

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Enter fullscreen mode Exit fullscreen mode

这里没什么大事发生,我们只是用 Express 创建了一个服务器。

我们只创建了一条路由,并附带一条简单的回复消息。如果您之前从未使用过 Express 或 NodeJS 服务器,相信我,您在这里真的无需担心太多。

直接复制粘贴就可以了。

如果保存,重新运行程序npm run app,您将看到日志消息“服务器正在端口 5000 上运行”。

如果你打开网页浏览器,打开一个新标签页,然后输入“ http://localhost:5000 ”,你就会收到“Buddy bot 正在运行”的消息。

服务器现在运行正常,但机器人似乎无法与之配合工作。我们来解决这个问题。

app.js中,我们有 `<script>` 标签client.login,创建一个名为 `<script>` 的函数startBot并将其包装在 `<script>` 标签内client.login。这样你就有了 `<script>` 标签。

const startBot = () => {
  client.login(config.DISCORD_TOKEN);
};

// export startBot as default
module.exports = startBot;
Enter fullscreen mode Exit fullscreen mode

server.jsstartBot中,从 './app.js'导入。

现在,在第一个路由之前调用该函数,即

startBot();

// before app.get()
Enter fullscreen mode Exit fullscreen mode

虽然你可以在任何地方调用这个函数,只要它在 listen 方法之前即可。但我更喜欢在路由之前调用它。

推送之前,别忘了创建一个.gitignore文件来忽略 node*modules。还要注意推送到哪里。如果要推送到 GitHub,请将/config/default.js添加到 _gitignore* 中。

现在把它推送到 Heroku 或 Replit。我已经写过一篇关于使用 Uptime Robot 的文章,可以去看看。

结论

我相信这已经足够清晰明了,可以帮助你开始为数十个服务器或单个服务器创建机器人。如果你遇到任何问题,请在评论区留言。

该项目的源代码上传至 GitHub,请给它点个赞,如果您喜欢这个项目,也请关注我。

最后,在我离开之前,我想说我真的每天都会在推特(@elijahtrillionz)上发布一些关于网页开发技巧和资源的推文。欢迎关注我,开启通知,让我们保持联系。

感谢阅读。下次再见,我和我的机器人也会再见。

文章来源:https://dev.to/elijahtrillionz/build-a-modern-discord-bot-from-scratch-learn-the-basics-973