Skip to content

Commit

Permalink
Merge pull request #1 from CybTekk-LLP/feat/email
Browse files Browse the repository at this point in the history
Feat/email
  • Loading branch information
Shubhcyb2611 authored Jul 4, 2024
2 parents 073a200 + 20b0750 commit 3acaf71
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 1,091 deletions.
1,103 changes: 39 additions & 1,064 deletions package-lock.json

Large diffs are not rendered by default.

26 changes: 4 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,53 +8,35 @@
"@types/cors": "^2.8.17",
"@types/dotenv": "^8.2.0",
"@types/express": "^4.17.21",
"@types/jsdom": "^21.1.6",
"@types/jsonwebtoken": "^9.0.5",
"@types/node": "^20.11.25",
"@types/nodemailer": "^6.4.14",
"fix-esm-import-path": "^1.5.0",
"resolve-tspaths": "^0.8.17",
"swagger-autogen": "^2.23.7",
"ts-node": "10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.4.2"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.600.0",
"bcryptjs": "^2.4.3",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.1",
"axios": "^1.7.2",
"cors": "^2.8.5",
"dotenv": "^16.4.1",
"express": "^4.18.2",
"express-async-errors": "^3.1.1",
"express-list-endpoints": "^6.0.0",
"express-oas-generator": "^1.0.46",
"express-openapi-generator": "^1.2.0",
"fs": "^0.0.1-security",
"jsdom": "^24.0.0",
"jsonwebtoken": "^9.0.2",
"multer": "^1.4.5-lts.1",
"multer-s3": "^3.0.1",
"nodemailer": "^6.9.10",
"node-fetch": "^2.7.0",
"nodemailer": "^6.9.14",
"pg": "^8.11.3",
"pino": "^8.18.0",
"pino-pretty": "^10.3.1",
"reflect-metadata": "^0.1.13",
"stripe": "^14.18.0",
"swagger-jsdoc": "^6.2.8",
"swagger-ui-express": "^5.0.0",
"typeorm": "0.3.20"
},
"scripts": {
"dev": "node --watch --experimental-specifier-resolution=node --loader ./scripts/loader.js ./src/app.ts | pino-pretty",
"devv": "node --experimental-specifier-resolution=node --import @swc-node/register/esm ./src/app.ts | pino-pretty",
"typeorm": "node --experimental-specifier-resolution=node --loader ./scripts/loader.js scripts/typeorm.custom-cli.ts ",
"generate-migrations": "npm run typeorm migration:generate -- ./src/infrastructure/migrations/migration -d ./src/infrastructure/database.config.ts",
"migrate": "npm run typeorm migration:run -- -d ./src/infrastructure/database.config.ts",
"generate-and-migrate": "npm run generate-migrations; npm run migrate",
"build": "tsc --project .; resolve-tspaths; fix-esm-import-path dist",
"start": "npm run migrate; cd dist; node ./app.js;",
"generate-docs": "node ./dist/swagger.js"
"build": "tsc --project .; resolve-tspaths; fix-esm-import-path dist"
}
}
85 changes: 85 additions & 0 deletions src/application/services/EmailService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
Logger,
NODEMAILER_EMAIL,
NODEMAILER_PASSWORD,
PUBLIC_BASE_URI,
KLAVIYO_PRIVATE_API_KEY,
} from "@/config";

import fetch from "node-fetch";

export class EmailService {
async uploadImage(imageURL) {
const url = "https://a.klaviyo.com/api/images/";
const options = {
method: "POST",
headers: {
accept: "application/json",
revision: "2024-06-15",
"content-type": "application/json",
Authorization: `Klaviyo-API-Key ${KLAVIYO_PRIVATE_API_KEY}`,
},
body: JSON.stringify({
data: {
type: "image",
attributes: {
import_from_url: `${imageURL}`,
hidden: false,
},
},
}),
};

const data = await fetch(url, options);
return await data.json();
}
async sendEmail(recipientEmail: string, imageURL: string) {
const url = "https://a.klaviyo.com/api/events/";
const options = {
method: "POST",
headers: {
accept: "application/json",
revision: "2024-06-15",
"content-type": "application/json",
Authorization: `Klaviyo-API-Key ${KLAVIYO_PRIVATE_API_KEY}`,
},
body: JSON.stringify({
data: {
type: "event",
attributes: {
properties: {
submit: "Yes",
imageURL: imageURL,
},

metric: {
data: {
type: "metric",
attributes: {
name: "Picture Submit",
},
},
},
profile: {
data: {
type: "profile",
attributes: {
properties: {
submit: "Yes",
},
email: `${recipientEmail}`,
},
imageURL:
"https://d3k81ch9hvuctc.cloudfront.net/company/TWnsJV/images/e9c9c693-0df8-4954-8b6d-47af088b0fd1.jpeg",
},
},
},
},
}),
};
fetch(url, options)
.then((res) => res.json())
.then((json) => JSON.parse(json))
.catch((err) => console.error("error:" + err));
}
}
1 change: 1 addition & 0 deletions src/application/services/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./UploadService";
export * from "./EmailService";
1 change: 1 addition & 0 deletions src/config/env.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ export const {
UPLOADS_PATH,
ALLOWED_ORIGINS,
PUBLIC_BASE_URI,
KLAVIYO_PRIVATE_API_KEY,
} = process.env;
2 changes: 1 addition & 1 deletion src/config/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class Server {
this.config = config;
this.app = express();

this.app.use(express.json({ limit: "10mb" }));
this.app.use(cors(corsConfig));

this.app.use("/api/uploads", express.static(UPLOADS_PATH));
Expand All @@ -28,7 +29,6 @@ export class Server {
const port = this.config.port ?? 1209;
this.app.listen(port, () => {
Logger.info(`🚀: Server started on http://localhost:` + port);
Logger.info(`📝: Serving docs on http://localhost:${port}/api/docs`);
});
}
}
13 changes: 13 additions & 0 deletions src/interfaces/controllers/email.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { EmailService } from "@/application/services";
import { Request, Response } from "express";
export class EmailController {
constructor(private emailService?: EmailService) {
this.emailService = emailService;
}
sendEmail = async (req: Request, res: Response) => {
let email = req.query.email.toString();
let imageURL = req.query.imageurl.toString();
await this.emailService.sendEmail(email, imageURL);
res.status(200).send("Email sent successfully");
};
}
10 changes: 9 additions & 1 deletion src/interfaces/controllers/upload.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
AWS_S3_BUCKET_ACCESS_SECRET,
AWS_S3_BUCKET_NAME,
} from "@/config/env.config";
import { EmailService } from "@/application/services";

export const s3 = new S3Client({
region: AWS_S3_BUCKET_REGION,
Expand All @@ -16,6 +17,9 @@ export const s3 = new S3Client({
});

export class UploadsController {
constructor(private emailService?: EmailService) {
this.emailService = emailService;
}
handleGalleryUpload = async (req: Request, res: Response) => {
const urls = [];
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Expand All @@ -31,8 +35,12 @@ export class UploadsController {
Body: file.buffer,
ContentType: file.mimetype,
});
await s3.send(command)
await s3.send(command);
}
res.json({ uri: urls });
};
handleEmailImage = async (req: Request, res: Response) => {
const imageURL = await this.emailService.uploadImage(req.body.imageurl);
res.status(200).send(imageURL.data.attributes.image_url);
};
}
10 changes: 10 additions & 0 deletions src/interfaces/routers/email.router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Router } from "express";
import { EmailController } from "../controllers/email.controller";
import { EmailService } from "@/application/services";

const router = Router();

const emailService = new EmailService();
const emailController = new EmailController(emailService);
router.route("/").post(emailController.sendEmail);
export default router;
2 changes: 2 additions & 0 deletions src/interfaces/routers/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Router } from "express";
import uploadRouter from "./upload.router";
import emailrouter from "./email.router";

const appRouter = Router();

appRouter.use("/uploads", uploadRouter);
appRouter.use("/email", emailrouter);

export { appRouter };
7 changes: 4 additions & 3 deletions src/interfaces/routers/upload.router.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { Router } from "express";
import { UploadsController } from "../controllers";
import { uploadGallery } from "@/application/services";
import { EmailService, uploadGallery } from "@/application/services";

const router = Router();

const uploadController = new UploadsController();
const emailService = new EmailService();
const uploadController = new UploadsController(emailService);

router
.route("/gallery")
.post(
uploadGallery.array("gallery", 3),
uploadController.handleGalleryUpload
);
router.route("/images/email").post(uploadController.handleEmailImage);

export default router;

0 comments on commit 3acaf71

Please sign in to comment.