Skip to content

Commit 40742cd

Browse files
committed
feat: added command and handler
1 parent 15e41cc commit 40742cd

File tree

6 files changed

+172
-0
lines changed

6 files changed

+172
-0
lines changed

src/constants/commands.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,34 @@ export const NOTIFY_ONBOARDING = {
217217
},
218218
],
219219
};
220+
221+
export const ONBOARDING_EXTENSION = {
222+
name: "onboarding-extension",
223+
description: "This command helps to create an onboarding extension request.",
224+
options: [
225+
{
226+
name: "username",
227+
description: "Username of onboarding user",
228+
type: 6,
229+
required: true,
230+
},
231+
{
232+
name: "number-of-days",
233+
description: "Number of days required for the extension request",
234+
type: 4,
235+
required: true,
236+
},
237+
{
238+
name: "reason",
239+
description: "Reason for the extension request",
240+
type: 3,
241+
required: true,
242+
},
243+
{
244+
name: "dev",
245+
description: "Feature flag",
246+
type: 5,
247+
required: true,
248+
},
249+
],
250+
};

src/controllers/baseHandler.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
REMOVE,
3131
GROUP_INVITE,
3232
GRANT_AWS_ACCESS,
33+
ONBOARDING_EXTENSION,
3334
} from "../constants/commands";
3435
import { updateNickName } from "../utils/updateNickname";
3536
import { discordEphemeralResponse } from "../utils/discordEphemeralResponse";
@@ -46,6 +47,7 @@ import { DevFlag } from "../typeDefinitions/filterUsersByRole";
4647
import { kickEachUser } from "./kickEachUser";
4748
import { groupInvite } from "./groupInvite";
4849
import { grantAWSAccessCommand } from "./grantAWSAccessCommand";
50+
import { onboardingExtensionCommand } from "./onboardingExtensionCommand";
4951

5052
export async function baseHandler(
5153
message: discordMessageRequest,
@@ -187,6 +189,21 @@ export async function baseHandler(
187189

188190
return await groupInvite(data[0].value, data[1].value, env);
189191
}
192+
193+
case getCommandName(ONBOARDING_EXTENSION): {
194+
const data = message.data?.options as Array<messageRequestDataOptions>;
195+
const transformedArgument = {
196+
userId: data[0],
197+
numberOfDays: data[1],
198+
reason: data[2],
199+
channelId: message.channel_id,
200+
member: message.member,
201+
dev: data.find((item) => item.name === "dev") as unknown as DevFlag,
202+
};
203+
204+
return await onboardingExtensionCommand(transformedArgument, env, ctx);
205+
}
206+
190207
default: {
191208
return commandNotFound();
192209
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { env } from "../typeDefinitions/default.types";
2+
import {
3+
messageRequestDataOptions,
4+
messageRequestMember,
5+
} from "../typeDefinitions/discordMessage.types";
6+
import { DevFlag } from "../typeDefinitions/filterUsersByRole";
7+
import { discordTextResponse } from "../utils/discordResponse";
8+
import {
9+
createOnboardingExtension,
10+
CreateOnboardingExtensionArgs,
11+
} from "../utils/onboardingExtension";
12+
13+
export async function onboardingExtensionCommand(
14+
transformedArgument: {
15+
member: messageRequestMember;
16+
userId: messageRequestDataOptions;
17+
numberOfDays: messageRequestDataOptions;
18+
reason: messageRequestDataOptions;
19+
channelId: number;
20+
dev?: DevFlag;
21+
},
22+
env: env,
23+
ctx: ExecutionContext
24+
) {
25+
const dev = transformedArgument.dev?.value || false;
26+
const discordId = transformedArgument.member.user.id.toString();
27+
28+
if (!dev) {
29+
return discordTextResponse(`<@${discordId}> Feature not implemented`);
30+
}
31+
32+
const args: CreateOnboardingExtensionArgs = {
33+
channelId: transformedArgument.channelId,
34+
userId: transformedArgument.userId.value,
35+
numberOfDays: Number(transformedArgument.numberOfDays.value),
36+
reason: transformedArgument.reason.value,
37+
discordId: discordId,
38+
};
39+
40+
const initialResponse = `<@${discordId}> Processing your request for onboarding extension`;
41+
42+
ctx.waitUntil(createOnboardingExtension(args, env));
43+
44+
return discordTextResponse(initialResponse);
45+
}

src/register.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
REMOVE,
1212
GROUP_INVITE,
1313
GRANT_AWS_ACCESS,
14+
ONBOARDING_EXTENSION,
1415
} from "./constants/commands";
1516
import { config } from "dotenv";
1617
import { DISCORD_BASE_URL } from "./constants/urls";
@@ -44,6 +45,7 @@ async function registerGuildCommands(
4445
REMOVE,
4546
GROUP_INVITE,
4647
GRANT_AWS_ACCESS,
48+
ONBOARDING_EXTENSION,
4749
];
4850

4951
try {

src/utils/onboardingExtension.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import config from "../../config/config";
2+
import { DISCORD_BASE_URL } from "../constants/urls";
3+
import { env } from "../typeDefinitions/default.types";
4+
import { generateDiscordAuthToken } from "./authTokenGenerator";
5+
import { sendReplyInDiscordChannel } from "./sendReplyInDiscordChannel";
6+
7+
export type CreateOnboardingExtensionArgs = {
8+
userId: string;
9+
channelId: number;
10+
reason: string;
11+
numberOfDays: number;
12+
discordId: string;
13+
};
14+
15+
export const createOnboardingExtension = async (
16+
args: CreateOnboardingExtensionArgs,
17+
env: env
18+
) => {
19+
const { channelId } = args;
20+
21+
const authToken = await generateDiscordAuthToken(
22+
"Cloudflare Worker",
23+
Math.floor(Date.now() / 1000) + 2,
24+
env.BOT_PRIVATE_KEY,
25+
"RS256"
26+
);
27+
28+
const discordReplyUrl = `${DISCORD_BASE_URL}/channels/${channelId}/messages`;
29+
const base_url = config(env).RDS_BASE_API_URL;
30+
const createOnboardingExtensionUrl = `${base_url}/requests?dev=true`;
31+
const requestBody = {
32+
userId: args.userId,
33+
type: "ONBOARDING",
34+
numberOfDays: args.numberOfDays,
35+
requestedBy: args.discordId,
36+
reason: args.reason,
37+
};
38+
39+
let content: string;
40+
41+
try {
42+
const response = await fetch(createOnboardingExtensionUrl, {
43+
method: "POST",
44+
headers: {
45+
"Content-Type": "application/json",
46+
Authorization: `Bearer ${authToken}`,
47+
},
48+
body: JSON.stringify(requestBody),
49+
});
50+
const jsonResponse = (await response.json()) as unknown as {
51+
message: string;
52+
};
53+
content = `<@${args.discordId}> ${jsonResponse.message}`;
54+
await sendReplyInDiscordChannel(discordReplyUrl, content, env);
55+
} catch (err) {
56+
content = `<@${args.discordId}> Error occurred while creating onboarding extension request.`;
57+
await sendReplyInDiscordChannel(discordReplyUrl, content, env);
58+
}
59+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { env } from "../typeDefinitions/default.types";
2+
3+
export const sendReplyInDiscordChannel = async (
4+
discordReplyUrl: string,
5+
body: any,
6+
env: env
7+
) => {
8+
await fetch(discordReplyUrl, {
9+
method: "POST",
10+
headers: {
11+
"Content-Type": "application/json",
12+
Authorization: `Bot ${env.DISCORD_TOKEN}`,
13+
},
14+
body: JSON.stringify({
15+
content: body,
16+
}),
17+
});
18+
};

0 commit comments

Comments
 (0)