如何使用AWS的SES服务发送邮件和40M的附件

背景介绍

SMTP协议

SMTP(Simple Mail Transfer Protocol):简单邮件传送协议

  • STMP端口号为25, 使用TCP建立连接.
  • SMTP限于传送7位的ASCII码

MIME协议

MIME (Multipurpose Internet Mail Extension)

flowchart LR A1[user1] <-- 不止7位ASCII码 --> B1[MIME] B1 <-- 7位ASCII码 --> C1[SMTP] C1 <-- 7位ASCII码 --> C2[SMTP] C2 <-- 7位ASCII码 --> B2[MIME] B2 <-- 不止7位ASCII码 --> A2[user2]

前置条件

  1. 首先要有一个AWS的账户,并且SES服务可以正常使用。
  2. 在SES服务中,提前verified 要使用的email

Overview

SES的三种发送邮件的方式

SES本身有三种发送邮件的方式,如下图所示:

flowchart LR SES --> B1["1. 直接发送邮件内容"] SES --> B2["2. 发送邮件内容和附件,包括但不限于 txt,csv,pdf,image..."] SES --> B3["3. 使用template发送邮件"]

在这里,我们主要讨论的是带附件的邮件的发送。

SES V1 和 V2 对于附件大小的限制

ses v1 ses v2
附件大小的限制 10M 40M

附件类型的定义

  • Content-Type: application/octet-stream ===> attachment.pdf
  • Content-Type: application/json ===> attachment.json
  • Content-Type: application/msword ===>attachment.docx
  • Content-Type: text/plain ===> attachment.txt

方法一: 使用AWS SES V1版本发送邮件和附件

使用 ses v1 发送邮件和附件,附件的限制大小是 10M.

1. 定义 payload

  • 使用 boundary 来分割大文件部分
  • boundary 可以级联 sub boundary
js 复制代码
// define file
let file = fs.readFileSync('./src/util/testData.csv',
    {encoding:'base64', flag:'r'}
);

// define payload
const payload = `From: ${email}
To: ${email}
Subject: Customer service contact info
Content-Type: multipart/mixed;
    boundary="a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: multipart/alternative;
    boundary="sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Please see the attached file for a list of customers to contact.

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

<html>
<head></head>
<body>
<h1>Hello!</h1>
<p>Please see the attached file for a list of customers to contact.</p>
</body>
</html>

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/plain; name="attachment.csv"
Content-Description: attachment.csv
Content-Disposition: attachment;filename="attachment.csv";
    creation-date="Sat, 05 Aug 2017 19:35:36 GMT";
Content-Transfer-Encoding: base64

${file}

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--
`;

2.发送邮件

js 复制代码
import * as AWS from "@aws-sdk/client-ses";
import fs from "fs";
const client = new AWS.SES();

const email = "test@test.com.cn";

(async () => {
    const params = {
        RawMessage: {
            Data: Buffer.from(payload)
        },
        Source: email,
        Destinations: [],
    };

    try {
        return await client.sendRawEmail(params);
    } catch (e) {
        console.error(e);
        console.error("Failed to send email.");
        return e;
    }
})();

方法二: 使用AWS SES V2版本发送邮件和附件

使用 ses v2 发送邮件和附件,附件的限制大小是 40M.

实现代码

js 复制代码
import fs from "fs";
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2"
const client = new SESv2Client();

const email = "test@test.com.cn";

let file = fs.readFileSync('./src/util/testData.csv',
    {encoding:'base64', flag:'r'}
);

const payload = `From: ${email}
To: ${email}
Subject: Customer service contact info
Content-Type: multipart/mixed;
    boundary="a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: multipart/alternative;
    boundary="sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a"

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

Please see the attached file for a list of customers to contact.

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable

<html>
<head></head>
<body>
<h1>Hello!</h1>
<p>Please see the attached file for a list of customers to contact.</p>
</body>
</html>

--sub_a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a
Content-Type: text/plain; name="attachment.csv"
Content-Description: attachment.csv
Content-Disposition: attachment;filename="attachment.csv";
    creation-date="Sat, 05 Aug 2017 19:35:36 GMT";
Content-Transfer-Encoding: base64

${file}

--a3f166a86b56ff6c37755292d690675717ea3cd9de81228ec2b76ed4a15d6d1a--
`;


(async () => {
    const command = new SendEmailCommand({
        Content: {
            Raw: {
                Data: Buffer.from(payload)
            }
        },
        Destination: {
            ToAddresses: [email],
        },
    });

    try {
        return await client.send(command);
    } catch (e) {
        console.error(e);
        console.error("Failed to send email.");
        return e;
    }
})();
相关推荐
Cacciatore->1 小时前
Electron 快速上手
javascript·arcgis·electron
vvilkim1 小时前
Electron 进程间通信(IPC)深度优化指南
前端·javascript·electron
某公司摸鱼前端2 小时前
ES13(ES2022)新特性整理
javascript·ecmascript·es13
清幽竹客3 小时前
vue-30(理解 Nuxt.js 目录结构)
前端·javascript·vue.js
weiweiweb8883 小时前
cesium加载Draco几何压缩数据
前端·javascript·vue.js
我不吃饼干9 天前
鸽了六年的某大厂面试题:你会手写一个模板引擎吗?
前端·javascript·面试
我不吃饼干9 天前
鸽了六年的某大厂面试题:手写 Vue 模板编译(解析篇)
前端·javascript·面试
AWS官方合作商9 天前
AWS ACM 重磅上线:公有 SSL/TLS 证书现可导出,突破 AWS 边界! (突出新功能的重要性和突破性)
服务器·https·ssl·aws
前端fighter9 天前
为什么需要dependencies 与 devDependencies
前端·javascript·面试
满楼、9 天前
el-cascader 设置可以手动输入也可以下拉选择
javascript·vue.js·elementui