通过用 Electron/React/TS 编写的应用程序发送电子邮件

Sending email via app written in Electron/React/TS

我正在尝试在我的应用程序中实施 email/gmail 发送机制。这是一个桌面应用程序,其托管内容是在 React 和 Electron 的帮助下编写的。我一直在尝试以网络上描述的各种方式实现它,使用各种模块,googleapi 等,但总是以一些奇怪的错误和更神秘的问题描述结束 - 代码通常基于文章的“Node.js”部分。我不知道我是否完全理解这个问题的架构方面,是否有可能触发发送机制,或者它是否必须以服务器端服务的形式实现。如果有人能阐明这个问题,我将不胜感激,因为我已经在这个问题上花费了 too 很多时间。提前致谢!

想通了(终于!)。我把它写在这里,希望它能对以后的人有所帮助。

所有尝试和方法对我失败的主要原因是我在 rendering/browser 进程而不是主 electron/node 进程上实现它们(来自 Electron 的 documentation). When I moved implementation described in details in this 文章(方法利用 nodemailer) 到主进程,在我的例子中,它几乎只包含 electron.js,并通过 [= 触发它20=]ipc(进程间通信)从渲染进程开始就奇迹般地起作用了!

感谢罗伯特指出 this 问题,因为以下陈述让我走上了正确的道路。

I was facing the same issue when trying to implement the nodemailer code client side. The reason was because nodemailer doesn't seem to work in the browser (only in node). Moving it serverside (into an express app) solved the issue.

// electron.js
var nodemailer = require("nodemailer");

function SendIt() {
  var transporter = nodemailer.createTransport({
    service: "gmail",
    auth: {
      user: "your_email@gmail.com",
      pass: "your_password",
    },
  });

  const mailOptions = {
    from: "your_email@gmail.com", 
    to: "recepient@gmail.com",
    subject: "Subject of your email",
    html: "<p>Your html here</p>",
  };

  transporter.sendMail(mailOptions, function (err, info) {
    if (err) console.log(err);
    else console.log(info);
  });
}

electron.ipcMain.on("SendIt", (event, args) => {
  console.log("ipcMain: Executing SendIt");
  SendIt();
});

如果有人正在使用 Quasar/Electron 并且想使用 nodemailer。这对我有用。我正在回复这个 post 因为它与电子有关。正如原作者所说,nodemailer作为node进程必须运行,不能在renderer进程上运行。

我把nodemailer的代码放在electron-preload.js文件里(src-electron目录下)

Electron 使用上下文隔离。因此需要将nodemailer代码放入electron-preload.js文件中。将它放在任何旧的 .vue 文件中都会导致错误。我得到的错误是:nodemailer.createTransport 不是函数

为了克服上下文隔离,我不得不使用上下文桥,如本电子文​​档中所述:https://www.electronjs.org/docs/latest/tutorial/context-isolation

出于测试目的,我按照 nodemailer 文档中的建议使用 ethereal.email。

electron-preload.js:

import { contextBridge } from 'electron'

contextBridge.exposeInMainWorld('myAPI', {
    doAThing: (emailFrom, emailTo, emailSubject, emailHTML) => {
         var nodemailer = require("nodemailer")

 let transporter = nodemailer.createTransport({
    host: "smtp.ethereal.email",
    port: 587,
    secure: false, // true for 465, false for other ports
     auth: {
          user: 'user@ethereal.email',
          pass: 'password'
      },
  })
  
    const mailOptions = {
      from: emailFrom, 
      to: emailTo,
      subject: emailSubject,
      html: emailHTML,
    }
  
    transporter.sendMail(mailOptions, function (err, info) {
      if (err) console.log(err);
      else console.log(info);
    })
      console.log("in the PreLoad Script")
    }
 }) // end contextBridge.exposeInMainWorld

然后,在我的 .vue 文件中(我称之为 personDetails.vue),我有一个按钮,当点击它时它会触发这个方法:

 async sendEmailMethodSMTP() {
      myAPI.doAThing(this.emailFrom, this.emailTo, this.emailSubject, this.emailHTML )
    }, // end sendEmailMethodSMTP

我正在从 .vue 文件传递​​的信息中收集变量信息(this.emailFrom、this.emailTo、this.emailSubject、this.emailHTML), electron-proload.js 文件中的 doAThing 方法。

按下按钮时,信息被传递到预加载器,nodemailer 被触发,电子邮件被发送。

我还没有编译我的 Quasar/Electron 应用程序来确保它能在实时环境中工作,但是 运行在开发模式下使用 quasar 这很好用。