利用 discord.js 建立一个 Discord 机器人。
我也是第一次上手,利用博客来记录我的学习过程,定期整理后再发到公众号。
在简单对比了 discord.js (JavaScript),discordgo (Go),discord.py (Python),Discord4J (Java) 和 D++ (C++) 等项目后,我选择了 discord.js。不为别的,就为 JS 本身。
为什么选择了discord.js 呢?因为它:
而且根据 Atwood 定律:任何可以使用 JavaScript 来编写的应用,并最终也会由 JavaScript 编写。所以,没得办法。
免责声明:先说好,不要将本教程的代码用于生产环境,因为它们通常有着已知或未知的漏洞。任何代码在上线之前,都应该经过充分的代码审查。本教程只是为了说明基本原理并自娱自乐。
下面,咱们开始吧。
你需要自行下载安装 node.js,npm,yarn,pnpm。
操作系统可以选择 Linux 发行版、FreeBSD 和 Mac OS,Windows 不是必须的,但操作系统你得有。
IDE 也不是必须的,用 VS Code, Sublime Text, Vim, nano 或者记事本都可以。
Node.js 是必须安装的。
云端环境是用来在我的笔记本关机时,保持机器人继续运行的环境。
但是我们这里也就写个机器人,图一乐,所以,凑合凑合就行了,当然没有也无所谓。
打开链接 https://discord.com/developers/applications ,登录你的 Discord 账号,选择 New Application
来创建新应用程序。
在 NAME
一栏填写你的应用名称,这个名称将会是机器人的外显账号名称,后期可修改。
按下 Create
以完成创建。
点开新创建的应用,点击左侧菜单栏的 General Infromation
,记下 APPLICATION ID
,这就是通常所说的机器人的 "client_id",这个 ID 是公开可查的,不是秘密。
点击左侧菜单栏的 Bot
,点击 Add Bot
,再点击弹出对话框的 Yes, do it!
创建机器人。注意此操作是不可逆的,也就是说机器人一旦创建,就不可被销毁删除。哪怕销毁应用程序,机器人账号仍会在 Discord 的世界里存在,只是变成无人能管理的孤儿账号了。
关于机器人账号和普通用户账号的区别,这里有介绍。
完成机器人账号创建后,在本页面的 Build-A-Bot
栏目中,你可以给机器人账号更换用户名和头像。
点击按钮 Reset Token
并点击 Yes, do it!
来首次获取我们的机器人账号 Token。
注意:Token (令牌)万万不可给别人看到,这是十分机密的一串文字,任何人有了它,就拥有了完全掌控机器人行为的能力了,比如机器人封禁和私聊服务器里的人、发送 @everyone 等恶劣行为都可能会发生。请妥善保管好这个密钥,
注意:Discord 出于安全目的,令牌在创建时只能查看一次。 如果您忘记或无法访问您的令牌,请重新生成一个新令牌,旧令牌将自动失效。
接着为了求福,取消勾选 Requires OAuth2 Code Grant
。
点击左侧菜单栏的 OAuth2
- URL Generator
,在 SCOPES
里勾选 bot
和 applications.commands
,为了方便,在 BOT PERMISSIONS
里直接勾选第一条 Administrator
(注意咱们只是为了玩哈,才直接赋予管理员权限的)。
复制最下方生成的 URL,粘贴到新浏览器窗口打开,选择服务器并添加。如果你没有看到任何可选选项,那么你需要去 Discord 先自己创建一个服务器,然后回来刷新一下。事实上,其他服务器如果给你管理服务器的权限的话,这个服务器将出现在可选选项中。
到此,我们完成了搭建开发环境、创建机器人账号和邀请机器人进入服务器。
对于 IDE 用户,创建一个 Node.js 项目。对于编辑器用户,新建文件夹即可。
比如我的工作目录是 C:\Users\root\WebstormProjects\discord_bot_2022
本文编写时,discord.js 的最新版本是 v13。因此,后文的所有代码可能在未来的版本(比如 v14)中失效。
不过幸运的是,v14 的推出还远着呢。
注意:你的 Node.js 的版本需高于 16.6.0(含)
cd 到 工作目录
,在终端输入来获取 discord.js:
npm install discord.js @discordjs/rest discord-api-types yarn add discord.js @discordjs/rest discord-api-types pnpm add discord.js @discordjs/rest discord-api-types
为了方便地获取服务器和用户 id,我们必须这么做。
打开你的 Discord,无论是手机 APP 还是 PC 还是网页版。在 设置
- 高级设置
里,勾选 开发者模式
。
在工作目录下创建文件 config.json
,写入:
{ "token": "bot-token-goes-here", "clientId": "bot-clientid-goes here", "guildId": "serverid-goes-here" }
比如
{ "token": "OTEzNDMyTEN0OTkzOTk1ODA4.Bhz0k7.97sjsWOGtmx-LBIlFvrkk6A9lkk9YGMX9OYbf", "clientId": "913432114993090099", "guildId": "978274108671780933" }
需要说明的是,token
字段就是那个极为重要不能外泄的机器人密钥,把你的粘贴过来。
clientId
字段就是 Application id
。在 Discord 服务器里。右击机器人头像,点击 复制 ID
即可轻松获取。
guildId
字段是服务器的 ID,当然得是机器人所在的服务器的 ID。右击服务器头像,点击 复制 ID
即可轻松获取。
接下来确保你的工作目录下存在 .gitignore
文件,确保文件内已写入
node_modules config.json
否则你的 token 将会在 git 推送后外泄。
在 工作目录
创建文件 deploy_commands.js
,写入:
const fs = require("fs"); const { REST } = require('@discordjs/rest'); const { Routes } = require('discord-api-types/v9'); const { clientId, guildId, token } = require('./config.json'); const commands = []; const commandFiles = fs.readdirSync("./commands").filter(file => file.endsWith(".js")); for (const file of commandFiles) { const command = require(`./commands/${file}`); commands.push(command.data.toJSON()); } const rest = new REST({ version: '9' }).setToken(token); rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands }) .then(() => console.log('Successfully registered application commands.')) .catch(console.error);
在 工作目录
下创建文件夹 events
,在这个文件夹里创建文件 ready.js
,写入:
module.exports = { name: "ready", once: true, execute(client) { console.log(`Ready! Logged in as ${client.user.tag}`); }, };
在 工作目录/event
文件夹里,创建文件 interactionCreate.js
,写入:
module.exports = { name: "interactionCreate", execute(interaction) { console.log(`${interaction.user.tag} in #${interaction.channel.name} triggered an interaction.`); }, };
在 工作目录
创建文件 index.js
,写入:
const fs = require('fs'); const { Client, Collection, Intents } = require('discord.js'); const { token } = require('./config.json'); const client = new Client({ intents: [Intents.FLAGS.GUILDS] }); const eventFiles = fs.readdirSync('./events').filter(file => file.endsWith('.js')); for (const file of eventFiles) { const event = require(`./events/${file}`); if (event.once) { client.once(event.name, (...args) => event.execute(...args)); } else { client.on(event.name, (...args) => event.execute(...args)); } } client.commands = new Collection(); const commandFiles = fs.readdirSync("./commands").filter(file => file.endsWith(".js")); for (const file of commandFiles) { const command = require(`./commands/${file}`); client.commands.set(command.data.name, command); } client.once('ready', () => {}); client.on('interactionCreate', async interaction => { if (!interaction.isCommand()) return; const command = client.commands.get(interaction.commandName); if (!command) return; try { await command.execute(interaction); } catch (error) { console.error(error); await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true }); } }); client.on('interactionCreate', interaction => {}); client.login(token);
在 工作目录
下创建文件夹 commands
,在这个文件夹里创建文件 ping.js
,写入:
const { SlashCommandBuilder } = require('@discordjs/builders'); module.exports = { data: new SlashCommandBuilder() .setName('ping') .setDescription('Replies with Pong!'), async execute(interaction) { await interaction.reply("Pong!"); }, };
这些代码,不懂正常。先照做,以后会介绍到的,何况我们的工作重点不是这些“框架”性的东西,而是真正的机器人交互逻辑代码。
对于 IDE 用户,创建运行配置后,点击“运行”或者什么之类的按钮即可让机器人跑起来。
对于非 IDE 用户(IDE 用户也可以),打开终端,cd 到工作目录,输入 node deploy_commands.js
注册斜杠命令。成功消息是 Successfully registered application commands.
。
成功后,cd 到工作目录,终端输入 node index.js
运行机器人。成功消息类似于 Ready! Logged in as abcd#0001
。
如果出现 “ 无法将“node”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。” 或者 “ 'node' 不是内部或外部命令,也不是可运行的程序
或批处理文件。”亦或者“ -bash: node: command not found ”,请检查你的 PATH 是否有包含 node.exe 所在文件夹,这通常是 C:\Program Files\nodejs\node.exe
。
如果失败,请检查你的网络是否能连接到 DIscord、你的上述步骤有没有漏做或者顺序错误的。
cd 到工作目录。
确保你已经通过 node deploy_commands.js
注册了斜杠命令,并已通过 node index.js
使机器人程序保持运行状态。验证方法是:能看到你的机器人是在线状态而非离线状态。
打开 Discord,在机器人所在的服务器的任何文字频道,输入 /ping
,回车选定斜杠命令,再次回车发送命令,机器人应该会发送消息 Pong!
,而且在机器人后端程序,会输出类似于 xxxx#0001 in #bot triggered an interaction.
这样,一个非常简单的机器人就完成了。
后续我们将学习更多的东西,先写到这吧。记得关注从而收取最新消息。
原文链接:https://www.cnblogs.com/hhzm/p/16461628.html