@dbx-tools/电子邮件
添加由人批准、发送政策、 SMTP 交付和 a 等模式起草的电子邮件 本地开发发包到 AppKit 或 Mastra 后端 。 浏览器安全消息 和结果的计谋 @dbx-tools/ 共享电子邮件电子邮件 演示文稿 @dbx-tools/ 共享电子邮件模板。 。 。 .
快开始
给代理服务器一个在发送前暂停的电子邮件工具 :
import { emailTool } from "@dbx-tools/email";
import { agents } from "@dbx-tools/appkit-mastra";
const support = agents.createAgent({
instructions: "Draft the reply and request approval before sending it.",
tools: () => ({ send_email: emailTool() }),
});
软件包 :
- 解决配置的 AppKit 插件注册,在启动时验证 SMTP,以及 挂载发送者选项路由.
- 两个特工在一次运行中浮出水面:一个马斯特拉
send_email暂停的工具 人类认可, 和AppKitemail.send工具标记为写入 东道主的审批门起火. - SMTP 供生产和 HTML 发货箱供当地开发 和测试.
- 来自当前 Databricks 用户的发件人 :
EMAIL_DOMAIN独自一人 足够,有固定EMAIL_FROM作为一种压倒性而非要求. - 系统邮件的单独 do- not reply发件人(
no-reply@<domain>,或EMAIL_SYSTEM_FROM),在没有用户范围时自动使用. - 拒绝默认发送方政策,并附有准确的地址、域、域通配符、,
和一个名字
unrestricted逃出舱门. - 使用响应组件对电子邮件进行反应渲染,匹配 HTML/Plain-text 选项、元数据、附件摘要和默认的 dbx 工具品牌.
- 在身体长度和附件大小上命名了盖子,以及
AbortSignal线程 通过每一个发送.
提供登记册
import { createApp, lakebase, server } from "@databricks/appkit";
import { email, emailTool } from "@dbx-tools/email";
import { agents, mastra } from "@dbx-tools/appkit-mastra";
const support = agents.createAgent({
instructions: "Draft emails, but wait for approval before sending.",
tools: () => ({ send_email: emailTool() }),
});
await createApp({
plugins: [
server(),
lakebase(),
email({
smtp: { host: "smtp.example.com", user: "apikey", password: process.env.SMTP_KEY },
domain: "mail.example.com",
}),
mastra({ agents: support, storage: true }),
],
});
plugin.email() 验证配置、 质数共享运行时间、 验证 SMTP 时
SMTP 模式已激活, 并挂载 UIs 的发件人- 选项路由 。 无法校验
设置失败, 所以一个糟糕的主机或证书 出现在靴子日志中而不是打开
第一个批准发送。 出箱模式跳过检查并登录一个警告.
tool.emailTool() 创建批准马斯特拉 send_email 工具。 核准
需要 Mastra 存储, 所以注册 lakebase() 或明确配置存储
在 Mastra 插件中.
emailTool({ requireApproval }) 也接受 Mastra 的本地条件
核准职能。 用马斯特拉 Classifier 或耐用、用户范围
指纹政策在以前审查过的电话中应减少未来的提示:
const sendEmail = emailTool({
requireApproval: async (input, { requestContext } = {}) =>
approvalPolicy.requiresReview({
input,
userId: requestContext?.["mastra__resourceId"],
}),
});
回调 true 当仍然需要人检讨时 false
当 Mastra 可能运行工具时。 保险单没结清 普通马斯特拉特工不
提供内置耐用"记住这个批准"商店. 代理主计长
权限规则是单独的运行时间, 因此此软件包不会模仿它们
客户端.
插件不决定如何提交批准 。 它释放出一个 Mastra 工具 并期望主机 UI 以批准或 拒绝结果. @dbx-tools/ui/电子邮件 提供匹配 批准卡和构件.
配置
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
smtp.host | string | SMTP_HOST | SMTP 服务器主机名 。 放弃整个 smtp 块,以发件箱模式运行. |
smtp.port | number | SMTP_PORT,则 587 | SMTP 服务器端口. |
smtp.secure | boolean | SMTP_SECURE,则 port === 465 | TLS-上接接接接接接头,而不是STATLS. |
smtp.user | string | SMTP_USER | SMTP 认证用户名 . |
smtp.password | string | SMTP_PASSWORD | SMTP 认证密码或 API 密钥 . |
domain | string | EMAIL_DOMAIN | 域域发送者来源于 <user-local-part>@<domain>。 。 。 . |
from | string | EMAIL_FROM | 可选固定 From。跳过每个用户的衍生. |
systemFrom | string | EMAIL_SYSTEM_FROM,则 no-reply@<domain> | From 用于系统邮件(范围中没有用户). |
senderPolicy | "allowlist" | "unrestricted" | EMAIL_SENDER_POLICY,则 "allowlist" | 当 allowedSenders 为空. |
allowedSenders | string | string[] | EMAIL_ALLOWED_SENDERS | 允许 From 模式:确切地址, *@domain一个赤裸的 domain,或 *。 。 。 . |
outDir | string | EMAIL_OUTBOX_DIR,则 <cwd>/tmp | 目录发件箱会写入 HTML 预览 . |
brand | EmailBrand | dbx-工具品牌 | 彩色,字体,显示名称,页脚,以及可选的标志都应用于每个消息. |
每个字段的优先权是明确的配置,然后是环境变量,然后是 内建默认值.
| 环境变量 | 目的 |
|---|---|
SMTP_HOST | SMTP 服务器主机名 . |
SMTP_PORT | SMTP 服务器端口. |
SMTP_SECURE | 强制或禁用连接的 TLS 套接字 . |
SMTP_USER | SMTP 认证用户名 . |
SMTP_PASSWORD | SMTP 认证密码或 API 密钥 . |
EMAIL_DOMAIN | 获取的发送地址域 . |
EMAIL_FROM | 可选固定 From 地址,压倒每个用户的衍生. |
EMAIL_SYSTEM_FROM | From 系统邮件。 默认为 no-reply@<domain>。 。 。 . |
EMAIL_SENDER_POLICY | allowlist (违约)或 unrestricted。 。 。 . |
EMAIL_ALLOWED_SENDERS | 逗号或空白分隔 From 许可列表 . |
EMAIL_OUTBOX_MODE | 当 SMTP 未配置时, 选择写入信件到磁盘 . |
EMAIL_OUTBOX_DIR | 发件箱预览目录 . |
这个 SMTP_* 由于 SMTP 是第三方服务,而非
数据砖资源.
无代理发送
import { transport } from "@dbx-tools/email";
const result = await transport.sendEmail(
{
to: ["[email protected]"],
cc: ["[email protected]"],
subject: "Daily report",
body: "# Report\nEverything completed.",
attachments: [{ filename: "report.csv", content: "a,b\n1,2\n" }],
},
"[email protected]",
);
使用直接发送进行操作邮件、测试或管理流程,如果一个模型不是
参与。 AppKit 插件和两个代理都使用相同的解析运行时间
工具,所以每个路径共享一个连接池,一个发送策略,和一个集
盖子 第三个论点接受 AbortSignal 当打电话者想停止
等着SMTP.
控制可见标题
HTML卡通常会将运输主题重复为标题. 设定
heading 当主题包含不应包含的通知特定背景时
在打开的消息中重复:
await transport.sendEmail(message, from, undefined, {
heading: "Verification code",
});
这样在收件箱和通知中保持一个带有代码的主题有用,而 HTML正文给出了一次代码.
控制纯文本部分
默认两个 MIME 替代品都是从一个 React Email 树中生成的,所以
text/plain 部分是 HTML 的渲染。 它带有品牌头和
页脚, CSS 差值变为空行 。 说不说就是对的
对于客户端描述的内容。 第四个论点仅取代这一部分,
将标有的 HTML 保留在原地 :
await transport.sendEmail(message, from, undefined, {
text: `Your verification code is: ${code}\nThis code expires in 10 minutes.`,
});
动机案例为一次性代码:客户端代码检测读取代码
和样式 <h2> 代码使以下两行为空白
快速, 所以自动填充会停止提供, 尽管 HTML 使正确 .
保留两部分相同的信息。 垃圾邮件过滤器可以处理文本
选项,它与 HTML 作为钓鱼方式不一致。 见
@dbx-tools/隧道 为了一个能做到这一点的大门.
控制前标(和推出通知)
相同的选项对象需要 a preview,前标题: 片断客户端
在收件箱列表中显示主题旁边,并显示驱动通知的正文
一个移动邮件应用程序。 默认为主体.
await transport.sendEmail(message, from, undefined, {
preview: `Your verification code is: ${code}`,
});
电话从通知中读出 而不是从.. 打开消息。 移动一次性编码自动填充就是一个例子:通知 带发件人,主题,和这个片段, 所以一个代码只出现在 尸体从不提供。 把重要文字放在主题和前题 身体变成人所读取的, 而不是一个高压的依赖.
插件导出等同, 并在调用时为您解决发送者 是 Databricks 用户 :
const appkit = await createApp({ plugins: [server(), email()] });
await appkit.email.sendEmail(message, "[email protected]");
如何发送到 AppKit 截取器
每个发送都通过 AppKit 的截取链(出时、遥测和
重试/ 缓存姿态 defaults),包括来自Mastra工具的函件,该工具
范围中没有插件实例。 运行时间包含此执行器槽 :
注册插件安装它自己的 Plugin.execute() 那里有布置,和
sendEmail() 任何安装的线路.
这有两个影响:
- 在一个没有注册 AppKit 插件的平版 Mastra app 中,槽会回到 直接运行发送,所以工具仍然在没有截取器的情况下工作.
- 接受、封顶和发送政策检查 在此之前 链子,所以一个被拒绝的
消息保持其特定状态和清晰的信息。 内部失败
链被重新提升为稳定
ExecutionError,所以SMTP中继器本身的措辞 永远不会成为呼叫者或模型的错误文本.
解析 SMTP 或出箱模式
import { config, transport } from "@dbx-tools/email";
const resolved = config.resolveEmailConfig({
smtp: { host: "smtp.example.com", user: "apikey", password: secret },
domain: "mail.example.com",
});
const runtime = transport.getEmailRuntime({
smtp: { host: "smtp.example.com", user: "apikey", password: secret },
domain: "mail.example.com",
});
resolveEmailConfig() 返回已验证的 ResolvedEmailConfig 页:1
检查. getEmailRuntime() 使用相同的插件配置,解析它,并且
纪念整个运输过程。 插件在设置时为质数, 所以稍后
打电话的人一无所获,就得到同样的情况.
SMTP模式需要主机,用户,密码,以及发送源. 输出模式写入
当 SMTP 证书缺失时 HTML 文件到磁盘 EMAIL_OUTBOX_MODE=1。 。 。 .
对已部署的应用程序使用 SMTP 模式 。 本地演示使用发件箱模式, 自动 测试,开发循环 发送真正的邮件是危险的.
代理工具和核准
两个工具暴露出相同的发送能力,每个代理运行时间一个. 两者都是
有门: Mastra 工具暂停审批, AppKit 工具附加了说明
{ effect: "write", requiresUserContext: true } 所以一个东道主的批准门起火.
AppKit 工具是故意没有的 autoInheritable,所以一个特工到达它
只能通过线条明确.
批准适用于代理工具. transport.sendEmail() 和应用程序
插头 sendEmail() 导出立即发送, 所以直接呼叫者必须执行
他们自己的授权和批准政策.
| 工具 | 运行时间 | 接线 |
|---|---|---|
send_email | 马斯特拉 | tools: () => ({ send_email: emailTool() }) |
email.send | 应用程序 | plugins.email.toolkit() 代码,或 plugin:email 前题条目 |
import { createApp, server } from "@databricks/appkit";
import { agents, createAgent } from "@databricks/appkit/beta";
import { email } from "@dbx-tools/email";
const support = createAgent({
instructions: "Draft emails, but wait for approval before sending.",
tools: (plugins) => ({ ...plugins.email.toolkit() }),
});
await createApp({
plugins: [server(), email(), agents({ agents: { support } })],
});
AppKit 路线
| 方法 | 路径 | 回应 |
|---|---|---|
GET | /api/email/senders | email.emailSendersSchema 从 @dbx-tools/shared-email。 。 。 . |
答复包括当前用户可能选择的具体发送地址, 默认发送地址,以及列表是否受策略限制。 这个 路由在半用户范围内运行,所以域通配符解析 打电话的本地部分.
使用此路径填充 a From 倒入一个作曲UI。 如果没有下降是
显示,服务器仍然可以从活动的用户和配置中获取发送者.
发送地址
import { config, sender } from "@dbx-tools/email";
const resolved = config.resolveEmailConfig({ domain: "mail.example.com" });
// A user caused this send, so it comes from them: [email protected]
const from = sender.resolveSenderAddress(resolved, "[email protected]");
// Nobody did, so it is system mail: [email protected]
const system = sender.resolveSystemSenderAddress(resolved);
sender.assertSenderAllowed(from, resolved.allowedSenders);
domain 是设定部署需要的唯一发送者。 这个 From 对普通
发送是用户本地部分的上半部重回原位,所以接收者可以
回复致电者. from 用一个固定来覆盖
地址和可选地址。 只在每条消息都该写的时候
来自一个邮箱.
没有用户要求的邮件,例如登录密码、密码重置或
提醒,是系统邮件, 和回复它到达任何人。 它从
no-reply@<domain> 相反,这也是什么 resolveSenderAddress() 返回时
当没有用户在范围, 所以服务文本发送 永远不会泄露一个人的
地址转到机器邮件。 那个默认的分数 from 因为一个固定
from 通常是一个人类或团队地址。 给自己取个地址
systemFrom 编号 : EMAIL_SYSTEM_FROM 将答复传送给受监视者
support@,或者使用不同的本地部分。 系统发送者是
折叠到有效的许可列表中, 因此拒绝默认策略从不屏蔽
应用程序的自己的登录邮件.
发送者帮助者支持精确地址、域通配符、空域和 *。 。 。 .
sender.listSenderOptions(resolved, userEmail) 生产混凝土 From
对当前用户的选项,这就是 AppKit 插件对客户端的曝光.
默认 senderPolicy: "allowlist" 是否认的
allowedSenders,所以
仅设定的部署 EMAIL_DOMAIN 拒绝 a From 在任何其他领域.
设定 senderPolicy: "unrestricted" 接受任何 From 来电用品。 这个
在启动时记录有效的政策.
发送回复邮件
import { emailHtml, markdown } from "@dbx-tools/email";
const html = await emailHtml.renderEmailHtml({
subject: "Incident update",
body: "## Status\nResolved.",
});
const text = await emailHtml.renderEmailText({
subject: "Incident update",
body: "## Status\nResolved.",
});
const fragment = await markdown.markdownToHtml("## Status\nResolved.");
renderEmailHtml() 财务报告和审定财务报表 renderEmailText() 制作相同的共享反应邮件
sMTP 使用的两种MIME替代品中的组件树。 普遍性
组件在 @dbx-tools/shared-email-template浏览器预览
并传递了信息共享打字、内容造型和品牌行为.
markdown.normalizeMarkdown() 使Markdown正常化,而不让它变形.
markdown.markdownToHtml() 通过共享回放邮件机体制作.
标出电子邮件
每个消息默认使用寄存器的dbx-tools品牌. 传出 a brand
切入到插件或渲染器中
身份证明.
import { defaultEmailBrand, email, emailBrandFromContext } from "@dbx-tools/email";
// Explicitly select the same brand used by default:
email({ brand: defaultEmailBrand });
// Or derive from any shared BrandContext:
import { brandUtils } from "@dbx-tools/shared-core";
email({ brand: emailBrandFromContext(brandUtils.defaultBrandContext) });
// Or hand-build the small email-safe slice:
email({
brand: {
accent: "#FF3621",
fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif",
name: "Acme",
logoUrl: "https://acme.example/logo.svg", // http(s): or data: only
},
});
React Email通过电子邮件安全内线样式应用该品牌. 浏览器 UI
[data-brand] CSS 桥桥无法到达收件箱, 所以两个已发送的文件
和浏览器预览 EmailBrand 直接值。 A 类 logoUrl
当它是 http(s):, (中文(简体) ), data:,或 cid: URL (中文(简体) ). 要不然就打个牌
显示名称成为页眉标记.
在测试中使用发件箱
import { outbox } from "@dbx-tools/email";
const path = await outbox.writeOutboxEmail(message, "[email protected]", "tmp/email-outbox");
发件箱文件是带有元数据的 HTML 预览,在信头中写入
<dir>/<from>/<timestamp>-<subject-slug>.html。第四个论点接受
EmailBrand第五个国家也接受 heading 财务报告和审定财务报表 preview 使用的演示文稿
在运输。 附件在预览中列出, 但附件字节
未复制到磁盘.
限制
| 常数 | 数值 | 边界 |
|---|---|---|
MAX_BODY_CHARS | 200,000美元 | 电子邮件内容长度 . |
MAX_ATTACHMENT_BYTES | 10个小米B | 一个附件的解码了内含内容. |
MAX_ATTACHMENTS_TOTAL_BYTES | 20个小米B | 合并解码附件内容. |
MAX_ATTACHMENT_COUNT | 20国 | 一个消息的附件. |
SEND_TIMEOUT_MS | 30 000人 | 一个SMTP的对话. |
VERIFY_TIMEOUT_MS | 15 000个 | 设置时间SMTP握手. |
超大小的有效载荷被一个 ValidationError 在事情发生之前
交给SMTP。 常数和插件的截取器设置在
defaults 模块。 附件接受内含 content 只有这个 本地路径和
远程 URL 不属于模型化合同.
模块
plugin- 说吧EmailPlugin,则email()AppKit 插件厂、 发送器 路径,以及email.sendAppKit 代理工具 .tool- 核准emailTool()Mastra 工具与共享SEND_EMAIL_DESCRIPTION。 。 。 .transport- 共享运行时间,getEmailRuntime(), (中文(简体) ),resetEmailRuntime(), (中文(简体) ),verifyEmailTransport(), (中文(简体) ),sendEmail()页:1SendEmailOptions(明确 HTML 语言heading, (中文(简体) ),text/plain备选,以及preview前标题)和执行器插槽 (单位:千美元)setEmailExecutor(), (中文(简体) ),executeWrite()),使每个发送在AppKit的 截取器链.config- SMTP/外框配置类型、发送方政策、JSON计划以及resolveEmailConfig()。 。 。 .defaults- 拦截器链和有效载荷盖的执行设置.sender- 每用户发送者产生,不复制系统发送者 (单位:千美元)resolveSystemSenderAddress()),允许列表解析和发送者-选项 列出.emailHtml- 共享模板上的节点渲染适配器:renderEmailHtml(), (中文(简体) ),renderEmailText(),以及renderEmail()两次MIME 一个组件树的替代品.markdown- 仅体能渲染normalizeMarkdown()。 。 。 .outbox- 用于开发和测试的本地 HTML 文件撰写器.brand- 说吧EmailBrand, (中文(简体) ),emailBrandFromContext(),以及defaultEmailBrand。 。 。 .
brand后方组件 emailHtml编号 :markdown,从
@dbx-tools/ 共享电子邮件模板它们的存在如此
服务器代码有一个要发送的导入, 因此节点渲染器和一个浏览器
预览不能分开 。 样式内置是 React Email 自己的 。 这个包
运行没有单独的 CSS 内线 .
给这个包配对 @dbx-tools/ 共享电子邮件 当UI时 或工具计划需要验证相同的电子邮件有效载荷,并且 @dbx-tools/ 共享电子邮件模板 当另一个 运行时间需要直接重用演示文稿组件.