Skip to content

Commit

Permalink
Added new routes for email integration
Browse files Browse the repository at this point in the history
  • Loading branch information
subru-37 committed Nov 2, 2024
1 parent 0030eb4 commit 489d03e
Show file tree
Hide file tree
Showing 6 changed files with 2,623 additions and 5,834 deletions.
4 changes: 4 additions & 0 deletions apps/core-admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,17 @@
"author": "",
"license": "ISC",
"dependencies": {
"@supabase/supabase-js": "^2.46.1",
"axios": "^1.5.1",
"bcryptjs": "^2.4.3",
"body-parser": "^1.20.2",
"chalk": "^5.3.0",
"cors": "^2.8.5",
"database": "workspace:*",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"express-oauth2-jwt-bearer": "^1.6.0",
"form-data": "^4.0.1",
"jsonwebtoken": "^9.0.0",
"passport": "^0.7.0",
"passport-local": "^1.0.0",
Expand Down
242 changes: 242 additions & 0 deletions apps/core-admin/src/controllers/mail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
import { Request, Response } from 'express';

import prisma from '../utils/database';
import axios from 'axios';
import * as dotenv from 'dotenv';
dotenv.config();
// import chalk from 'chalk';
import supabase from '../utils/supabase';
import FormData from 'form-data';

const MAILER_URL = process.env.MAILER_URL;
const MAILER_DATABASE_URL = process.env.MAILER_DATABASE_URL;
const AUTHORIZATION_TOKEN = process.env.AUTHORIZATION_TOKEN;
const sleepAsync = async (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};

export const sendMailWithQR = async (req: Request, res: Response) => {
try {
// const { name, to, subject, text, html, qr_code, projectId } = req.body;
const { subject, html, projectId } = req.body;
const { orgId, eventId } = req?.params;
if (!subject || !html || !projectId || !orgId || !eventId) {
return res.status(400).send({ message: 'Missing required fields' });
} else {
if (supabase) {
const response = await supabase.from('Recipients').select('*').eq('projectId', projectId);
if (response.status == 200) {
if (response.data && response.data?.length > 0) {
const recipients = response.data;
const numberOfRecipientsToBeMailed = recipients.length;
let numberOfRecipientsMailed = 0;
let RecipientsMailed = [];
let numberOfRecipientsAlreadyMailed = 0;
let numberOfRecipientsFailed = 0;
let RecipientsNotMailed = [];

for (const recipient of recipients) {
if (recipient.emailSent) {
numberOfRecipientsAlreadyMailed++;
console.log(`Project: ${projectId} - Mail already sent to ${recipient.email}`);
} else {
console.log(`Project: ${projectId} - Sending mail to ${recipient.email}`);
await sleepAsync(5);
const form = new FormData();
form.append('name', recipient.name);
form.append('to', recipient.email);
let emailText: string = html;
emailText = emailText.replace('{{payload}}', recipient.payload);
emailText = emailText.replace('{{payload}}', recipient.payload);
emailText = emailText.replace('{{name}}', recipient.name);
form.append('html', emailText);
form.append('subject', subject);
form.append('text', subject);
const response = await axios.post(`${MAILER_URL}/mail`, form, {
headers: {
...form.getHeaders(),
authorization: AUTHORIZATION_TOKEN,
},
});
console.log(response.data);
if (response && response.status == 200) {
await supabase
.from('Recipients')
.update({
emailSent: true,
emailSentAt: new Date().toDateString(),
jobId: response.data.jobId,
})
.eq('id', recipient.id);
numberOfRecipientsMailed++;
RecipientsMailed.push(recipient.email);
} else {
try {
console.log(response.data);
} catch (e) {
console.log('error', e);
}
numberOfRecipientsFailed++;
RecipientsNotMailed.push(recipient.email);
}
}
}
res.status(200).json({
success: RecipientsMailed,
failure: RecipientsNotMailed,
nSuccess: RecipientsMailed.length,
nFailure: RecipientsNotMailed.length,
});
} else {
res.status(400).send({ message: 'Invalid Project ID / project ID not found' });
}
} else {
res.status(400).send({ message: 'Incorrect project ID or invalid supabase credentials' });
}
} else {
res.status(500).send({ message: 'Invalid Supabase Credentials' });
}
}
} catch (e: any) {
console.error(e);
res.status(400).send({ message: e });
}
};

export const getMailStatus = async (req: Request, res: Response) => {
try {
const { email } = req?.params;
if (!email) {
return res.status(400).send({ message: 'Missing required fields' });
}
if (supabase) {
let response = await supabase.from('Recipients').select('jobId').eq('email', email);
if (response.data && response.status == 200) {
const jobId = response.data[0].jobId;
if (jobId) {
const emailStatus = await axios.get(`${MAILER_URL}/mail?jobId=${jobId}`, {
headers: {
authorization: AUTHORIZATION_TOKEN,
},
});
if (emailStatus && emailStatus.status == 200) {
console.log({ ...emailStatus.data.status });
res.send(200).json({
...emailStatus.data.status,
});
} else {
res.status(400).send({ message: 'JobId not found', error: emailStatus.data });
}
} else {
res.status(400).send({ message: 'Email Job ID not found, send email again' });
}
} else {
res.status(400).send({ message: 'Email Job not found, send email again' });
}
} else {
res.status(500).send({ message: 'Invalid Supabase Credentials' });
}
} catch (e: any) {
console.error(e);
res.status(400).send({ message: e });
}
};

export const newMailProject = async (req: Request, res: Response) => {
try {
const { name, desc } = req.body;
const { orgId } = req?.params;
if (!name || !desc || !orgId) {
return res.status(400).send({ message: 'Missing required fields' });
}
if (supabase) {
const response = await supabase.from('Projects').select('name').eq('name', name);
console.log(response.data);
if (response && response.status == 200) {
if (response.data && response.data?.length == 0) {
const response = await supabase
.from('Projects')
.insert({ name: name, description: desc });
if (response && response.status == 200) {
const currentProject = await supabase.from('Projects').select('*').eq('name', name);
res
.status(200)
.send({ message: 'Successfully created project', ...currentProject.data });
}
} else {
const currentProject = await supabase.from('Projects').select('*').eq('name', name);
res.status(200).send({ message: 'Project Already Exists', ...currentProject.data });
}
} else {
res.status(400).send({ message: 'Error', data: response.data });
}
} else {
res.status(500).send({ message: 'Invalid Supabase Credentials' });
}
} catch (e: any) {
console.error(e);
res.status(400).send({ message: e });
}
};

export const getMailProjects = async (req: Request, res: Response) => {
try {
const { orgId } = req?.params;
if (orgId) {
return res.status(400).send({ message: 'Missing required fields' });
}
if (supabase) {
const response = await supabase.from('Projects').select('*').eq('orgId', orgId);
if (response && response.status == 200) {
res.status(200).json({
data: response.data,
});
} else {
res.status(400).send({ message: 'No Emailing tasks found for this organization' });
}
} else {
res.status(500).send({ message: 'Invalid Supabase Credentials' });
}
} catch (e: any) {
console.error(e);
res.status(400).send({ message: e });
}
};

export const addNewRecipient = async (req: Request, res: Response) => {
const { projectId, name, email, payload } = req.body;
if (!projectId || !name || !email || !payload) {
return res.status(400).send({ message: 'Missing required fields' });
}
if (supabase) {
const recipientExists = await supabase
.from('Recipients')
.select('*')
.eq('projectId', projectId)
.eq('email', email);
if (recipientExists && recipientExists.status == 200) {
if (recipientExists.data && recipientExists.data?.length > 0) {
res.status(200).json({ message: 'User already exists, add another user' });
} else {
const response = await supabase
.from('Recipients')
.insert({ name: name, email: email, payload: payload, projectId: projectId });
console.log('Insert:', response.data);
if (response && response.status == 200) {
res.status(200).json({ message: 'User successfully Added' });
} else {
res.status(400).send({ message: 'User Not added', ...response.error });
}
}
} else {
res.status(400).send({ message: 'Supabase Error' });
}
} else {
res.status(500).send({ message: 'Invalid Supabase Credentials' });
}
try {
} catch (e: any) {
console.error(e);
res.status(400).send({ message: e });
}
};
11 changes: 10 additions & 1 deletion apps/core-admin/src/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { fetchAccountDetails, myCredential, updateAccountDetails } from './contr
import { validateOrganizationUser, validateOrganizationAdmin } from './middlewares/authorization';
import { addNewExtra, checkInExtra, getAllExtras, getExtraById } from './controllers/extras';
import { validateUUID } from './middlewares/validateParams';
import { addNewRecipient, getMailProjects, getMailStatus, newMailProject, sendMailWithQR } from './controllers/mail';

const router: Router = express.Router();

Expand Down Expand Up @@ -109,4 +110,12 @@ router.get('/organizations/:orgId/events/:eventId/extras/:extraId', getExtraById
router.post('/organizations/:orgId/events/:eventId/extras/:extraId/check-in', checkInExtra);
router.post('/organizations/:orgId/events/:eventId/extras', addNewExtra);

export default router;


//mailer routes
router.post('/organizations/:orgId/newEmailProject', newMailProject)
router.get('/organizations/:orgId/getEmailProjects', getMailProjects)
router.get('/organizations/:orgId/getMailStatus', getMailStatus)
router.post('/organizations/:orgId/addNewRecipient', addNewRecipient)
router.post('/organizations/:orgId/events/:eventId/mailQR', sendMailWithQR)
export default router;
14 changes: 14 additions & 0 deletions apps/core-admin/src/utils/supabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// supabaseClient.js

import { createClient } from '@supabase/supabase-js';
import * as dotenv from 'dotenv';
import { Database } from './supabaseTypes';
dotenv.config();

const SUPABASE_URL = process.env.SUPABASE_URL;
const SUPABASE_KEY = process.env.SUPABASE_KEY;

const supabase = SUPABASE_URL !== undefined && SUPABASE_KEY !== undefined && createClient<Database>(SUPABASE_URL, SUPABASE_KEY);

// module.exports = supabase;
export default supabase;
Loading

0 comments on commit 489d03e

Please sign in to comment.