javascriptelectronaddeventlistenernodemailerjs-xlsx

ElectronJS Event Listener Loads All Files Instead of Latest Selected


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.


Solution

  • 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');
          };
        }
      }