Skip to content

Commit

Permalink
Merge pull request #49 from srm-kzilla/lsd/feat/notifications
Browse files Browse the repository at this point in the history
Lsd/feat/notifications
  • Loading branch information
shawshankkumar authored Feb 22, 2022
2 parents 708f0d6 + 733e665 commit c43c8bb
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/api/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { initDbClient } from "../utils/database";
import { initDiscordBot } from "../utils/discord";
import { ERRORS } from "./error/error.constant";
import { join } from "path";
import notificationsRoutes from "./notifications/notifications.routes";

/**
* Initialize Webhook API Server
Expand Down Expand Up @@ -36,6 +37,7 @@ app.get("/", (req: Request, res: Response, next: NextFunction) => {
}
});
app.use("/api/v1", rolesRoutes);
app.use("/api/v1", notificationsRoutes);
app.use("/api/v1", channelRoutes);
app.use("/healthcheck", (req: Request, res: Response, next: NextFunction) => {
try {
Expand Down
33 changes: 33 additions & 0 deletions src/api/notifications/notifications.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { NextFunction, Request, Response, Router } from "express";
import validateQuery from "../middlewares/validate-query";
import { validateWebhook } from "../middlewares/validate-webhook";
import { notificationsService } from "./notifications.service";
import {
notificationsRequestSchema,
notificationsRequest,
} from "./notifications.schema";
const router = Router();

const handleNotifications = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const response = await notificationsService(
req.body as notificationsRequest
);
res.status(201).json(response);
} catch (err) {
next(err);
}
};

router.post(
"/notifications",
validateWebhook(),
validateQuery("body", notificationsRequestSchema),
handleNotifications
);

export default router;
23 changes: 23 additions & 0 deletions src/api/notifications/notifications.schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import * as yup from "yup";
import { emailSchema } from "../../models/email";

export const notificationsRequestSchema = yup.object({
emails: yup.array().of(emailSchema).required(),
title: yup.string().required(),
body: yup.string().required(),
});

export type notificationsRequest = yup.InferType<
typeof notificationsRequestSchema
>;

export interface notificationUserSchema {
email: string;
discordID: string;
}

export interface getDiscordUserDetailSchema {
userIDArray: Array<notificationUserSchema>;
failedEmails: Array<string>;
successEmails: Array<string>;
}
64 changes: 64 additions & 0 deletions src/api/notifications/notifications.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { checkInDBSchema } from "../../models/event";
import { getDbClient } from "../../utils/database";
import { getDiscordBot } from "../../utils/discord";
import {
notificationsRequest,
notificationUserSchema,
} from "./notifications.schema";
import { MessageEmbed } from "discord.js";
import { COLORS, CONSTANTS } from "../../utils/constants";

export const getDiscordID = async (emailArray: Array<string>) => {
const db = (await getDbClient()).db().collection(`jack-notifications`);
const userIDArray: notificationUserSchema[] = [];
const failedEmails: string[] = [];
for (let index = 0; index < emailArray.length; index++) {
const userEmail = emailArray[index];
const user = await db.findOne<checkInDBSchema>({
email: userEmail,
});
if (!user) {
failedEmails.push(userEmail);
} else {
const userID = user.discordID;
userIDArray.push({ email: userEmail, discordID: userID });
}
}
return { userIDArray, failedEmails };
};

export const notificationsService = async (data: notificationsRequest) => {
try {
const client = await getDiscordBot();
const notificationArray = await getDiscordID(data.emails);
const failedUsers = notificationArray.failedEmails;
if (notificationArray?.userIDArray.length && client) {
const notification = await (Promise as any).allSettled(
notificationArray.userIDArray.map(async (userDetails) => {
try {
const embed = new MessageEmbed()
.setColor(COLORS.PURPLE_HEX)
.setTitle(data.title)
.setDescription(data.body)
.setThumbnail(CONSTANTS.SRMKZILLA_GRADIENT_LOGO)
.setTimestamp()
.setFooter(CONSTANTS.FOOTER, CONSTANTS.FOOTER_LOGO_URL);
const user = await client.users.fetch(userDetails.discordID, false);
await user.send(embed);
} catch (err) {
failedUsers.push(userDetails.email);
}
})
);
}
return {
status: true,
failed: failedUsers,
};
} catch (error: any) {
throw {
code: error.code || 500,
message: error.message || "Internal Server Error",
};
}
};
3 changes: 3 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ export const CONSTANTS = {
FOOTER: "Powered by SRMKZILLA and hamster-charged batteries",
SRMKZILLA_WHITE_LOGO:
"https://jack.srmkzilla.net/assets/srmkzilla_logo_white_mono.png",
SRMKZILLA_GRADIENT_LOGO:
"https://mozohack-mozofest-2022.s3.ap-south-1.amazonaws.com/mozohack/srmkzlla_logo.png",
certificateUserDirectMessage: (eventName: string, username: string) =>
new MessageEmbed()
.setTitle(`${eventName} Certificates`)
Expand Down Expand Up @@ -469,6 +471,7 @@ export const COLORS = {
LEAVE_VOICE: "#ff0066",
MOVE_VOICE: "#00ccff",
REACTION_ROLE: "#bf00ff",
PURPLE_HEX: "#7289da",
};

export const randomMemesEndpoint = () => {
Expand Down

0 comments on commit c43c8bb

Please sign in to comment.