From 9da5075b3047bca255b32db1ac1b7356d1616b2f Mon Sep 17 00:00:00 2001 From: "Kalle (Sendou)" <38327916+Sendouc@users.noreply.github.com> Date: Tue, 22 Dec 2020 18:41:40 +0200 Subject: [PATCH] discord bot ping pong test --- discord/index.ts | 52 ++++++++++++++++++++++++++++++++++++++++ package-lock.json | 8 +++++++ package.json | 1 + pages/api/discord.ts | 56 +++++++++++--------------------------------- 4 files changed, 75 insertions(+), 42 deletions(-) create mode 100644 discord/index.ts diff --git a/discord/index.ts b/discord/index.ts new file mode 100644 index 000000000..c21bf8848 --- /dev/null +++ b/discord/index.ts @@ -0,0 +1,52 @@ +import { + InteractionResponseFlags, + InteractionResponseType, +} from "discord-interactions"; + +type InvocationCommon = { + member: { + user: { + id: number; + username: string; + avatar: string; + discriminator: string; + public_flags: number; + }; + roles: string[]; + }; +}; + +interface Interaction extends InvocationCommon { + data: { name: "ping" }; +} + +type ReturnData = { + type: InteractionResponseType; + data: { + content: string; + }; + flags?: InteractionResponseFlags; +}; + +const handleCommand = (interaction: Interaction): ReturnData => { + switch (interaction.data.name) { + case "ping": + return { + type: InteractionResponseType.CHANNEL_MESSAGE, + data: { + content: "pong", + }, + }; + default: + console.error("not existing command invoced"); + return { + type: InteractionResponseType.CHANNEL_MESSAGE, + data: { + content: "Sorry but I don't understand this command 😞", + }, + flags: InteractionResponseFlags.EPHEMERAL, + }; + } +}; + +export default handleCommand; diff --git a/package-lock.json b/package-lock.json index 2a76e5fd1..3ee70c90f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4429,6 +4429,14 @@ } } }, + "discord-interactions": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/discord-interactions/-/discord-interactions-1.4.1.tgz", + "integrity": "sha512-JLB+uAWEluymJWlJkQ9GJui2cYdTMM3pGOEN5j3p2S/+7xdRjjGtqGgRGAqA5tyPVUHHchtsV/EAooVgM0cVBg==", + "requires": { + "tweetnacl": "^1.0.3" + } + }, "dom-helpers": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", diff --git a/package.json b/package.json index 6b7e0b6e1..c241a2265 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@prisma/client": "^2.13.1", "@sendou/react-sketch": "^0.5.2", "countries-list": "^2.5.6", + "discord-interactions": "^1.4.1", "framer-motion": "^3.1.1", "next": "^10.0.3", "next-auth": "^3.1.0", diff --git a/pages/api/discord.ts b/pages/api/discord.ts index c8cee476a..02aeb928c 100644 --- a/pages/api/discord.ts +++ b/pages/api/discord.ts @@ -1,43 +1,9 @@ +import handleCommand from "discord"; +import { InteractionType } from "discord-interactions"; import { NextApiRequest, NextApiResponse } from "next"; import getRawBody from "raw-body"; import nacl from "tweetnacl"; -/* -{ - "type": 2, - "token": "A_UNIQUE_TOKEN", - "member": { - "user": { - "id": 53908232506183680, - "username": "Mason", - "avatar": "a_d5efa99b3eeaa7dd43acca82f5692432", - "discriminator": "1337", - "public_flags": 131141 - }, - "roles": ["539082325061836999"], - "premium_since": null, - "permissions": "2147483647", - "pending": false, - "nick": null, - "mute": false, - "joined_at": "2017-03-13T19:19:14.040000+00:00", - "is_pending": false, - "deaf": false - }, - "id": "786008729715212338", - "guild_id": "290926798626357999", - "data": { - "options": [{ - "name": "cardname", - "value": "The Gitrog Monster" - }], - "name": "cardsearch", - "id": "771825006014889984" - }, - "channel_id": "645027906669510667" -} - */ - const discordCommandHandler = async ( req: NextApiRequest, res: NextApiResponse @@ -47,13 +13,13 @@ const discordCommandHandler = async ( const signature = req.headers["x-signature-ed25519"] as string; const timestamp = req.headers["x-signature-timestamp"] as string; - const body = (await getRawBody(req)).toString(); // rawBody is expected to be a string, not raw bytes + const rawBody = (await getRawBody(req)).toString(); // rawBody is expected to be a string, not raw bytes let isVerified; try { isVerified = nacl.sign.detached.verify( - Buffer.from(timestamp + body), + Buffer.from(timestamp + rawBody), Buffer.from(signature, "hex"), Buffer.from(PUBLIC_KEY, "hex") ); @@ -65,10 +31,16 @@ const discordCommandHandler = async ( return res.status(401).end("invalid request signature"); } - // if req.json type === 1 - res.status(200).json({ - type: 1, - }); + const interaction = JSON.parse(rawBody); + + if (interaction && interaction.type === InteractionType.COMMAND) { + const result = handleCommand(interaction); + res.status(200).json(result); + } else { + res.status(200).json({ + type: 1, + }); + } }; export default discordCommandHandler;