Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Files/PANNO00001.pdf
Binary file not shown.
Binary file added Files/PANNO00002.pdf
Binary file not shown.
20 changes: 20 additions & 0 deletions Files/email_logs_10-10-2025.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
10/10/2025, 11:19:19 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:19:19 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:24:48 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:24:48 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:27:14 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:27:14 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:34:28 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:34:28 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:37:40 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:37:40 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:41:30 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:41:30 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:46:32 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:46:32 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:48:46 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:48:46 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 11:54:58 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Subrato@infocusin.com]
10/10/2025, 11:54:58 AM - FAILED: No file found for PAN undefined. Skipping... [Recipient: Anohita@infocusin.com]
10/10/2025, 12:19:36 PM - SUCCESS: Email sent to: Subrato@infocusin.com, Files: PANNO00001.pdf
10/10/2025, 12:19:38 PM - SUCCESS: Email sent to: Anohita@infocusin.com, Files: PANNO00002.pdf
6 changes: 3 additions & 3 deletions backupIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,11 @@ async function sendFiles() {
await Promise.all(
filteredData.map(async (item) => {
let filePath = dirPath;
let pan = item["PAN NAME"];
let codeIdentifier = item["CODE1"];
let filesInFolder = fs.readdirSync(filePath);
let filesToSend = [];

const matchedFileName = filesInFolder.find(file => file.includes(pan));
const matchedFileName = filesInFolder.find(file => file.includes(codeIdentifier));

const logTime = () =>
new Date().toLocaleString('en-US', {
Expand All @@ -242,7 +242,7 @@ async function sendFiles() {
});

if (!matchedFileName) {
const msg = `No file found for PAN ${pan}. Skipping...`;
const msg = `No file found for CODE1 ${codeIdentifier}. Skipping...`;
showMessage(msg, false);
fs.appendFileSync(logFilePath, `${logTime()} - FAILED: ${msg} [Recipient: ${item["MAIL ID"]}]\n`);
return;
Expand Down
138 changes: 62 additions & 76 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,8 @@ let mailCount = 0;

// Function to send files as email attachments
async function sendFiles(event) {
// Validate the form first
// Validate form before sending
if (!formValidation()) {
// If not valid, stop the execution
return;
}

Expand All @@ -251,150 +250,137 @@ async function sendFiles(event) {
user: mail_ID,
pass: password,
},
// Retry configuration
retry: {
retries: 5, // Number of retries
factor: 2, // Exponential backoff factor
minTimeout: 1000, // Minimum time between retries in milliseconds
}
});

const formElement = document.getElementById("formbox1");
const loadingElement = document.getElementById("loading");
const mailCountBox = document.getElementById('mailCount');
let mailCountNo = document.getElementById('mailCountNo');
const mailCountBox = document.getElementById("mailCount");
const mailCountNo = document.getElementById("mailCountNo");

loadingElement.style.display = "block";
mailCountBox.style.display = "block";
formElement.classList.add("blur");

const workbook = XLSX.readFile(path1);
// Set up paths
const baseDir = __dirname;
const excelPath = path.join(baseDir, "Form_16_test_list.xlsx");
const dirPath = path.join(baseDir, "Files/"); // Folder where PDFs are stored
if (!fs.existsSync(dirPath)) {
showMessage("❌ 'Files' directory not found. Please create it and add your PDFs.", false);
loadingElement.style.display = "none";
formElement.classList.remove("blur");
return;
}

// Read the Excel file
const workbook = XLSX.readFile(excelPath);
const sheet_name_list = workbook.SheetNames;
const data = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list[0]]);

// Filter data to keep only objects with the "E mail" property
const filteredData = data.filter(obj => obj.hasOwnProperty("E mail"));
// Filter data to only include rows with MAIL ID
const filteredData = data.filter((obj) => obj.hasOwnProperty("MAIL ID"));

// If there are no valid objects, show an error message and stop further execution
if (filteredData.length === 0) {
showMessage("Invalid Excel format. No valid data with 'E mail' property found.", false);
showMessage("Invalid Excel format. No valid 'MAIL ID' column found.", false);
loadingElement.style.display = "none";
mailCountBox.style.display = "none";
formElement.classList.remove("blur");
return;
}

// dynamic the no of files go though
// Determine how many CODE columns exist
let maxCodeFileNo = 0;
filteredData.forEach(obj => {
Object.keys(obj).forEach(key => {
filteredData.forEach((obj) => {
Object.keys(obj).forEach((key) => {
if (key.startsWith("CODE")) {
// Extract number after "CODE"
const codeFileNo = parseInt(key.substring(4));
if (codeFileNo > maxCodeFileNo) {
maxCodeFileNo = codeFileNo;
}
}
})
})
});
});

try {
await Promise.all(
filteredData.map(async (item) => {
// Create a new instance of AdmZip for each recipient
const zip = new AdmZip();
let filePath = dirPath; // Set the correct filePath for each email
console.log("📄 Excel row:", item);

for (let i = 1; i <= maxCodeFileNo; i++) {
if (!item[`CODE${i}`]) {
const codeValue = item[`CODE${i}`];
const empName = item["Employee Name"];
const email = item["MAIL ID"];

if (!codeValue || codeValue.trim() === "") {
console.log(`⚠️ Skipping: No CODE${i} found [Recipient: ${email}]`);
continue;
} else {
zip.addLocalFile(filePath + item[`CODE${i}`] + ".pdf");
}

}
const pdfPath = path.join(dirPath, `${codeValue}.pdf`);
if (!fs.existsSync(pdfPath)) {
console.log(`❌ FAILED: No file found for ${codeValue}. Skipping... [Recipient: ${email}]`);
continue;
}

// Get the current date in the format "dd_mm_yyyy"
// const currentDate = new Date();
// const day = String(currentDate.getDate()).padStart(2, "0");
// const month = String(currentDate.getMonth() + 1).padStart(2, "0");
// const year = currentDate.getFullYear();
const downloadName = item['TRADER NAME'] + ".zip";
zip.addLocalFile(pdfPath);
}

// Create the zipped file
zip.writeZip(filePath + downloadName);
// Create ZIP name
const downloadName = `${item["Employee Name"]}.zip`;
const zipPath = path.join(dirPath, downloadName);
zip.writeZip(zipPath);

// Now the zip file is fully created, proceed with email sending
// Mail configuration
const mailOptions = {
from: mail_ID,
to: item["E mail"],
subject: "File Attachment",
text: `Hi ${item['TRADER NAME']}, please check the attachments`,
to: item["MAIL ID"],
subject: "Form 16 Documents",
text: `Hi ${item["Employee Name"]},\n\nPlease find attached your Form 16 documents.\n\nBest regards,\nYour HR Team`,
attachments: [
{
filename: downloadName,
path: filePath + downloadName,
path: zipPath,
},
],
};

// Use the rate limiter to control the email sending rate
// Send email with rate limiter
try {
await limiter.schedule(() => {
return new Promise((resolve, reject) => {
transporter.sendMail(mailOptions, function (error, info) {
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.log(error);

const errorMessage = error.response
? error.message.replace(/^Error:\s(.+?)\s\[.+/, "$1")
: "Error sending email. Please try again later.";


mailCount = 0;
mailCountBox.style.display = "none";
// Show the error message
showMessage(errorMessage, false);

console.log("❌ Email failed:", error.message);
showMessage(`❌ Failed to send to ${item["MAIL ID"]}`, false);
reject(error);
} else {
console.log("Email sent: " + info.response);
console.log(`✅ Email sent successfully to ${item["MAIL ID"]}`);
mailCount++;
mailCountNo.textContent = mailCount;

// Delete the zip file after email is sent successfully
// if (fs.existsSync(filePath + downloadName)) {
// fs.unlink(filePath + downloadName, (err) => {
// if (err) {
// console.error("Error deleting zip file:", err);
// } else {
// console.log("Zip file deleted successfully.");
// }
// });
// }

// Resolve the promise on success
resolve(info);
}
});
});
});
} catch (error) {
console.error("Email sending failed!", error);
throw error; // Throw the error again to handle it outside this catch block
} finally {
filePath = dirPath; // Reset filePath for the next email iteration
// Delete the ZIP after sending
if (fs.existsSync(zipPath)) {
fs.unlink(zipPath, (err) => {
if (err) console.error("Error deleting zip file:", err);
});
}
}
})
);

mailCountBox.style.display = "none";
// Show the success message after all emails are sent successfully
showMessage(`All Emails Sent Successfully : [\u0020${mailCount}\u0020]`, true);
showMessage(`✅ All Emails Sent Successfully: [${mailCount}]`, true);
mailCount = 0;
} catch (error) {
// Show the error message if any email encounters an error
showMessage(error, false);
showMessage(`❌ Error occurred: ${error}`, false);
} finally {
// Hide the loading box and reset the form
loadingElement.style.display = "none";
formElement.classList.remove("blur");
mailCountNo.textContent = 0;
Expand Down
Loading