Skip to content

Commit e1d6387

Browse files
Merge pull request #57 from Real-Dev-Squad/develop
Sync dev to main
2 parents 9256f2a + 5c982e5 commit e1d6387

File tree

7 files changed

+131
-37
lines changed

7 files changed

+131
-37
lines changed

CONTRIBUTING.md

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,37 @@
55

66
## Getting Started
77

8-
To work on this project please create an account on Cloudflare and Discord.
9-
Also, create a personal discord server.
10-
Copy the guild id of your server and save it in a .env file as `DISCORD_GUILD_ID`
11-
12-
To get the server ID for the first parameter, open Discord, go to Settings > Advanced and enable developer mode.
13-
Then, right-click on the server title and select "Copy ID" to get the guild ID.
14-
8+
To contribute to this project, you have to set up few things first.
9+
10+
- Create an account on Cloudfare Workers and Discord if you don't already have one
11+
- Create a personal discord server
12+
- Fork and clone this repo (this is optional; if you are a member of RDS community, you don't have to fork)
13+
- Install volta - this will check if you have the right node version or not
14+
- Create a .env file in the root directory of the project
15+
16+
Next, you need to gather few details that will be crucial for setting up your local environment. The IDs that you will gather in the next steps, will be stored as secret keys on the Cloudfare workers platform, where the application will be hosted.
17+
18+
- To get the guild ID of your server :
19+
- Open your discord server
20+
- Click on the server name in the top-left corner
21+
- Click on Server Settings
22+
- Click on the Widget tab in the side panel
23+
- Copy/paste the Server ID in the .env file as `DISCORD_GUILD_ID`
1524
- Visit [Discord Developer Portal](https://discord.com/developers/applications)
1625
- Click on new application.
26+
- Under the General Information panel
27+
- copy/paste the Application ID in the .env file as `DISCORD_APPLICATION_ID`
28+
- copy/paste the Public Key in the .env file as `DISCORD_PUBLIC_KEY`
1729

18-
Gather the following details from the Developer portal and save it in a .env file.
30+
Next, you need to create your own bot. The idea here is that you will have your own bot that can be used to run all commands in your private server. You can add new features and test it there to make sure everything works as expected, before deploying the code on production.
1931

20-
```
21-
DISCORD_TOKEN: Available in bot panel of your discord bot after clicking reset token button.
22-
DISCORD_APPLICATION_ID: Available in general panel of your discord bot.
23-
DISCORD_PUBLIC_KEY: Available in general panel of your discord bot.
24-
```
32+
- To create a bot, go to the Bot panel and click on 'Add Bot'
33+
- Next, copy the token from the dashboard there and save it in the .env file as `DISCORD_TOKEN `.
34+
- Next, you have to generate a set of RSA keys 2048 bit in size. We will use them as `BOT_PRIVATE_KEY` and `BOT_PUBLIC_KEY`.
2535

26-
Please set Following permissions for your bot:
36+
- You can read more about RSA keys [here](https://www.namecheap.com/support/knowledgebase/article.aspx/798/69/what-is-an-rsa-key-used-for/)
37+
- All you need to know for now is that the private and public keys are used when authenticating using JWT.
38+
- You can generate your own keys for local development [here](https://cryptotools.net/rsagen)
2739

2840
- Navigate to OAuth2 > URL Generator
2941
- In scopes select `bot` and `applications.commands`
@@ -39,35 +51,59 @@ Please set Following permissions for your bot:
3951
- Mention Everyone
4052
- Use slash commands
4153

42-
After providing all the permissions you will get an url at the bottom of the page use that to invite the bot to your server.
54+
After providing all the permissions, a URL will be generated below.
4355

44-
Open the Url you get and invite the bot to your test server.
56+
- Copy/paste this URL in a new browser window
57+
- Select your private server from the dropdown and authorize
58+
- This will invite the bot to your private discord server
4559

4660
## Setting Up Local Development
4761

48-
- Clone the Repository to your machine
49-
- Now, get the .env file created above in the project folder
5062
- run `npm install`
51-
- Now, run the command `npm run register`
63+
- Now, run the command `npm run register` - this will register all the commands to your discord bot.
5264

53-
This will register all the commands to your discord bot.
65+
Next you will have to set up the wrangler cli, so that you can connect to your cloudflare workers account.
5466

55-
Now let's link our local development server to our bot.
67+
- run `npx wrangler login` -> You will be prompted to authenticate your account, after which you will see a 'successfully logged in' message in your terminal
68+
- For a sanity check, run `npx wrangler whoami` -> You will then see your account name and account id in the terminal
5669

57-
- After all the commands are installed we need to save few secrets in wrangler cli.
58-
- run command `wrangler secret put DISCORD_TOKEN` and then enter the value of your token.
59-
- run command `wrangler secret put DISCORD_PUBLIC_KEY` and enter the public key.
60-
- Now, start the local server with the command `npm start`
61-
- Once the wrangler starts make sure it is running on port `8787`
62-
- Once the server starts on desired port open another terminal and type in the command `npm run ngrok`
63-
- The above command will give you a `https` link copy that.
70+
- Run the command `npx wrangler publish`
71+
- Go to Your cloudflare `dashboard > workers > discord-slash-commands > settings > variables > edit Variables`
72+
- Now add following variables to your environment:
73+
74+
- `BOT_PRIVATE_KEY`
75+
- `DISCORD_GUILD_ID`
76+
- `DISCORD_PUBLIC_KEY`
77+
- `DISCORD_TOKEN`
78+
79+
- Now, start the local server with the command `npm start`- make sure it is running on port `8787`
80+
- Open another terminal and type in the command `npm run ngrok`.
81+
- `ngrok` creates a secure tunnel that allows a local server to connect to external clients. It provides a URL that can be used to connect to a local server, just like if it were a public server hosted somewhere. For eg: Say you're running your app on `http://127.0.0.1:5501/` i.e localhost port 5501. Any external applications cannot connect to this server by default, but `ngrok` will give you a `http(s)` URL that any other client can use to connect to this server.
82+
- You will see 2 URLs generated, copy the `https` URL (eg: https://765m-321-132-44-44-44.ngrok.io)
6483
- Now, go to [Discord Developer Portal](https://discord.com/developers/applications) and select your bot
65-
- In general information panel you will find a space for `INTERACTIONS ENDPOINT URL`
66-
- Enter the copied link here and hit save.
84+
- In the General Information, paste the link in the `INTERACTIONS ENDPOINT URL` field.
6785

6886
To verify if your bot is working:
6987

7088
- Go to the server where your bot was invited
7189
- run a /hello command and the bot should reply with `Hello <Your_username>`
7290

91+
Now add the public key in `rds-backend`
92+
93+
- Go to `local.js` in config
94+
- Create following there
95+
96+
```
97+
botToken:{
98+
botPublicKey:<Public key generated in the format similar to development.js>
99+
}
100+
```
101+
102+
- Start the rds backend
103+
- Open a new terminal and run the following command `npx ngrok http <backend-port>`
104+
105+
- Go to `constants.js` in discord-slash-commands
106+
- Go to `src/constants/urls.ts`
107+
- Change the `RDS_BASE_DEVELOPMENT_API_URL` to the `ngrok https` URL generated for rds backend
108+
73109
Now you are ready to contribute to the Repository.

src/constants/responses.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ export const COMMAND_NOT_FOUND = "Command Not Found";
1818

1919
export const INTERNAL_SERVER_ERROR =
2020
"Oops! We have encountered an internal Server Error";
21+
22+
export const RETRY_COMMAND =
23+
"Oops, we didn't catch that! Please use the command again.";

src/controllers/verifyCommand.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import config from "../../config/config";
2+
import { RETRY_COMMAND } from "../constants/responses";
23
import { env } from "../typeDefinitions/default.types";
3-
import { discordTextResponse } from "../utils/discordResponse";
4+
import { discordEphemeralResponse } from "../utils/discordEphemeralResponse";
45
import { generateUniqueToken } from "../utils/generateUniqueToken";
5-
import { sendDiscordDm } from "../utils/sendDiscordDm";
66
import { sendUserDiscordData } from "../utils/sendUserDiscordData";
77

88
export async function verifyCommand(
@@ -22,12 +22,11 @@ export async function verifyCommand(
2222
discriminator,
2323
env
2424
);
25-
if (response?.status === 201) {
25+
if (response?.status === 201 || response?.status === 200) {
2626
const verificationSiteURL = config(env).VERIFICATION_SITE_URL;
2727
const message = `${verificationSiteURL}/discord?token=${token}`;
28-
await sendDiscordDm(userId, env, message);
29-
return discordTextResponse("Please check the DM");
28+
return discordEphemeralResponse(message);
3029
} else {
31-
return discordTextResponse("Error, please use the verify command again. ");
30+
return discordEphemeralResponse(RETRY_COMMAND);
3231
}
3332
}

src/typeDefinitions/default.types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ export interface responseJson {
2020
type: number;
2121
data: {
2222
content: string;
23+
flags?: number;
2324
};
2425
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { InteractionResponseType } from "discord-interactions";
2+
import JSONResponse from "./JsonResponse";
3+
export const discordEphemeralResponse = (reply: string): JSONResponse => {
4+
return new JSONResponse({
5+
type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
6+
data: {
7+
content: reply,
8+
flags: 64, // for ephemeral messages, flags value 64 will generate an ephemeral response. "1 << 6" is converted to integer.
9+
},
10+
});
11+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { InteractionResponseType } from "discord-interactions";
2+
import { responseJson } from "../../src/typeDefinitions/default.types";
3+
import JSONResponse from "../../src/utils/JsonResponse";
4+
import { discordEphemeralResponse } from "../../src/utils/discordEphemeralResponse";
5+
6+
describe("Test discordEphemeralResponse function", () => {
7+
it("should return a JSONResponse", () => {
8+
const response = discordEphemeralResponse("Hello");
9+
expect(response).toBeInstanceOf(JSONResponse);
10+
});
11+
it("Should have type as channelMessageWithSource", async () => {
12+
const response: responseJson = await discordEphemeralResponse(
13+
"Hello"
14+
).json();
15+
expect(response?.type).toBe(
16+
InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE
17+
);
18+
});
19+
it("Should contain a content property in data", async () => {
20+
const response: responseJson = await discordEphemeralResponse(
21+
"Hello"
22+
).json();
23+
expect(response?.data).toHaveProperty("content");
24+
});
25+
it("Should have content as hello", async () => {
26+
const response: responseJson = await discordEphemeralResponse(
27+
"Hello"
28+
).json();
29+
expect(response?.data.content).toBe("Hello");
30+
});
31+
it("Should contain a flag property in data", async () => {
32+
const response: responseJson = await discordEphemeralResponse(
33+
"Hello"
34+
).json();
35+
expect(response?.data).toHaveProperty("flags");
36+
});
37+
it("Should have flag as 64", async () => {
38+
const response: responseJson = await discordEphemeralResponse(
39+
"Hello"
40+
).json();
41+
expect(response?.data.flags).toBe(64);
42+
});
43+
});

wrangler.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
name = "discord-slash-commands"
22
main = "src/index.ts"
33
compatibility_date = "2023-01-13"
4-
node_compat = true
4+
node_compat = true
5+
[vars]

0 commit comments

Comments
 (0)