带有附件的电子邮件无法通过 gmail 正常发送 api
Email with attachment is not going properly with gmail api
这是我在 node.js 中编写的以下代码,用于使用 gmail api 发送带附件的电子邮件:
我正在使用节点 js 的请求承诺模块向 api 发送请求。
let user = await db.model('User').findOne({ _id: userId });
let filepath = fs.readFileSync(req.file.path).toString('base64');
// let filepath = fs.readFileSync(req.file.path);
let from = user.crmOptions.email;
let raw = [
'Content-Type: multipart/mixed; boundary="boundary_mail"\r\n',
'MIME-Version: 1.0\r\n',
"to: ", req.body.to, "\n",
"from: ", from, "\n",
"cc: ", req.body.cc ? req.body.cc : '', "\n",
"bcc: ", req.body.bcc ? req.body.bcc : '', "\n",
"subject: ", req.body.subject, "\n\n",
'--boundary_mail\r\n',
"Content-Type: text/html; charset=\"UTF-8\"\n",
'MIME-Version: 1.0\r\n',
req.body.message,
'--boundary_mail\r\n',
`Content-Type: ${req.file.mimetype}\r\n`,
'MIME-Version: 1.0\r\n',
`Content-Disposition: attachment; filename="${req.file.filename}"\r\n\r\n`,
filepath, '\r\n\r\n',
'--boundary_mail--'
].join('');
const id = 'me';
let options = {
url: "https://www.googleapis.com/upload/gmail/v1/users/" + id + "/messages/send?uploadType=multipart",
method: 'POST',
headers: {
'Authorization': `Bearer ${user.crmOptions.access_token}`,
'Content-Type': 'message/rfc822'
},
body: raw
};
await request(options).then(async body => {
console.log("Body: ", body);
}).catch(err => {
console.log("Error: ", err);
})
发送邮件后邮件内容是这样的
发送html邮件和附件时,使用multipart/mixed
和multipart/alternative
。请求体结构如下
- multipart/mixed
- multipart/alternative
- html 留言
- 附件文件
当时在请求体中使用了2个边界
修改后的脚本:
请修改raw
如下。
let raw = [
'MIME-Version: 1.0\n',
"to: ", req.body.to, "\n",
"from: ", from, "\n",
"cc: ", req.body.cc ? req.body.cc : '', "\n",
"bcc: ", req.body.bcc ? req.body.bcc : '', "\n",
"subject: ", req.body.subject, "\n",
"Content-Type: multipart/mixed; boundary=boundary_mail1\n\n",
"--boundary_mail1\n",
"Content-Type: multipart/alternative; boundary=boundary_mail2\n\n",
"--boundary_mail2\n",
"Content-Type: text/html; charset=UTF-8\n",
"Content-Transfer-Encoding: quoted-printable\n\n",
req.body.message, "\n\n",
"--boundary_mail2--\n",
'--boundary_mail1\n',
`Content-Type: ${req.file.mimetype}\n`,
`Content-Disposition: attachment; filename="${req.file.filename}"\n`,
"Content-Transfer-Encoding: base64\n\n",
filepath, '\n',
'--boundary_mail1--',
].join('');
注:
- 在此修改后的脚本中,假设您当前的脚本可以使用 Gmail 发送电子邮件 API。
参考文献:
编辑:
例如,当请求正文中包含2个附件时,请将--boundary_mail1
修改为--boundary_mail1--
如下。请注意是否有重复的文件名。
发件人:
'--boundary_mail1\n',
`Content-Type: ${req.file.mimetype}\n`,
`Content-Disposition: attachment; filename="${req.file.filename}"\n`,
"Content-Transfer-Encoding: base64\n\n",
filepath, '\n',
'--boundary_mail1--',
收件人:
'--boundary_mail1\n',
`Content-Type: mimetype\n`, // mimetype
`Content-Disposition: attachment; filename="### filename1 ###"\n`, // filename1
"Content-Transfer-Encoding: base64\n\n",
filepath1, '\n', // filepath1
'--boundary_mail1\n',
`Content-Type: mimetype\n`, // mimetype
`Content-Disposition: attachment; filename="### filename2 ###"\n`, // filename2
"Content-Transfer-Encoding: base64\n\n",
filepath2, '\n', // filepath2
'--boundary_mail1--',
这是我在 node.js 中编写的以下代码,用于使用 gmail api 发送带附件的电子邮件:
我正在使用节点 js 的请求承诺模块向 api 发送请求。
let user = await db.model('User').findOne({ _id: userId });
let filepath = fs.readFileSync(req.file.path).toString('base64');
// let filepath = fs.readFileSync(req.file.path);
let from = user.crmOptions.email;
let raw = [
'Content-Type: multipart/mixed; boundary="boundary_mail"\r\n',
'MIME-Version: 1.0\r\n',
"to: ", req.body.to, "\n",
"from: ", from, "\n",
"cc: ", req.body.cc ? req.body.cc : '', "\n",
"bcc: ", req.body.bcc ? req.body.bcc : '', "\n",
"subject: ", req.body.subject, "\n\n",
'--boundary_mail\r\n',
"Content-Type: text/html; charset=\"UTF-8\"\n",
'MIME-Version: 1.0\r\n',
req.body.message,
'--boundary_mail\r\n',
`Content-Type: ${req.file.mimetype}\r\n`,
'MIME-Version: 1.0\r\n',
`Content-Disposition: attachment; filename="${req.file.filename}"\r\n\r\n`,
filepath, '\r\n\r\n',
'--boundary_mail--'
].join('');
const id = 'me';
let options = {
url: "https://www.googleapis.com/upload/gmail/v1/users/" + id + "/messages/send?uploadType=multipart",
method: 'POST',
headers: {
'Authorization': `Bearer ${user.crmOptions.access_token}`,
'Content-Type': 'message/rfc822'
},
body: raw
};
await request(options).then(async body => {
console.log("Body: ", body);
}).catch(err => {
console.log("Error: ", err);
})
发送邮件后邮件内容是这样的
发送html邮件和附件时,使用multipart/mixed
和multipart/alternative
。请求体结构如下
- multipart/mixed
- multipart/alternative
- html 留言
- 附件文件
- multipart/alternative
当时在请求体中使用了2个边界
修改后的脚本:
请修改raw
如下。
let raw = [
'MIME-Version: 1.0\n',
"to: ", req.body.to, "\n",
"from: ", from, "\n",
"cc: ", req.body.cc ? req.body.cc : '', "\n",
"bcc: ", req.body.bcc ? req.body.bcc : '', "\n",
"subject: ", req.body.subject, "\n",
"Content-Type: multipart/mixed; boundary=boundary_mail1\n\n",
"--boundary_mail1\n",
"Content-Type: multipart/alternative; boundary=boundary_mail2\n\n",
"--boundary_mail2\n",
"Content-Type: text/html; charset=UTF-8\n",
"Content-Transfer-Encoding: quoted-printable\n\n",
req.body.message, "\n\n",
"--boundary_mail2--\n",
'--boundary_mail1\n',
`Content-Type: ${req.file.mimetype}\n`,
`Content-Disposition: attachment; filename="${req.file.filename}"\n`,
"Content-Transfer-Encoding: base64\n\n",
filepath, '\n',
'--boundary_mail1--',
].join('');
注:
- 在此修改后的脚本中,假设您当前的脚本可以使用 Gmail 发送电子邮件 API。
参考文献:
编辑:
例如,当请求正文中包含2个附件时,请将--boundary_mail1
修改为--boundary_mail1--
如下。请注意是否有重复的文件名。
发件人:
'--boundary_mail1\n',
`Content-Type: ${req.file.mimetype}\n`,
`Content-Disposition: attachment; filename="${req.file.filename}"\n`,
"Content-Transfer-Encoding: base64\n\n",
filepath, '\n',
'--boundary_mail1--',
收件人:
'--boundary_mail1\n',
`Content-Type: mimetype\n`, // mimetype
`Content-Disposition: attachment; filename="### filename1 ###"\n`, // filename1
"Content-Transfer-Encoding: base64\n\n",
filepath1, '\n', // filepath1
'--boundary_mail1\n',
`Content-Type: mimetype\n`, // mimetype
`Content-Disposition: attachment; filename="### filename2 ###"\n`, // filename2
"Content-Transfer-Encoding: base64\n\n",
filepath2, '\n', // filepath2
'--boundary_mail1--',