diff --git a/config/config.ts b/config/config.ts index e594a218..1c95bcad 100644 --- a/config/config.ts +++ b/config/config.ts @@ -11,6 +11,8 @@ import { STAGING_RDS_TRACKING_CHANNEL_URL, RDS_STATUS_SITE_URL, RDS_STAGING_STATUS_SITE_URL, + RDS_DASHBOARD_SITE_URL, + RDS_STAGING_DASHBOARD_SITE_URL, } from "../src/constants/urls"; import { DISCORD_PROFILE_SERVICE_HELP_GROUP, @@ -26,6 +28,7 @@ const config = (env: env) => { TRACKING_CHANNEL_URL: RDS_TRACKING_CHANNEL_URL, PROFILE_SERVICE_HELP_GROUP_ID: DISCORD_PROFILE_SERVICE_HELP_GROUP, RDS_STATUS_SITE_URL: RDS_STATUS_SITE_URL, + DASHBOARD_SITE_URL: RDS_DASHBOARD_SITE_URL, }, staging: { RDS_BASE_API_URL: RDS_BASE_STAGING_API_URL, @@ -33,6 +36,7 @@ const config = (env: env) => { TRACKING_CHANNEL_URL: STAGING_RDS_TRACKING_CHANNEL_URL, PROFILE_SERVICE_HELP_GROUP_ID: DISCORD_PROFILE_SERVICE_STAGING_HELP_GROUP, RDS_STATUS_SITE_URL: RDS_STAGING_STATUS_SITE_URL, + DASHBOARD_SITE_URL: RDS_STAGING_DASHBOARD_SITE_URL, }, default: { RDS_BASE_API_URL: RDS_BASE_DEVELOPMENT_API_URL, @@ -41,6 +45,7 @@ const config = (env: env) => { PROFILE_SERVICE_HELP_GROUP_ID: DISCORD_PROFILE_SERVICE_DEVELOPMENT_HELP_GROUP, RDS_STATUS_SITE_URL: RDS_STATUS_SITE_URL, + DASHBOARD_SITE_URL: RDS_DASHBOARD_SITE_URL, }, }; diff --git a/src/constants/commands.ts b/src/constants/commands.ts index 1ec8aa73..1225cb59 100644 --- a/src/constants/commands.ts +++ b/src/constants/commands.ts @@ -9,6 +9,25 @@ export const VERIFY = { "Generate a link with user specific token to link with RDS backend.", }; +export const GROUP_INVITE = { + name: "group-invite", + description: "Send group invite link for the user.", + options: [ + { + name: "name", + description: "User to send group invite link", + type: 6, + required: true, + }, + { + name: "role", + description: "Role you want to invite to the user", + type: 8, + required: true, + }, + ], +}; + export const MENTION_EACH = { name: "mention-each", description: "mention each user with this role", diff --git a/src/constants/responses.ts b/src/constants/responses.ts index bff6a2c0..59a04ff9 100644 --- a/src/constants/responses.ts +++ b/src/constants/responses.ts @@ -65,6 +65,8 @@ export const FAILED_TO_FETCH_TASKS = `Failed to fetch tasks for **{{assignee}}** export const USER_NOT_FOUND = `User Not Found`; export const USER_STATUS_NOT_FOUND = "No Status Found"; +export const FAILED_TO_FETCH_DISCORD_GROUPS = "Failed to fetch discord groups"; + export const OVERDUE_DEFAULT_MESSAGE = "You have overdue tasks."; export const OVERDUE_CUSTOM_MESSAGE = "Please be aware that you currently have tasks that are overdue or due within the next {{days}} day. If you require additional time to complete these tasks, kindly submit an extension request."; diff --git a/src/constants/urls.ts b/src/constants/urls.ts index e60a02d0..a86b355f 100644 --- a/src/constants/urls.ts +++ b/src/constants/urls.ts @@ -22,3 +22,7 @@ export const DEVELOPMENT_RDS_TRACKING_CHANNEL_URL = export const RDS_STATUS_SITE_URL = "https://status.realdevsquad.com"; export const RDS_STAGING_STATUS_SITE_URL = "https://staging-status.realdevsquad.com"; + +export const RDS_DASHBOARD_SITE_URL = "https://dashboard.realdevsquad.com"; +export const RDS_STAGING_DASHBOARD_SITE_URL = + "https://staging-dashboard.realdevsquad.com"; diff --git a/src/controllers/baseHandler.ts b/src/controllers/baseHandler.ts index 89129e1f..acb22e97 100644 --- a/src/controllers/baseHandler.ts +++ b/src/controllers/baseHandler.ts @@ -28,6 +28,7 @@ import { OOO, USER, REMOVE, + GROUP_INVITE, } from "../constants/commands"; import { updateNickName } from "../utils/updateNickname"; import { discordEphemeralResponse } from "../utils/discordEphemeralResponse"; @@ -42,6 +43,7 @@ import { } from "../constants/responses"; import { DevFlag } from "../typeDefinitions/filterUsersByRole"; import { kickEachUser } from "./kickEachUser"; +import { groupInvite } from "./groupInvite"; export async function baseHandler( message: discordMessageRequest, @@ -156,6 +158,12 @@ export async function baseHandler( const data = message.data?.options as Array; return await userCommand(data[0].value, env); } + + case getCommandName(GROUP_INVITE): { + const data = message.data?.options as Array; + + return await groupInvite(data[0].value, data[1].value, env); + } default: { return commandNotFound(); } diff --git a/src/controllers/groupInvite.ts b/src/controllers/groupInvite.ts new file mode 100644 index 00000000..95049b4d --- /dev/null +++ b/src/controllers/groupInvite.ts @@ -0,0 +1,21 @@ +import config from "../../config/config"; +import { env } from "../typeDefinitions/default.types"; +import { discordTextResponse } from "../utils/discordResponse"; +import { fetchDiscordGroups } from "../utils/fetchDiscordGroups"; + +export async function groupInvite(userId: string, roleId: string, env: env) { + const response = await fetchDiscordGroups(env); + const group = response.groups.find((group) => group.roleid === roleId); + + if (!group) { + return discordTextResponse(`<@&${roleId}> is not a valid group.`); + } + + const groupName = group.rolename.replace(/^group-/, ""); + + return discordTextResponse( + `<@${userId}> join the group <@&${roleId}> via the link below:\n ${ + config(env).DASHBOARD_SITE_URL + }/groups/?dev=true&name=${groupName}` + ); +} diff --git a/src/register.ts b/src/register.ts index c7ca0263..6bd22737 100644 --- a/src/register.ts +++ b/src/register.ts @@ -9,6 +9,7 @@ import { OOO, USER, REMOVE, + GROUP_INVITE, } from "./constants/commands"; import { config } from "dotenv"; import { DISCORD_BASE_URL } from "./constants/urls"; @@ -39,6 +40,7 @@ async function registerGuildCommands( NOTIFY_OVERDUE, NOTIFY_ONBOARDING, REMOVE, + GROUP_INVITE, ]; try { diff --git a/src/typeDefinitions/default.types.d.ts b/src/typeDefinitions/default.types.d.ts index 3ae4f36b..b1828b20 100644 --- a/src/typeDefinitions/default.types.d.ts +++ b/src/typeDefinitions/default.types.d.ts @@ -7,6 +7,7 @@ export interface environment { } export interface variables { + DASHBOARD_SITE_URL: string; RDS_BASE_API_URL: string; VERIFICATION_SITE_URL: string; TRACKING_CHANNEL_URL: string; diff --git a/src/typeDefinitions/group.types.d.ts b/src/typeDefinitions/group.types.d.ts new file mode 100644 index 00000000..1d9b8d0b --- /dev/null +++ b/src/typeDefinitions/group.types.d.ts @@ -0,0 +1,18 @@ +export type GroupType = { + id: string; + date: { + _seconds: number; + _nanoseconds: number; + }; + createdBy: string; + rolename: string; + roleid: string; + description: string; + memberCount: number; + isMember: boolean; +}; + +export type GroupResponseType = { + message?: string; + groups: GroupType[]; +}; diff --git a/src/utils/fetchDiscordGroups.ts b/src/utils/fetchDiscordGroups.ts new file mode 100644 index 00000000..7469bace --- /dev/null +++ b/src/utils/fetchDiscordGroups.ts @@ -0,0 +1,23 @@ +import config from "../../config/config"; +import { FAILED_TO_FETCH_DISCORD_GROUPS } from "../constants/responses"; +import { env } from "../typeDefinitions/default.types"; +import { GroupResponseType } from "../typeDefinitions/group.types"; + +async function fetchDiscordGroups(env: env): Promise { + try { + const url = `${config(env).RDS_BASE_API_URL}/discord-actions/groups`; + const response = await fetch(url); + + if (!response.ok) { + throw new Error(FAILED_TO_FETCH_DISCORD_GROUPS); + } + + const responseData: GroupResponseType = await response.json(); + return responseData; + } catch (error) { + console.error("An error occurred while fetching discord groups:", error); + throw error; + } +} + +export { fetchDiscordGroups };