I'm creating an app that will solely run on local except for mail sending operations.I've wrote necessary codes that will get recipients' mail adresses from excel file and send mail one by one. My problem is; if I select additional excel files after selecting first file, code sends mail to previously sent mails' recipients as well. I'll provide codes below:
main.js
// Handle file reading operation
ipcMain.on("openExcelFile", async (event, sender) => {
console.log(sender);
try {
const result = await dialog.showOpenDialog({
filters: [{ name: "Excel Dosyası", extensions: ["xlsx", "xls"] }],
properties: ["openFile"],
});
if (!result.canceled) {
const filePath = result.filePaths[0];
const workbook = XLSX.readFile(filePath);
const sheetName = workbook.SheetNames[0];
const sheet = workbook.Sheets[sheetName];
const jsonData = XLSX.utils.sheet_to_json(sheet, { header: 1 });
console.log(jsonData);
console.log(jsonData.length);
if (jsonData.length === 1 && jsonData[0].length === 0) {
event.reply("openExcelResponse", { error: "Alıcı dosyası geçersiz!" });
}
else {
if (sender === "mailSender") {
event.reply("recipientData", jsonData);
} else if (sender === "sertificateCreator") {
event.reply("participantData", jsonData);
}
}
}
} catch (error) {
console.error(error);
event.reply("recipientData", null); // Send null in case of error
}
});
ipcMain.on("sendEmail", async (event, emailOptions) => {
try {
await sendEmail(emailOptions);
event.reply("sendEmailResponse", { success: true });
} catch (error) {
event.reply("sendEmailResponse", {
success: false,
error: error.message,
});
}
});
async function sendEmail(emailOptions) {
// Create a Nodemailer transporter and send the email
var transporter = nodeMailer.createTransport(Credentials);
// Construct the email message
const mailOptions = {
from: Credentials.auth.user,
to: emailOptions.to,
subject: emailOptions.subject,
text: emailOptions.text,
};
// Check if attachments are present
if (emailOptions.attachments && emailOptions.attachments.length > 0) {
mailOptions.attachments = emailOptions.attachments.map((attachment) => ({
filename: attachment.filename,
path: attachment.path,
}));
}
// Send the email
await transporter.sendMail(mailOptions);
}
preload.js
contextBridge.exposeInMainWorld('api', {
openExcelFile: (sender) => {
ipcRenderer.send('openExcelFile', sender);
},
receiveRecipientData: (callback) => {
ipcRenderer.on('recipientData', (event, jsonData) => {
callback(jsonData);
});
},
getAttachments: () => {
ipcRenderer.send('getAttachments');
},
receiveAttachments: (callback) => {
ipcRenderer.on('attachments', (event, attachmentData) => {
callback(attachmentData);
});
},
sendEmail: (emailOptions) => {
ipcRenderer.send('sendEmail', emailOptions);
},
receiveEmailResponse: (callback) => {
ipcRenderer.on('sendEmailResponse', (event, response) => {
callback(response);
});
},
});
renderer.js
// Handle variables specific to mailSender.html
function handleMailSender() {
//Info buttons
const recipientInfoButton = document.getElementById("recipientInfoButton");
const recipientInfoBubble = document.querySelector("#recipientInfoButton .info-bubble");
const greetingInfoButton = document.getElementById("greetingInfoButton");
const greetingInfoBubble = document.querySelector("#greetingInfoButton .info-bubble");
if (recipientInfoButton && recipientInfoBubble) {
recipientInfoButton.addEventListener("click", toggleInfoBubble);
}
if (greetingInfoButton && greetingInfoBubble) {
greetingInfoButton.addEventListener("click", toggleInfoBubble);
}
function handleExcelFile() {
const recipientButton = document.getElementById('recipient');
if (recipientButton) {
recipientButton.addEventListener('click', () => {
window.api.openExcelFile(sender = 'mailSender');
});
}
}
function handleAttachments() {
const addAttachmentButton = document.getElementById('addAttachment');
if (addAttachmentButton) {
addAttachmentButton.addEventListener('click', () => {
window.api.getAttachments();
});
}
}
handleExcelFile();
handleAttachments();
//Reset form after submission
function resetForm() {
const form = document.querySelector('form');
form.reset();
const submitButton = document.querySelector('input[type="submit"]');
submitButton.disabled = true;
}
// Handle the email response
window.api.receiveEmailResponse((response) => {
if (response.success) {
showMessage('success', 'Mailler başarıyla gönderildi.');
resetForm();
} else {
const errorMessage = `Mail gönderilirken bir hata yaşandı:<br>${response.error}`;
showMessage('error', errorMessage);
console.error(response.error);
resetForm();
}
});
}
// Prepare the emails to be sent
function prepareEmail(mailSubject, recipientEmail, mailContent, attachmentData) {
const emailOptions = {
to: recipientEmail,
subject: mailSubject,
text: mailContent,
attachments: attachmentData
};
//console.log(emailOptions.attachments[0].filename);
// Send the email using nodemailer
window.api.sendEmail(emailOptions);
}
let attachmentData;
// Receive the attachments from the main process
window.api.receiveAttachments((data) => {
if (data) {
attachmentData = data;
console.log(attachmentData);
} else {
// Handle the case when an error occurred or no file was selected
console.error('Error occurred or no file selected');
}
});
// Receive the recipientData from the main process
window.api.receiveRecipientData((jsonData) => {
if (jsonData) {
console.log(jsonData);
const recipientData = jsonData.slice(1);
// Enable the submit button
const submitButton = document.querySelector('input[type="submit"]');
submitButton.disabled = false;
createMail(recipientData);
} else {
// Handle the case when an error occurred or no file was selected
console.error('Error occurred or no file selected');
}
});
function createMail(recipientData) {
// Add event listener for form submission
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
event.preventDefault(); // Prevent the default form submission behavior
const mailSubject = document.getElementById('mailSubject').value;
const mailContent = document.getElementById('mailContent').value;
const addGreeting = document.getElementById('greeting').checked;
recipientData.forEach((row) => {
const [name, email] = row;
// Construct the email content
let content = '';
if (addGreeting) {
content += `Merhaba ${name},\n`;
}
content += mailContent;
// Process the recipient file data and send emails
prepareEmail(mailSubject, email, content, attachmentData);
});
});
}
I've tried printing variables to see if any data was getting appended but everything seemed to work as intended. I've also tried removing eventlistener and re-adding it after selecting file once but it didn't work either. I'm quite new to electron so I'm not quite sure what I'm doing wrong. Any help is appreciated.
I've managed to solve the problem with getting rid of eventlisteners and using Global Event Handlers.
// Handle variables specific to mailSender.html
function handleMailSender() {
//Info buttons
const recipientInfoButton = document.getElementById("recipientInfoButton");
const recipientInfoBubble = document.querySelector("#recipientInfoButton .info-bubble");
const greetingInfoButton = document.getElementById("greetingInfoButton");
const greetingInfoBubble = document.querySelector("#greetingInfoButton .info-bubble");
if (recipientInfoButton && recipientInfoBubble) {
recipientInfoButton.onclick = toggleInfoBubble;
}
if (greetingInfoButton && greetingInfoBubble) {
greetingInfoButton.onclick = toggleInfoBubble;
}
function handleExcelFile() {
const recipientButton = document.getElementById('recipient');
if (recipientButton) {
recipientButton.onclick = () => {
window.api.openExcelFile(sender = 'mailSender');
};
}
}