Skip to content

Commit

Permalink
html pdf functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
rayhanalmim committed Jun 12, 2024
1 parent ff77ef3 commit 151c99d
Show file tree
Hide file tree
Showing 19 changed files with 2,261 additions and 84 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
node_modules
dist
.env
.vercel
31 changes: 31 additions & 0 deletions dist/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const cors_1 = __importDefault(require("cors"));
const pdftomail_route_1 = require("./app/modules/pdftoemail/pdftomail.route");
const app = (0, express_1.default)();
app.use(express_1.default.json());
app.use((0, cors_1.default)());
//applications route
app.use("/api", pdftomail_route_1.pdftomail);
app.get("/", (req, res) => {
res.send("Hello World!");
});
// Not Found Route Handler
app.use((req, res) => {
res.status(404).json({
success: false,
message: "Route not found",
});
});
app.use((err, req, res) => {
console.error(err.stack);
res.status(500).json({
success: false,
message: "An unexpected error occurred",
});
});
exports.default = app;
13 changes: 13 additions & 0 deletions dist/app/config/cloudinary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cloudinary_1 = require("cloudinary");
const index_1 = __importDefault(require("./index"));
cloudinary_1.v2.config({
cloud_name: index_1.default.cloudinary_cloud_name,
api_key: index_1.default.cloudinary_api_key,
api_secret: index_1.default.cloudinary_api_secret,
});
exports.default = cloudinary_1.v2;
18 changes: 18 additions & 0 deletions dist/app/config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const dotenv_1 = __importDefault(require("dotenv"));
const path_1 = __importDefault(require("path"));
dotenv_1.default.config({ path: path_1.default.join((process.cwd(), ".env")) });
exports.default = {
port: process.env.PORT,
database_url: process.env.DATABASE_URL,
cloudinary_cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
cloudinary_api_key: process.env.CLOUDINARY_API_KEY,
cloudinary_api_secret: process.env.CLOUDINARY_API_SECRET,
aws_access_key_id: process.env.AWS_ACCESS_KEY_ID,
aws_secret_access_key: process.env.AWS_SECRET_ACCESS_KEY,
aws_region: process.env.AWS_REGION,
};
111 changes: 111 additions & 0 deletions dist/app/modules/pdftoemail/pdftomail.controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PdfController = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const handlebars_1 = __importDefault(require("handlebars"));
const aws_sdk_1 = __importDefault(require("aws-sdk"));
const html_pdf_1 = __importDefault(require("html-pdf"));
const config_1 = __importDefault(require("../../config"));
// Configure AWS
aws_sdk_1.default.config.update({
accessKeyId: config_1.default.aws_access_key_id,
secretAccessKey: config_1.default.aws_secret_access_key,
region: config_1.default.aws_region,
signatureVersion: "v4",
});
const s3 = new aws_sdk_1.default.S3();
const generateAndUploadPdf = (req, res) => __awaiter(void 0, void 0, void 0, function* () {
try {
const pdfData = req.body;
// Validate input data
if (!pdfData.title || !pdfData.content) {
return res.status(400).json({
success: false,
message: "Title and content are required.",
});
}
// HTML template as a string
const templateContent = `
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<h1>{{title}}</h1>
<p>{{content}}</p>
</body>
</html>
`;
// Compile the template
const template = handlebars_1.default.compile(templateContent);
// Generate HTML from the template and data
const html = template({ title: pdfData.title, content: pdfData.content });
// Use html-pdf to generate the PDF
html_pdf_1.default.create(html).toFile((err, fileInfo) => {
if (err) {
console.error("Error generating PDF:", err);
return res.status(500).json({
success: false,
message: "Failed to generate PDF",
error: err,
});
}
// Upload the PDF to AWS S3
const fileContent = fs_1.default.readFileSync(fileInfo.filename);
const uploadParams = {
Bucket: "loamic-media",
Key: `pdfs/${Date.now()}-${path_1.default.basename(fileInfo.filename)}`,
Body: fileContent,
ContentType: "application/pdf",
};
s3.upload(uploadParams, (uploadErr, data) => __awaiter(void 0, void 0, void 0, function* () {
if (uploadErr) {
console.error("Error uploading to S3:", uploadErr);
fs_1.default.unlinkSync(fileInfo.filename); // Ensure temporary file is deleted even on upload failure
return res.status(500).json({
success: false,
message: "Failed to upload PDF to S3",
error: uploadErr,
});
}
// Generate a pre-signed URL for the uploaded PDF
const signedUrl = yield s3.getSignedUrlPromise("getObject", {
Bucket: "loamic-media",
Key: uploadParams.Key,
Expires: 60 * 5, // Link expires in 5 minutes
});
// Delete temporary file
fs_1.default.unlinkSync(fileInfo.filename);
res.json({
downloadUrl: signedUrl,
message: "Email sent successfully",
});
}));
});
}
catch (error) {
console.error("Unexpected error:", error);
res.status(500).json({
success: false,
message: "Something went wrong!",
error: error,
});
}
});
exports.PdfController = {
generateAndUploadPdf,
};
6 changes: 6 additions & 0 deletions dist/app/modules/pdftoemail/pdftomail.model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DemoDataModel = void 0;
const mongoose_1 = require("mongoose");
// DemoData model without a schema
exports.DemoDataModel = (0, mongoose_1.model)("DemoData", new mongoose_1.Schema({}, { strict: false }));
11 changes: 11 additions & 0 deletions dist/app/modules/pdftoemail/pdftomail.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pdftomail = void 0;
const express_1 = __importDefault(require("express"));
const pdftomail_controller_1 = require("./pdftomail.controller");
const router = express_1.default.Router();
router.post("/generate-pdf", pdftomail_controller_1.PdfController.generateAndUploadPdf);
exports.pdftomail = router;
1 change: 1 addition & 0 deletions dist/app/modules/pdftoemail/pdftomailservices.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"use strict";
31 changes: 31 additions & 0 deletions dist/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const app_1 = __importDefault(require("./app"));
const mongoose_1 = __importDefault(require("mongoose"));
const config_1 = __importDefault(require("./app/config"));
function main() {
return __awaiter(this, void 0, void 0, function* () {
try {
yield mongoose_1.default.connect(config_1.default.database_url);
app_1.default.listen(config_1.default.port, () => {
console.log(`pdf to email server listening on port ${config_1.default.port}`);
});
}
catch (error) {
console.log(error);
}
});
}
main();
Loading

0 comments on commit 151c99d

Please sign in to comment.