ToolJet 接入 Amazon SES 数据源:连接配置、鉴权模式与 Email service 发信操作全解析
Amazon SES(Simple Email Service)是 AWS 提供的邮件发送服务。在 ToolJet 中,Amazon SES 以一个官方数据源(datasource)插件的形式存在,核心能力是让应用内构建的数据查询直接调用 SES 发送邮件——例如在按钮事件、表单提交或工作流中触发通知邮件。阅读本篇后,你将掌握在 ToolJet 中建立 Amazon SES 连接的完整步骤、三种 AWS 鉴权方式的选择,以及通过 Email service 操作向单个或多个收件人发送 HTML 邮件的具体写法与底层实现原理。
本文以 docs/docs/data-sources/amazonses.md 官方文档为主体,并结合作者对应的插件源码(位于 plugins/packages/amazonses)逐层展开。
Amazon SES 数据源在 ToolJet 中扮演什么角色
在 ToolJet 中接入 Amazon SES 后,你能在查询面板中选中该数据源并执行 Email service(邮件服务) 操作,向指定地址发送邮件。底层实现并不由 ToolJet 自行模拟,而是调用 AWS 官方 SDK @aws-sdk/client-sesv2 完成真实发信,这一点可以从插件依赖与执行代码中得到印证。
插件 @tooljet-plugins/amazonses 的运行时依赖仅包含三类 AWS SDK 模块,见 plugins/packages/amazonses/package.json:
@aws-sdk/client-sesv2:SES v2 API 客户端,负责组装并发送邮件;@aws-sdk/client-sts:在选用 ARN 角色鉴权时,用于临时换取角色凭证;@aws-sdk/credential-providers:在选用 EC2 实例元数据凭证时使用。
SES 插件所声明的能力与许多邮件服务插件(如 sendgrid、mailgun、smtp)类似,但鉴权体系与 Amazon 生态深度绑定,因此连接配置也带有明显的 AWS 风格。
建立与 Amazon SES 的连接
要建立 Amazon SES 连接,有两种入口,任选其一即可:
- 点击查询面板上的 + Add new Data source 按钮;
- 通过 ToolJet 仪表盘导航到 Data Sources(数据源) 页面进行统一管理。
必需配置项
根据官方文档与 manifest.json 中定义的 required 字段(access_key、secret_key、region),连接时需提供:
| 配置项 | 说明 |
|---|---|
| Region | SES 所在的 AWS 区域(下拉选择,默认值可见于 defaults 段) |
| Authentication | 鉴权方式:Use IAM Access Keys / Use AWS Instance Credentials / Use AWS ARN Role(默认 iam_access_keys) |
| Access key | IAM 用户的访问密钥 ID(仅 IAM Access Keys 方式需要) |
| Secret key | IAM 用户的访问密钥(仅 IAM Access Keys 方式需要,存储时加密) |
安全建议(官方文档原文提示):强烈建议为该数据源单独创建一个 IAM 用户,而不是直接使用拥有过高权限的根账号或管理员密钥,以便精确控制 ToolJet 对 SES 的访问范围。
区域下拉支持的范围
Region 并非自由输入,而是从 commonFields.region.list 中预置的下拉选项,覆盖了 SES 可用的主流区域(详见 manifest.json),例如:
us-east-1(US East, N. Virginia)、us-east-2(US East, Ohio)、us-west-1、us-west-2eu-central-1(Frankfurt)、eu-west-1(Ireland)、eu-west-2(London)、eu-north-1(Stockholm)ap-south-1(Mumbai)、ap-southeast-1(Singapore)、ap-southeast-2(Sydney)、ap-northeast-1(Tokyo)、ap-northeast-2(Seoul)sa-east-1(São Paulo)、ca-central-1、cn-north-1/cn-northwest-1(中国区)、me-south-1(Bahrain)以及us-gov-east-1/us-gov-west-1(AWS GovCloud)
选择区域时,应确保与 SES 控制台中已配置(完成发信身份验证)的账号、域名所属区域一致。
三种鉴权方式的实现差异
ToolJet 的 SES 连接支持三种鉴权策略,体现在连接表单中 "Authentication" 下拉的 iam_access_keys、aws_instance_credentials、aws_arn_role 三个选项。其底层逻辑在 index.ts 的 getConnection 方法 中一分为三:
- Use IAM Access Keys(默认):直接使用用户填写的
access_key/secret_key构建SESv2Client,这是最通用的自管理凭证方案。 - Use AWS Instance Credentials:当 ToolJet 本身运行在 EC2 实例(或具备 IAM 角色的计算环境)上时,调用
fromInstanceMetadata()自动从实例元数据服务获取角色凭证,无需在界面中填写任何密钥。 - Use AWS ARN Role:填写一个角色 ARN(例如
arn:aws:iam::123456789012:role/role-name),插件会通过 STS 的AssumeRoleCommand换取临时凭证(AccessKeyId、SecretAccessKey、SessionToken)后建立客户端。换取的RoleSessionName由源码拼接为s3-${roleName}-${timestamp}形式,见 index.ts。
需要注意的是,manifest.json 的 required 列表仍声明了 access/secret key,但三种方式的字段是否展示由下拉联动控制,实际代码按上述分支各自建连,因此 Instance Credentials 与 ARN Role 模式下并不强制要求 IAM 密钥。
通过查询管理器触发 SES 发信
连接建立后即可编写查询。操作步骤如下:
- 在编辑器底部的查询管理器中点击 + Add 按钮;
- 在数据源下拉中选择上一步添加的 Amazon SES;
- 在操作(Operation)下拉中选择 Email service,并填写所需参数;
- 点击 Preview 预览输出,或点击 Run 立即触发查询。
查询执行链路与结果变量
选中查询并运行时,ToolJet 会调用插件类 AmazonSES 的 run 方法。整个执行过程可拆解为(见 index.ts):
- 依据连接时保存的
sourceOptions调用getConnection建立SESv2Client; - 把查询面板中的字段拼装为 AWS SES v2 的
SendEmailCommandInput; - 通过
client.send(command)真实发信; - 成功时返回
{ status: 'ok', data: res },失败时抛出包装后的QueryError('Query could not be completed', ...),便于在 UI 中呈现错误原因。
每次查询执行后,SES 查询会自动向外暴露 isLoading、data、rawData 三个变量(由 manifest.json 的 exposedVariables 声明),可在应用的其他位置引用查询结果或加载状态。
Email service:唯一支持的操作及其参数
Amazon SES 数据源当前只支持一个操作 —— Email service,对应内部枚举值 mail_service(见 operations.json 中 operation.list)。
必填参数
- Send email to:收件人地址;
- Send email from:发件人地址(需为 SES 已验证的发信身份,如已验证域名下的地址);
- Subject:邮件主题;
- Body:邮件正文。
可选参数
- CC Addresses(抄送)
- BCC Addresses(密送)
参数与 SES API 字段的映射关系
UI 中的每个参数字段都会映射到 SES v2 SendEmailCommand 的对应结构,完整映射可以从 index.ts 的 SendEmailCommandInput 拼装段 中直接读到:
| 界面参数(operations.json 字段) | SES 请求字段 | 取值规则 |
|---|---|---|
Send mail to(send_mail_to) |
Destination.ToAddresses |
字符串数组,支持多个收件人 |
CC mail to(cc_to) |
Destination.CcAddresses |
字符串数组 |
BCC mail to(bcc_to) |
Destination.BccAddresses |
字符串数组 |
Send mail from(send_mail_from) |
FromEmailAddress |
单个字符串 |
Subject(subject) |
Content.Simple.Subject.Data |
字符串 |
Body(body) |
Content.Simple.Body.Html.Data |
HTML 字符串,编码固定为 UTF-8 |
另外,插件类型定义 QueryOptions 中还存在 reply_to(回复地址,见 types.ts),源码将其映射为 ReplyToAddresses。由于当前 operations.json 的 mail_service 并未向 UI 暴露该输入框,可推断该字段在当前版本属于预留能力,UI 直接可见的输入以必填四项与 CC/BCC 为主。
收件人字段的数组语法
Send mail to 支持一次发送给多个收件人,字段类型为 codehinter(代码输入器),意味着它可以写死、引用组件值或使用模板字符串求值。官方文档给出的推荐写法是数组形式:
{{["dev@tooljet.io", "admin@tooljet.io"]}}
两种需要区分理解的语义:
- 一个数组 = 一封邮件:
Send mail to内放入一个包含多个地址的数组,SES 会把这封邮件的全部收件人都放进ToAddresses,即"一封群发邮件,所有收件人可见彼此"; - 多个独立的单收件人邮件:如需每个收件人看到单独的收件人列表(相互不可见),应逐次构造并运行查询(每次一个字符串地址),而不是把多个地址放进同一个数组。
由于 CC/BCC 同样接受数组,若需要"一人可见、他人密送"的混合场景,可将可见收件人放入
Send mail to、抄送放入cc_to、隐藏收件人放入bcc_to。
Body 支持 HTML
body 字段在 operations.json 中标注为 "Supports HTML",源码也将其写入 Body.Html.Data 而非纯文本字段。因此可以在正文中直接使用 <p>、<a>、<strong> 等标签拼装富文本邮件,例如:
{{"<h3>欢迎使用 ToolJet</h3><p>这是一封由 Amazon SES 发送的测试邮件,点击 <a href='https://tooljet.com'>这里</a> 了解更多。</p>"}}
若邮件无需排版,也可仅输出纯文本内容,SES 仍会将其作为 HTML 正文投递。
在真实应用中的典型用法
将 SES 查询与事件联动即可构建"业务动作完成后自动发信"的流程,常见做法包括:
- 表单提交通知:在表单组件按钮的点击事件中触发 SES 查询,
Send mail to引用表单里的邮箱字段; - 审批/状态流转提醒:在表格行按钮的事件处理器里,用
{{globals.currentRow.email}}(视具体组件而定)动态带出当前行用户作为收件人; - 批量运营通知:配合循环查询或按数据集逐行触发,将数组收件人拆分为多条独立邮件。
由于所有字段均为代码输入器,可使用 {{queries.<queryName>.data}} 等查询间引用串联数据。每次查询执行后 data、rawData、isLoading 变量可供后续步骤读取。
注意事项与故障排查提示
- 发信身份必须完成验证:SES 要求
FromEmailAddress属于已验证的邮箱或域名,否则请求会被 AWS 拒绝;这与 ToolJet 插件本身无关,属于 SES 服务侧的账号级要求。 - IAM 权限最小化:建议为专用 IAM 用户仅授予发信所需的 SES 操作权限,避免使用管理级权限。官方文档亦明确提示为数据库/数据源单独创建受控 IAM 用户。
- 沙箱模式限制:SES 新账号默认处于沙箱模式,只能向已验证地址发信且存在配额限制,需要在 AWS 控制台申请出沙箱后才能大规模投递。
- 错误信息定位:查询失败时,插件会抛出
Query could not be completed并将 AWS 原始error.message一并带出,可在查询运行结果面板查看具体原因(如AccessDenied、MessageRejected、区域不匹配等)。 - 区域一致性:Region 必须与 SES 发信身份所在区域一致,并确保数据源连接时选择的区域与查询实际命中的 SES 端点对应。
源码地图:快速定位 SES 插件的关键文件
若希望进一步研究该数据源的实现,可按如下路径阅读(仓库根目录相对路径):
| 关注点 | 文件 |
|---|---|
| 连接与发信核心逻辑 | plugins/packages/amazonses/lib/index.ts |
| 数据源配置结构(区域下拉、鉴权选项、必填项) | plugins/packages/amazonses/lib/manifest.json |
| 查询操作的表单定义(参数类型、placeholder、是否支持 HTML) | plugins/packages/amazonses/lib/operations.json |
| 连接/查询参数的类型定义 | plugins/packages/amazonses/lib/types.ts |
| 运行时依赖(AWS SDK 版本等) | plugins/packages/amazonses/package.json |
| 官方数据源文档 | docs/docs/data-sources/amazonses.md |
关于插件测试,plugins/packages/amazonses/tests/index.js 目前仅保留了 it.todo 占位用例,尚未覆盖实际发信断言,这也意味着在接入真实 SES 凭据前,建议先在 UI 中通过 Preview 验证参数拼装是否符合预期。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
video-shotcraftAI宣传片skill,使用 Remotion 制作电影级产品视频:提供106 张镜头配方卡和可复用的视频魔板。适用于 Claude Code 与 Codex以及所有其他智能体Markdown00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00


