如何使用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;
    }
})();
相关推荐
拖拉斯旋风7 分钟前
从零开始:使用 Ollama 在本地部署开源大模型并集成到 React 应用
前端·javascript·ollama
德育处主任16 分钟前
『NAS』在群晖部署图片压缩工具-Squoosh
前端·javascript·docker
Van_captain2 小时前
rn_for_openharmony常用组件_Breadcrumb面包屑
javascript·开源·harmonyos
静听松涛1332 小时前
提示词注入攻击的防御机制
前端·javascript·easyui
澄江静如练_2 小时前
优惠券提示文案表单项(原生div写的)
前端·javascript·vue.js
C_心欲无痕2 小时前
ts - 关于Object、object 和 {} 的解析与区别
开发语言·前端·javascript·typescript
全栈前端老曹2 小时前
【包管理】read-pkg-up 快速上手教程 - 读取最近的 package.json 文件
前端·javascript·npm·node.js·json·nrm·package.json
故乡de云2 小时前
Google Cloud与AWS大数据AI服务对比:2026年企业选型指南
大数据·人工智能·aws
JQLvopkk3 小时前
Vue框架技术详细介绍及阐述
前端·javascript·vue.js
笔COOL创始人3 小时前
requestAnimationFrame 动画优化实践指南
前端·javascript·面试