如何使用Node.js从用户帐户发送电子邮件?

时间:2019-09-13 17:00:39

标签: javascript html sql node.js

我正在使用一个保存联系人的程序。我想添加一个新功能,使您可以通过电子邮件帐户向联系人发送电子邮件。 我尝试使用nodemailer进行此操作,从用户需要填写的表单中获取登录数据。

但是nodemailer给我发送了一个错误,看起来是这样:

Error: Invalid login: 535-5.7.8 Username and Password not accepted.

我尝试使用应用密码并激活了不太安全的选项,但是错误仍然存​​在。看我的代码:

我在这里获取用户的电子邮件和密码:

router.post('/email', isLoggedIn, async (req, res) => {
    var { email } = req.body;
    var { password } = req.body;

    var parts = email.substring(email.lastIndexOf('@')+ 1);



    exports.email = email;
    exports.password = password;

    res.redirect('/links/message')



});

我在这里留言:

router.post('/sendmessage', isLoggedIn, async (req, res) => {

    const { message } = req.body;
    const { assumpt } = req.body;
    exports.message = message;
    exports.assumpt = assumpt;
    res.redirect('/links/contactsemail')


});

最后,我选择了您需要发送电子邮件的类别联系人,并发送了电子邮件以及用户给我的消息和数据登录信息:

router.post('/contactsend', isLoggedIn, async (req, ress) => {
    const { contacts } = req.body;
    const row = await pool.query('SELECT count(email) AS email FROM links WHERE user_id=? AND category=? AND email IS NOT NULL',[req.user.id, contacts]);
    const rows = row[0].email;
    const assumpt = myModule.assumpt;
    const message = myModule.message;
    const email = myModule.email;
    const password = myModule.password
    var parts = email.substring(email.lastIndexOf('@')+ 1);
    const hosts = 'smtp.' + parts;
    var transporter = nodemailer.createTransport({
        host: hosts,
        port: 587,
        auth: {
            user: email,
            pass: password
        }
    });


   for (i = 1; i <= rows; i++ ){
    var email1 = await pool.query('SELECT email AS email FROM (SELECT  email, ROW_NUMBER() OVER (ORDER BY email) AS rn FROM links WHERE user_id= ? AND category=?) q WHERE  rn = ?', [req.user.id, contacts, i]);
    var email1 = email1[0].email;
    var mailOptions = {
        from: email,
        to: email1,
        subject: assumpt,
        text: message

    };



        transporter.sendMail(mailOptions, function (error, info) {
            if (error) {
                console.log(error);

            } else {
                console.log('Email sent: ' + info.response);
                res.flash('success', 'Missatge enviat correctament');
                res.redirect('/links');
            }
        });


    };


});

我的问题是:

如何解决该错误?

我可以通过不同的方式来做到这一点,因为它更容易,更好?

1 个答案:

答案 0 :(得分:0)

我是否正确理解您希望用户输入其私人/外部电子邮件提供商的凭据,以便您可以使用该提供商发送电子邮件?

在这种情况下,您的问题没有通用的答案,因为所需配置的细节在很大程度上取决于电子邮件提供商。例如,在您的代码中:

    var parts = email.substring(email.lastIndexOf('@')+ 1);
    const hosts = 'smtp.' + parts;
    var transporter = nodemailer.createTransport({
        host: hosts,
        port: 587,
        auth: {
            user: email,
            pass: password
        }
    });

此块已经有一些硬编码的假设,即john.doe@example.net的smtp主机为smtp.example.org,该电子邮件的用户名也为{{ 1}},这两者-不一定对许多电子邮件提供商都是如此。

所以即使这对您来说 也很有可能对所有用户 无效!

相反,您应该使用一个smtp网关/您的应用程序可以将电子邮件转发到的中继。然后,您也将不需要用户自己的凭据,但可以将您的应用程序的登录凭据用于该smtp网关。

但是是否允许您使用任意发件人地址发送邮件,这取决于您的smtp网关的配置。而且即使您的网关可能允许这样做,由于不允许您的网关发送用户域的电子邮件,由于垃圾邮件过滤器,邮件也可能被阻止,请参阅SPF

因此,除使用专用的smtp网关外,我建议您使用自己拥有和控制的电子邮件地址/域进行发送。您仍然可以增加直接来自用户的邮件,例如通过适当设置显示名称和Reply-To header

john.doe@example.net

对于此邮件,收件人将获得显示为发件人的发送用户的姓名(但您应用的电子邮件而非该用户的姓名),并且在单击“答复”按钮时,默认情况下将答复(取决于电子邮件客户端)发送回用户,例如From: "John Doe" <myapp@example.com> To: jane.doe@example.org Reply-To: "John Doe" <john.doe@example.org> Subject: "A message from John Doe via MyApp"