使用TypeScript+AWS CDK构建无服务器Discord机器人如何添加斜杠命令
TypeScript + AWS 无服务器Discord机器人斜杠命令实现方案
1 安装必要依赖
在你的TypeScript项目中安装交互验证、AWS Lambda类型支持包:
npm install discord-interactions @discordjs/rest discord-api-types @types/aws-lambda typescript ts-node
你可以自行调整tsconfig.json配置,target设置为ES2020、module设置为CommonJS即可适配Lambda Node.js运行环境。
2 定义斜杠命令结构
先在本地完成命令规则的定义,示例如下:
// src/commands/hello.ts export const HELLO_COMMAND = { name: 'hello', description: '测试斜杠命令,返回问候语', type: 1, // 1代表CHAT_INPUT类型,即普通斜杠命令 options: [ { name: 'name', type: 3, // 3代表STRING类型参数 description: '要问候的用户名', required: false } ] }
3 注册斜杠命令到Discord
写一个本地执行的命令注册脚本,开发阶段建议注册服务器级命令(即时生效),生产环境再注册全局命令(生效需1小时左右):
// scripts/register-commands.ts import { REST } from '@discordjs/rest' import { Routes } from 'discord-api-types/v10' import { HELLO_COMMAND } from '../src/commands/hello' // 以下参数从Discord开发者后台获取 const DISCORD_APPLICATION_ID = '你的Discord应用ID' const DISCORD_BOT_TOKEN = '你的机器人令牌' const DISCORD_TEST_GUILD_ID = '你的测试服务器ID' const rest = new REST({ version: '10' }).setToken(DISCORD_BOT_TOKEN) async function registerCommands() { try { console.log('开始注册斜杠命令...') // 服务器级命令注册(开发用) await rest.put( Routes.applicationGuildCommands(DISCORD_APPLICATION_ID, DISCORD_TEST_GUILD_ID), { body: [HELLO_COMMAND] } ) // 全局命令注册(生产用,注释打开即可) // await rest.put(Routes.applicationCommands(DISCORD_APPLICATION_ID), { body: [HELLO_COMMAND] }) console.log('斜杠命令注册成功') } catch (error) { console.error('命令注册失败:', error) } } registerCommands()
在package.json中添加执行脚本:"register:commands": "ts-node scripts/register-commands.ts",本地运行npm run register:commands即可完成命令注册。
4 Lambda中处理斜杠命令交互
首先需要验证Discord请求的签名合法性,再根据交互类型做对应处理:
// src/lambda/interactionHandler.ts import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda' import { verifyKey, InteractionType, InteractionResponseType } from 'discord-interactions' import { HELLO_COMMAND } from '../commands/hello' // 从Discord开发者后台获取公钥,建议存在Lambda环境变量中 const DISCORD_PUBLIC_KEY = process.env.DISCORD_PUBLIC_KEY as string export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => { // 验证请求来源合法性 const signature = event.headers['x-signature-ed25519'] const timestamp = event.headers['x-signature-timestamp'] const body = event.body || '' if (!signature || !timestamp) { return { statusCode: 401, body: '无效请求' } } const isValidRequest = verifyKey( Buffer.from(body), signature, timestamp, DISCORD_PUBLIC_KEY ) if (!isValidRequest) { return { statusCode: 401, body: '请求验证失败' } } const interaction = JSON.parse(body) // 处理Discord端点验证的PING请求 if (interaction.type === InteractionType.PING) { return { statusCode: 200, body: JSON.stringify({ type: InteractionResponseType.PONG }) } } // 处理斜杠命令请求 if (interaction.type === InteractionType.APPLICATION_COMMAND) { const { name } = interaction.data if (name === HELLO_COMMAND.name) { const nameParam = interaction.data.options?.find(opt => opt.name === 'name')?.value || '陌生人' return { statusCode: 200, body: JSON.stringify({ type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE, data: { content: `你好呀,${nameParam}!` } }) } } } return { statusCode: 400, body: JSON.stringify({ error: '未知命令' }) } }
5 打包部署
把TypeScript编译为JS后,连同node_modules一起打包上传到Lambda,运行时选择Node.js 18.x及以上版本,Lambda的handler配置对应编译后的文件路径即可。
注意事项
- 开发阶段优先使用服务器级命令测试,确认无问题再发布全局命令
- Discord请求超时时间为3秒,耗时较长的任务需要先返回延迟响应,后续再编辑消息返回结果,避免触发超时
- 所有敏感凭证不要硬编码,建议存储在AWS Secrets Manager或者Lambda环境变量中
内容的提问来源于stack exchange,提问作者Kinhira
相关产品推荐
相关产品推荐

