在“nodejs”中使用“@sendgrid/mail”发送“base64”电子邮件“附件”时遇到问题

Posted

技术标签:

【中文标题】在“nodejs”中使用“@sendgrid/mail”发送“base64”电子邮件“附件”时遇到问题【英文标题】:Having issues sending "base64" email "attachments" using "@sendgrid/mail" in "nodejs" 【发布时间】:2021-10-22 07:09:28 【问题描述】:

所以,基本上我想在@sendgrid/mail 中发送一个base64 编码的.zip 文件作为电子邮件附件。该文件像这样保存在MongoDB中,

我正在获取数据并使用类似这样的 .toString("base64") 将二进制数据“file.buffer”转换为 base64,

console.log('Converting to base64')
plugin.file.buffer = plugin.file.buffer.toString('base64')

它被完美地转换成base64(我知道它正在工作,因为我也在.ejs文件中使用那个“plugin.file”作为下载按钮,就像这样,

<a class="btn btn-success btn-sm" download="plugin.zip" href="data:application/zip;base64,<%- plugin %>" role="button">Download</a>

所以,现在我将使用该“插件”向用户发送电子邮件,所以我在渲染 ejs 页面之前正在做类似的事情,

if (req.session.email) await sendMail(req.session.email , "Thanks for purchasing" , "Here is your delivery!" , plugin)
res.render('success' , payment , type: "Payment" , discord , plugin: plugin.file.buffer)

它基本上检查用户的电子邮件是否存储在“会话”中,即登录,如果是,它会发送一封电子邮件,然后呈现成功页面!

所以,问题出在 email.js 文件的 sendMail() 函数中。它既没有向我发送电子邮件,也没有发送附件。

在显示该函数()中的代码之前,我的 api 密钥等是正确的,因为每当用户创建帐户时我也会发送邮件,在这种情况下,一切正常并且正在发送邮件。但是每当我包含附件逻辑时,邮件和附件都不会被发送!所以,这是我的代码:-

const  MAILER_API_KEY  = require('../config.json')
const mailer = require('@sendgrid/mail')
mailer.setApiKey(MAILER_API_KEY)

async function sendMail(email , subject , text , plugin) 
    mailOptions = 
        to: email,
        from: 'zoomdev.code@gmail.com',
        subject: subject,
        text: text
    

    // if this if statement is false i.e. plugin is undefined(whenever the user is signing up, he/she doesnt need attachment or stuff. The attachment email is being sent whenever the payment is completed and the file is being sent to the user) it works fine. But sending an attachment doesn't work. The email and attachment doesn't get sent!
    if (plugin) mailOptions.attachments = [
        content: plugin.file.buffer,
        filename: plugin.file.originalname,
        type: 'application/zip', // Here, I have also tried using "application/x-zip-compressed", the type saved in the database and it is the same! :(
        disposition: 'attachment'
    ]

    await mailer.send(mailOptions).then(res => 
        console.log(JSON.stringify(res))
        return true
    ).catch(err => 
        console.log(JSON.stringify(err))
        return false
    )
    console.log('Mail sent to ' + email)


module.exports =  sendMail 

每当发送附件电子邮件时,我都会在控制台中收到此邮件,

Executing Payment
Converting to base64
Updating user
// ^ these are something else. Ignore them

// this is the JSON.stringify(... console.log in sendMail function last lines
["statusCode":202,"body":"","headers":"server":"nginx","date":"Fri, 22 Oct 2021 06:57:18 GMT","content-length":"0","connection":"close","x-message-id":"QpxSudqkRGytDU7YFleVgA","access-control-allow-origin":"https://sendgrid.api-docs.io","access-control-allow-methods":"POST","access-control-allow-headers":"Authorization, Content-Type, On-behalf-of, x-sg-elas-acl","access-control-max-age":"600","x-no-cors-reason":"https://sendgrid.com/docs/Clas-s-room/Basics/API/cors.html","strict-transport-security":"max-age=600; includeSubDomains",""]
Mail sent to <my email , I have edited this part for privacy, but it correctly logs the email>

注意:-

    我正在使用 express@^4.17.1 @sendgrid/mail@^7.4.7 我已检查垃圾邮件文件夹和所有内容

【问题讨论】:

在您的代码中,您发送的电子邮件地址是 Gmail 地址。您在创建帐户时发送电子邮件时使用的是同一电子邮件吗?您是否使用 Single Sender Verification 验证了该电子邮件地址? 是的,电子邮件地址是正确的。我还提到我在登录时也在使用电子邮件发送功能,当时它正在工作,但是在发送附件时,它没有 【参考方案1】: 推荐的答案 Twilio

这里是 Twilio SendGrid 开发人员宣传员。

使用 Gmail 地址作为您的发件人地址并不是让您的电子邮件送达的好方法。这样做意味着您正在欺骗一个电子邮件地址,即使它是您的电子邮件地址。

当您像这样欺骗电子邮件地址时,电子邮件服务器无法证明它有权为该地址发送电子邮件。 SPF 和 DKIM 是您可以用来证明您控制了电子邮件来自的域的方法,但是当您使用 Gmail 地址(或任何其他邮箱提供商)时,您似乎是在欺骗和接收邮箱可能选择丢弃您的电子邮件或将它们放入垃圾邮件收件箱。

您可能已经设法使用此方法发送和接收您的帐户创建电子邮件,但邮箱提供商在接收带有附加 zip 文件的电子邮件时会受到更多限制。整个事情看起来很可疑,邮箱可能会拒绝它、发送垃圾邮件或默默删除它。

这里的建议只是don't send emails from a domain that you don't control。您应该做的是获得一个您想从中发送电子邮件的域,set up domain authentication for that domain,与欺骗 Gmail 相比,您将更有可能将电子邮件放入用户的收件箱。

【讨论】:

以上是关于在“nodejs”中使用“@sendgrid/mail”发送“base64”电子邮件“附件”时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Nodejs 中使用 document.getElementById()

如何在nodejs中使用facebook登录

不要在nodejs中阻塞event loop

Codeigniter在nodejs中读取会话cookie

如何在 Windows 7 中使用 Nodejs? [关闭]

在nodejs中使用--user选项卷曲