This commit is contained in:
Luke Vella 2022-05-09 08:21:53 +01:00 committed by GitHub
parent 1d7bcddf1b
commit 5c991d7011
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
83 changed files with 2463 additions and 1178 deletions

View file

@ -5,47 +5,128 @@ import { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
import path from "path";
import { prisma } from "../db";
import absoluteUrl from "./absolute-url";
import { sendEmail } from "./send-email";
export const exclude = <O extends Record<string, any>, E extends keyof O>(
obj: O,
...fieldsToExclude: E[]
): Omit<O, E> => {
const newObj = { ...obj };
fieldsToExclude.forEach((field) => {
delete newObj[field];
});
return newObj;
};
export const getQueryParam = (req: NextApiRequest, queryKey: string) => {
const value = req.query[queryKey];
return typeof value === "string" ? value : value[0];
};
export const withLink = (
handler: (
req: NextApiRequest,
res: NextApiResponse,
link: Link,
) => Promise<void>,
type ApiMiddleware<T, P extends Record<string, unknown>> = (
ctx: {
req: NextApiRequest;
res: NextApiResponse<T>;
} & P,
) => Promise<void | NextApiResponse>;
/**
* Gets the Link from `req.query.urlId` and passes it to handler
* @param handler
* @returns
*/
export const withLink = <T>(
handler: ApiMiddleware<T, { link: Link }>,
): NextApiHandler => {
return async (req, res) => {
const urlId = getQueryParam(req, "urlId");
const link = await prisma.link.findUnique({ where: { urlId } });
if (!link) {
const message = `Could not find link with urlId: ${urlId}`;
return res.status(404).json({
res.status(404).json({
status: 404,
message,
message: `Could not find link with urlId: ${urlId}`,
});
return;
}
return await handler(req, res, link);
await handler({ req, res, link });
return;
};
};
type NotificationAction =
| {
type: "newParticipant";
participantName: string;
}
| {
type: "newComment";
authorName: string;
};
export const sendNotification = async (
req: NextApiRequest,
pollId: string,
action: NotificationAction,
): Promise<void> => {
try {
const poll = await prisma.poll.findUnique({
where: { urlId: pollId },
include: { user: true, links: true },
});
/**
* poll needs to:
* - exist
* - be verified
* - not be a demo
* - have notifications turned on
*/
if (
poll &&
poll?.user.email &&
poll.verified &&
!poll.demo &&
poll.notifications
) {
const adminLink = getAdminLink(poll.links);
if (!adminLink) {
throw new Error(`Missing admin link for poll: ${pollId}`);
}
const homePageUrl = absoluteUrl(req).origin;
const pollUrl = `${homePageUrl}/admin/${adminLink.urlId}`;
const unsubscribeUrl = `${pollUrl}?unsubscribe=true`;
switch (action.type) {
case "newParticipant":
await sendEmailTemplate({
templateName: "new-participant",
to: poll.user.email,
subject: `Rallly: ${poll.title} - New Participant`,
templateVars: {
title: poll.title,
name: poll.authorName,
participantName: action.participantName,
pollUrl,
homePageUrl: absoluteUrl(req).origin,
supportEmail: process.env.SUPPORT_EMAIL,
unsubscribeUrl,
},
});
break;
case "newComment":
await sendEmailTemplate({
templateName: "new-comment",
to: poll.user.email,
subject: `Rallly: ${poll.title} - New Comment`,
templateVars: {
title: poll.title,
name: poll.authorName,
author: action.authorName,
pollUrl,
homePageUrl: absoluteUrl(req).origin,
supportEmail: process.env.SUPPORT_EMAIL,
unsubscribeUrl,
},
});
break;
}
}
} catch (e) {
console.error(e);
}
};
export const getAdminLink = (links: Link[]) =>
links.find((link) => link.role === "admin");