在一个小时内建立你的第一个Discord机器人
了解如何用NodeJS创建交互式Discord机器人
在不到60分钟的时间里用NodeJS构建你的第一个Discord机器人
Discord是一个超过1亿用户依赖的聊天应用程序,通过文本、语音和视频对话建立在线社区。利用Discord为开发者提供的大量API,我们可以建立机器人,在Discord上执行重复的、平凡的、甚至是有趣的任务。管理社区、向社区发送信息、给用户发私信,只是我们可以使用 Discord 机器人自动完成的几项工作。
在今天的教程中,我们将建立一个简单(和有趣)的机器人,在用户要求下向社区发送随机的爸爸笑话。使用Node.js和discord.js模块,我们可以在60分钟内创建、开发和部署这个Discord机器人,而且没有任何麻烦。现在开始倒计时了。
在我们开始之前...
在这里,我们列出了在开始学习教程之前需要设置的所有东西:
- 在你的机器上安装Node.js。
- 在 Discord 上创建一个账户。你可以下载桌面应用程序或使用浏览器访问它。
- 创建一个新的社区(或者用Discord语言创建一个新的 "服务器")来测试该应用程序。
一旦所有这些都设置好了,你就可以继续学习教程了。
最后一件事,你可以在GitHub上找到项目的代码
创建一个新的Discord机器人
在这第一步,你应该在Discord上创建和配置一个新的机器人。以下是你的操作方法
登录你的Discord账户,进入其开发者门户网站的应用页面。
Discord 开发者门户网站
点击 "新应用程序"。它会生成一个弹出窗口,提供新机器人的名字。
Discord新申请表格
添加完名字后,点击创建按钮,你会被导航到一个包含申请信息的新页面。进入 "机器人 "标签,点击 "添加机器人 "按钮,将机器人添加到申请中。同样,在弹出的对话框中确认该操作。
Discord机器人应用程序
这就把新的机器人添加到了 Discord。现在,我们可以开始配置它了。
Discord注册机器人
第一步,复制机器人令牌,并将其存放在某个私人地方。记住:这个令牌只能给你看,千万不要与其他人分享。
保持 "授权流程 "部分的默认选择。
Discord授权流程
接下来,你应该在 "特权网关意图 "下打开 "服务器成员意图 "选项。我们的机器人需要这个意图的权限来检测新成员加入服务器的时间。
Discord设置的机器人意图
将机器人添加到Discord服务器上
我们应该生成一个邀请链接,反映机器人应该拥有的权限级别,以便将其添加到Discord服务器。要做到这一点,在同一页上的 "OAuth2 "标签,选择 "机器人 "作为应用程序的范围。然后,选择机器人在与服务器互动时应该有的一组权限。我们的机器人只需要在服务器频道中读取和发送消息的权限。
Discord设置机器人的权限
选择所有必要的权限后,复制范围部分下生成的URL,并在新的浏览器标签中打开它。然后,选择机器人应该加入的服务器,并在出现提示时授权该行动。
将机器人连接到 Discord 服务器
现在,如果你进入Discord服务器,你就能看到新的机器人在右侧面板上被列为成员。
实现机器人的行为
我们现在可以开始添加代码来定义机器人在服务器中的行为。正如我们在文章开头提到的,我们将使用Node.js和discord.js来完成这个任务。
作为实施的第一步,建立一个新的Node.js项目,用npm初始化它。然后,我们应该用npm安装discord.js、axios和dotenv模块。
npm install discord.js axios dotenv
接下来,我们创建一个.env文件,并添加我们之前复制的令牌作为环境变量。
//.env
TOKEN=<your token>
登录并开始监听事件
现在我们可以导入discord.js,设置机器人来监听服务器事件并作出相应的反应。创建一个名为index.js的新文件,并在其中添加以下代码:
//index.js
require("dotenv").config();
const Discord = require("discord.js");
const client = new Discord.Client();
//Listen to the event that signals the bot is ready to start working
client.on("ready", () => {
console.log(`logged in as ${client.user.tag}`);
});
//Listen to new messages on the server
client.on("message", async (message) => {
if (message.content === "ping") {
message.reply("pong");
}
});
//Login to the server using bot token
client.login(process.env.TOKEN);
这段代码中发生了几件重要的事情。首先,我们导入discord.js模块,并创建一个新的客户端对象,在这个方案中代表Discord机器人。然后,client.login
方法允许机器人使用我们添加到.env文件中的令牌登录到 Discord。dotenv模块负责把它作为一个环境变量添加到进程中。
我们的机器人监听两个Discord事件:ready和message。当机器人准备好被使用时,就会触发ready事件。而消息事件是在每次用户向频道发送消息时触发的。在这里,我们将机器人设置为用 "pong "来回复每条发送 "ping "的消息。
当我们使用node index
命令运行这个Node脚本时,到目前为止一直处于离线状态的Bot就会上线并开始工作。
看到你的机器人在线
你可以向一个频道发送ping信息,测试它是否正常工作。
测试你的基本机器人
应用户要求用随机的爸爸笑话回复用户
最后,我们来到了这个项目的有趣部分。在这一步中,我们将设置我们的机器人回复任何直接提到它的用户,并给他一个随机的爸爸笑话。为此,我们将使用这个很棒的API:icanhazdadjoke.com。它有一个伟大的有趣(和尴尬)的爸爸笑话集合,我们可以免费检索。
这个实现的基本逻辑是这样的。当用户提到我们的机器人时,它使用axios向爸爸笑话API发送一个请求,并检索一个随机的爸爸笑话。然后,它将笑话回复给用户。相当简单。
这里需要注意的是,我们需要将GET请求的接受头设置为application/json,以便以JSON格式从API检索结果。
require("dotenv").config();
const axios = require("axios");
const Discord = require("discord.js");
const client = new Discord.Client();
const dadJokeURL = "https://icanhazdadjoke.com";
const headers = { "Accept": "application/json" };
async function getRandomDadJoke() {
const response = await axios.get(dadJokeURL, { headers: headers });
return response.data;
}
//Listen to the event that signals bot is ready to start working
client.on("ready", () => {
console.log(`logged in as ${client.user.tag}`);
});
//Listen to new messages on the server
client.on("message", async (message) => {
//"Ignore the message if the bot authored it"
if (message.author.bot) return;
//If the doesn't specifically mention the bot, return
if (text.includes("@here") || text.includes("@everyone")) return;
//Return if the message doesn't mention the bot
if (!message.mentions.has(client.user.id)) return;
try {
//Reply with a random joke
const result = await getRandomDadJoke();
message.reply(result.joke);
}
catch (error) {
message.reply("Sorry, an error occured");
}
});
//Login to the server using bot token
client.login(process.env.TOKEN);
getRandomDadJoke
方法发送axios请求,并返回带有随机笑话的检索数据。在消息处理程序中,机器人监听消息事件并决定它应该回复哪些消息。它消除了三种类型的消息:
- 由机器人自己编写的消息。
- 提及服务器上的每个人,而不仅仅是机器人的消息。
- 没有提到机器人的信息。
如果一个用户直接提到机器人,它就会用一个使用getRandomDadJoke
方法检索的随机笑话进行回复。
你可以停止和启动Node脚本,让修改后的机器人在服务器上运行。
现在机器人可以从API中回复信息了
用用户提供的搜索词来搜索爸爸的笑话
这个实现与上一个没有太大区别。但在这里,用户可以提交一个搜索词,以获得一个特定主题的爸爸笑话。
为了实现这一点,我们添加了一个名为searchDadJokes
的新函数,该函数将请求发送到/search
API端点,并将搜索词作为一个查询参数。我们还设置了limit=1
,以便在一个给定的主题上只检索一个笑话。
async function searchDadJokes(term) {
const params = { term: term, limit: 1 }
const response = await axios.get(`${dadJokeURL}/search`, { params: params, headers: headers });
return response.data.results[0];
}
然后,我们必须修改消息事件处理程序,以考虑用户提交搜索词的情况。下面是我们如何做的。
//Listen to new messages on the server
client.on("message", async (message) => {
//"Ignore the message if the bot authored it"
if (message.author.bot) return;
const text = message.content.toLowerCase();
//If the doesn't specifically mention, bot return
if (text.includes("@here") || text.includes("@everyone")) return;
//Return if the message doesn't mention the bot
if (!message.mentions.has(client.user.id)) return;
let result;
try {
const term = text.replace(/<@!\d+>/, "").trim();
//If there is a search term
if (term !== "") {
//Search a joke containing the term
result = await searchDadJokes(term);
if (!result) {
message.reply(`Sorry, got no dad jokes about ${term}. But how about a random dad joke?`);
}
}
//Reply with a random joke
if (!result) {
result = await getRandomDadJoke();
}
message.reply(result.joke);
}
catch (error) {
message.reply("Sorry, an error occured")
}
});
在这段代码中,为了检查用户是否提交了一个搜索词,我们需要从文本中删除机器人的ID。当用户提到机器人的时候,它就会被添加到文本中。一个被提及的ID在文本中以如下格式出现。
<@!1223344342859688930>
我们使用regex模式<@!\d+>
,检测文本中的ID,并将其替换为一个空字符串。在修剪了修改后的文本后,机器人可以检索到用户提交的搜索词。然后,机器人使用searchDadJokes
方法找到一个相关的笑话。
但是,如果API数据库中没有关于某个特定主题的笑话,机器人就会回复用户,解释这种情况以及一个随机笑话。如果用户没有提交搜索词,它就会默认回复一个随机笑话。
代码的其余部分保持与上一个场景相似。所以,我们现在可以运行和测试我们机器人的这个新功能。
欢迎新成员
我们可以设置我们的机器人来欢迎每个加入Discord服务器的新用户。当机器人检测到一个新的 "guildMemberAdd "事件,也就是一个新用户加入的信号,它会向 "General "频道发送一条消息,欢迎新用户。
//Listen to new member joining event
client.on("guildMemberAdd", member => {
//Find the general channel in the user's channel list to send the welcome message
const channel = member.guild.channels.cache.find(ch => ch.name === "general");
//If the channel is not in the server, exit
if (!channel) return;
channel.send(`Welcome, ${member}! I'm at your service if you want to hear dad jokes`);
});
至此,我们已经完成了我们的Discord机器人的开发。你现在可以把机器人添加到任何你有 "管理服务器 "权限的服务器上,并享受阅读随机爸爸笑话的乐趣。