本页内容
Discord 斜杠命令
Discord 有一个新功能叫做 斜杠命令。它们允许你输入 /
后跟一个命令名称来执行某些操作。例如,你可以输入 /giphy cats
(一个内置命令)来获取一些猫咪 GIF。
Discord 斜杠命令通过在有人发出命令时向 URL 发送请求来工作。你不需要让你的应用程序一直运行才能让斜杠命令工作,这使得 Deno Deploy 成为构建此类命令的完美解决方案。
在这篇文章中,让我们看看如何使用 Deno Deploy 构建一个 hello world 斜杠命令。
步骤 1: 在 Discord 开发者门户上创建应用程序 跳转到标题
- 访问 https://discord.com/developers/applications (如果需要,请使用你的 Discord 账户登录)。
- 点击你头像左侧的 新建应用程序 按钮。
- 为你的应用程序命名,然后点击 创建。
- 进入 机器人 部分,点击 添加机器人,最后点击 是,执行! 确认。
就是这样。一个新应用程序已创建,它将承载我们的斜杠命令。请不要关闭此选项卡,因为在整个开发过程中,我们将需要此应用程序页面上的信息。
步骤 2: 在 Discord 应用中注册斜杠命令 跳转到标题
在编写代码之前,我们需要通过 curl 调用 Discord 端点,在我们的应用中注册一个斜杠命令。
使用 BOT_TOKEN
填充 机器人 部分提供的令牌,并使用页面 通用信息 部分提供的 ID 填充 CLIENT_ID
,然后在终端运行该命令。
BOT_TOKEN='replace_me_with_bot_token'
CLIENT_ID='replace_me_with_client_id'
curl -X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bot $BOT_TOKEN" \
-d '{"name":"hello","description":"Greet a person","options":[{"name":"name","description":"The name of the person","type":3,"required":true}]}' \
"https://discord.com/api/v8/applications/$CLIENT_ID/commands"
这将注册一个名为 hello
的斜杠命令,它接受一个名为 name
的字符串类型参数。
步骤 3: 在 Deno Deploy 上创建并部署 hello world 斜杠命令 跳转到标题
接下来,当 Discord 发出带有用户斜杠命令的 POST 请求时,我们需要创建一个服务器来响应。
-
导航到 https://dash.deno.com/new 并在 Playground 卡片下点击 Play。
-
在下一页的编辑器中,点击顶部菜单上的 设置 图标。在弹出的模态框中,选择 + 添加变量。
-
将
DISCORD_PUBLIC_KEY
作为 KEY 输入。VALUE 应为 Discord 应用程序页面 通用信息 部分中提供的公钥。 -
将以下代码复制并粘贴到编辑器中
// Sift is a small routing library that abstracts away details like starting a // listener on a port, and provides a simple function (serve) that has an API // to invoke a function for a specific path. import { json, serve, validateRequest, } from "https://deno.land/x/sift@0.6.0/mod.ts"; // TweetNaCl is a cryptography library that we use to verify requests // from Discord. import nacl from "https://esm.sh/tweetnacl@v1.0.3?dts"; // For all requests to "/" endpoint, we want to invoke home() handler. serve({ "/": home, }); // The main logic of the Discord Slash Command is defined in this function. async function home(request: Request) { // validateRequest() ensures that a request is of POST method and // has the following headers. const { error } = await validateRequest(request, { POST: { headers: ["X-Signature-Ed25519", "X-Signature-Timestamp"], }, }); if (error) { return json({ error: error.message }, { status: error.status }); } // verifySignature() verifies if the request is coming from Discord. // When the request's signature is not valid, we return a 401 and this is // important as Discord sends invalid requests to test our verification. const { valid, body } = await verifySignature(request); if (!valid) { return json( { error: "Invalid request" }, { status: 401, }, ); } const { type = 0, data = { options: [] } } = JSON.parse(body); // Discord performs Ping interactions to test our application. // Type 1 in a request implies a Ping interaction. if (type === 1) { return json({ type: 1, // Type 1 in a response is a Pong interaction response type. }); } // Type 2 in a request is an ApplicationCommand interaction. // It implies that a user has issued a command. if (type === 2) { const { value } = data.options.find((option) => option.name === "name"); return json({ // Type 4 responds with the below message retaining the user's // input at the top. type: 4, data: { content: `Hello, ${value}!`, }, }); } // We will return a bad request error as a valid Discord request // shouldn't reach here. return json({ error: "bad request" }, { status: 400 }); } /** Verify whether the request is coming from Discord. */ async function verifySignature( request: Request, ): Promise<{ valid: boolean; body: string }> { const PUBLIC_KEY = Deno.env.get("DISCORD_PUBLIC_KEY")!; // Discord sends these headers with every request. const signature = request.headers.get("X-Signature-Ed25519")!; const timestamp = request.headers.get("X-Signature-Timestamp")!; const body = await request.text(); const valid = nacl.sign.detached.verify( new TextEncoder().encode(timestamp + body), hexToUint8Array(signature), hexToUint8Array(PUBLIC_KEY), ); return { valid, body }; } /** Converts a hexadecimal string to Uint8Array. */ function hexToUint8Array(hex: string) { return new Uint8Array( hex.match(/.{1,2}/g)!.map((val) => parseInt(val, 16)), ); }
-
点击 保存并部署 以部署服务器
-
文件部署后,请注意项目 URL。它将在编辑器的右上角,并以
.deno.dev
结尾。
步骤 3: 配置 Discord 应用程序,使用我们的 URL 作为交互端点 URL 跳转到标题
- 返回 Discord 开发者门户上你的应用程序(Greeter)页面
- 使用上面提到的 Deno Deploy 项目 URL 填充 交互端点 URL 字段,然后点击 保存更改。
应用程序现已准备就绪。让我们继续下一节来安装它。
步骤 4: 在你的 Discord 服务器上安装斜杠命令 跳转到标题
因此,要使用 hello
斜杠命令,我们需要在我们的 Discord 服务器上安装 Greeter 应用程序。以下是步骤:
- 访问 Discord 开发者门户上 Discord 应用程序页面的 OAuth2 部分
- 选择
applications.commands
范围,然后点击下方的 复制 按钮。 - 现在在浏览器中粘贴并访问该 URL。选择你的服务器,然后点击 授权。
打开 Discord,输入 /hello Deno Deploy
,然后按 回车键。输出将类似于下图。
恭喜你完成本教程!快去构建一些超棒的 Discord 斜杠命令吧!并务必在 Deno Discord 服务器的 deploy 频道与我们分享。