如何使用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;
    }
})();
相关推荐
大今野11 分钟前
node.js和js
开发语言·javascript·node.js
ᥬ 小月亮18 分钟前
Js前端模块化规范及其产品
开发语言·前端·javascript
码小瑞33 分钟前
某些iphone手机录音获取流stream延迟问题 以及 录音一次第二次不录音问题
前端·javascript·vue.js
半吊子伯爵36 分钟前
开发过程优化·自定义鼠标右键菜单
前端·javascript·自定义鼠标右键菜单
Tirzano1 小时前
vue3 ts 简单动态表单 和表格
前端·javascript·vue.js
程序员_三木1 小时前
使用 Three.js 创建圣诞树场景
开发语言·前端·javascript·ecmascript·three
赵大仁2 小时前
深入理解 Vue 3 中的具名插槽
前端·javascript·vue.js·react.js·前端框架·ecmascript·html5
秋雨凉人心9 小时前
简单发布一个npm包
前端·javascript·webpack·npm·node.js
哥谭居民000111 小时前
将一个组件的propName属性与父组件中的variable变量进行双向绑定的vue3(组件传值)
javascript·vue.js·typescript·npm·node.js·css3
踢足球的,程序猿11 小时前
Android native+html5的混合开发
javascript