电子邮件工作流集成与 SDK
探索 SendRepute API 和集成,用于电子邮件分析、另行付费的 AI 重写和设计工具。核心分析、重写和生成器端点不会发送电子邮件;特意启用的 Campaigns 交付和某些提供商适配器可以使用您配置的提供商进行发送。没有任何结果可以保证收件箱投递率。
Node.js 软件包已在 npm 上发布。其他集成可在此处下载或从经验证的公共 GitHub 仓库安装。在启用之前,请选择一个集成,遵循其指南,并查看权限、当前定价及 failure 策略设置。
请保留您当前的电子邮件工作流程。这些中心 API 示例仅用于分析、重写或构建内容,绝不会发送电子邮件。只有在特意启用了营销活动投放以及特定提供商适配器的情况下,才能通过您配置的提供商进行发送。请根据安装、配置、示例和操作限制来选择工具。示例不会在此页面运行;请分别查看付费操作和发送操作的相关说明。
WordPress 插件
0.2.0
需要 WordPress 5.7+、PHP 7.4+ 及 OpenSSL。通过“插件 > 安装插件 > 上传插件”上传 ZIP,然后打开“设置 > SendRepute”。请分别为每个站点配置令牌和付费分析同意。已安装生命周期证据覆盖了 WordPress 6.8.3 与 WooCommerce 10.4.3;独立的 SMTP 插件证据覆盖了 WordPress 7.1.2 与 WP Mail SMTP 4.9.0 及 FluentSMTP 2.4.0。
通过 pre_wp_mail 检查邮件,不更换 SMTP 或重写邮件。咨询模式允许发送;拦截模式应用概率阈值。API 故障策略需单独配置。绕过 wp_mail 的插件不在覆盖范围内;后续的传输更改不会被分析。拦截操作不会将邮件存入队列。
分析默认禁用。在启用付费分析之前,请配置限定范围的客户令牌,运行非付费连接检查,查看定价并明确表示同意。手动 AI 操作需要单独确认。
下载 WordPress ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
在可使用WP-CLI的WordPress目录中运行这些命令,或者通过“插件 > 安装插件 > 上传插件”上传下载的ZIP并激活。打开“设置 > SendRepute”。在多站点模式下分别配置并激活每个站点。保持支持的WordPress/PHP组合;最低版本要求并非运行已停止维护软件的推荐建议。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-wp.zip
wp plugin install ./sendrepute-wp.zip --activate
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-wordpress.git
cd sendrepute-wordpress
python3 package.py
2. 安全配置
创建一个具有classify、account:read和catalog:read作用域、过期时间和支出上限的服务端客户令牌。在设置中输入它,或从服务器机密库加载SENDREPUTE_API_TOKEN,如所示。存储的令牌使用带有WordPress盐值和OpenSSL的身份验证加密;在盐值轮换后需重新输入。运行非付费连接检查,查看分类定价,然后明确启用自动分析。设置建议/拦截模式、阈值以及独立的失败开启/失败关闭策略。
// wp-config.php — optional server-secret alternative to settings storage.
$sendreputeToken = getenv('SENDREPUTE_API_TOKEN');
if (is_string($sendreputeToken) && $sendreputeToken !== '') {
define('SENDREPUTE_API_TOKEN', $sendreputeToken);
}
3. 审慎使用
下方函数使用正常的wp_mail,并仅在您的应用程序调用时发送。在启用付费分析的情况下,插件在pre_wp_mail处进行分析,然后许可或拦截现有的传输。请提供您自己的授权收件人;先针对非中继的本地邮件接收器进行测试。错误结果意味着调用者必须处理被拒绝的发送——它不会进入队列。
// Call deliberately: this sends through your existing WordPress transport.
function sendrepute_reviewed_message($recipient) {
return wp_mail(
$recipient,
'Your requested account summary',
'Here is the account summary you requested.'
);
}
它还能做什么?
设置还提供手动AI重写和模板生成操作,并需单独的付费确认。价格显示需要vip:read;重写需要rewrite;生成需要ai:generate,VIP生成需要有效的VIP会员身份。结果是经过转义的、仅供复制的文本:绝不会自动应用或发送。现有令牌不会自动获得作用域。
结果、失败与限制
建议模式(Advisory)允许投递;拦截模式会将有限的垃圾邮件概率与您的阈值进行比较。API 超时和失败遵循独立的失败策略,而不是垃圾邮件标签。不透明的本地锁会在 24 小时内抑制重复分析;未知的网络结果不会自动重试。发送操作本身不会被去重。已安装的更新检查覆盖了从 0.1.0 ZIP 升级到 0.2.0 的跟踪过程、管理员 nonce 拒绝/保存以及选定的 WooCommerce 路径。一个独立的 40 种场景矩阵覆盖了 WP Mail SMTP 和 FluentSMTP 的两种插件加载顺序,包括 To/Cc/Bcc、Reply-To、标头、附件、SMTP 拒绝和策略结果。这些确切的组合元组不认证其他 CMS、SMTP 插件或提供商版本。绕过 wp_mail 的钩子和随后的传输更改仍不在覆盖范围内。停用会保留设置;卸载会移除凭据,即使保留了禁用的设置。请自行移除 wp-config 令牌。
WooCommerce 电子邮件适配器
0.2.0
已包含在 WordPress 插件的同一个 SendRepute 0.2.0 ZIP 压缩包中;没有单独的 WooCommerce 插件或下载。它需要该插件的 WordPress 5.7+、PHP 7.4+ 和 OpenSSL 基准环境。此适配器已针对 WooCommerce 10.4.3 进行源码审查,未在每个 WooCommerce 或邮件扩展版本中进行认证。
WooCommerce 分析拥有独立的管理员开关和精确的内置电子邮件类型选择,默认情况下全部关闭。全局分析和付费同意控制也必须开启。未选择的类型和扩展定义的类型将绕过分析。每个选定的内置 customer_* 类型都受到保护且仅供参考:它们可能被分析,但绝不会被阻止。选定的多部分邮件在发起任何付费请求前会分类失败;仅供参考或故障放行模式会保留投递,而故障关闭模式仅阻止非受保护的邮件。
下载共享的 WordPress 和 WooCommerce ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
这与 WordPress 指南中使用的安装 ZIP 文件相同。只需安装一次;请勿安装第二个 WooCommerce 插件。激活 SendRepute,然后打开“设置 > SendRepute”。请保持 WordPress、WooCommerce、PHP 和实际的邮件传输受支持并及时更新。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-wp.zip
wp plugin install ./sendrepute-wp.zip --activate
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-wordpress.git
cd sendrepute-wordpress
python3 package.py
2. 安全配置
使用来自服务器机密或已加密 WordPress 设置的受限客户令牌。首先配置共享的非付费连接检查、当前价格审查、全局付费同意、风险模式、阈值和失败策略。然后单独启用 WooCommerce 分析,并仅选择已审核的内置电子邮件类型。扩展定义的类型永远不会被自动选择。
// wp-config.php — keep the shared WordPress/WooCommerce token server-side.
$sendreputeToken = getenv('SENDREPUTE_API_TOKEN');
if (is_string($sendreputeToken) && $sendreputeToken !== '') {
define('SENDREPUTE_API_TOKEN', $sendreputeToken);
}
3. 审慎使用
继续通过 WooCommerce 正常发送。该适配器封装了 WooCommerce 已经选择的回调,并保留其原始参数和传输;它不提供新的发送方法。如果另一个过滤器更改了回调参数,普通邮件在该回调期间嵌套,或者自定义回调从未调用 wp_mail,则分析将保守地绕过,而不是进入常规付费路径。请使用非中继邮件池测试选定的非关键类型。
结果、失败与限制
选定的单部分邮件遵循共享的 WordPress 建议、阈值和失败策略,但每个 customer_* 类型都受到保护且仅限建议模式。受保护的客户邮件在出现高风险结果、API 失败或不支持的内容后始终继续发送。WooCommerce 在 pre_wp_mail 之后构建多部分备选项,因此选定的多部分邮件将在任何付费请求之前失败,而不是被部分分类;只有选定的非受保护邮件可能会被 fail-closed 策略拒绝。回调上下文在成功、失败和嵌套发送后会被移除。
Drupal 邮件后端
0.1.0
需要 Drupal 10.3+ 或 11.x 以及 PHP 8.1+。将 ZIP 作为模块安装,仅向受信任的管理员授予 administer sendrepute 权限,配置有界的非地址发件人显示名称,并选择确切的模块/关键邮件路由。版本 0.1.0 仅支持 Drupal 核心 php_mail;它是一个 Mail 后端,而非提供商或替代传输工具。已安装站点的证据覆盖了确切的 Drupal 10.6.17 和 11.4.7 版本及 PHP 8.4.10。
默认情况下,付费同意和所有路由均处于关闭状态。每个准确路由使用固定的核心 php_mail 委托、咨询或拦截模式、独立的保留或拦截故障策略、阈值以及深思熟虑的关键邮件选择。账户和安全邮件保持可送达状态,除非该准确路由明确允许拦截关键邮件。同一个 php_mail 实例格式化并发送一个标量最终正文;不支持多部分和带有附件的输出。
下载 Drupal ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
从 Drupal 项目根目录运行,或使用 Drupal 的模块安装程序上传 ZIP。该压缩包包含一个适用于 modules/contrib 的 sendrepute 模块根目录。启用它,仅向信任的管理员授予 administer sendrepute 权限,并打开 Configuration > System > SendRepute。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-drupal.zip
unzip sendrepute-drupal.zip -d modules/contrib
drush en sendrepute -y
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-drupal.git
cd sendrepute-drupal
2. 安全配置
仅在 web/PHP 进程环境中存储 classify 作用域的 SENDREPUTE_API_TOKEN。表单绝不接受该令牌,也不会在 Drupal 配置中导出。在表单中,输入必填的发件人显示名称,最大 320 字节,不含地址、尖括号或控制字符。按所示为每个准确路由添加一行七字段配置;delegate 必须是 php_mail。选择 advisory/block 模式、preserve/block 失败策略、阈值以及关键邮件 yes/no。建议从 advisory、preserve 和 no 开始。
export SENDREPUTE_API_TOKEN="replace-with-a-scoped-server-token"
# Enter a non-address sender display name in Configuration > System > SendRepute.
# One exact route in Configuration > System > SendRepute:
# contact|page_mail|php_mail|advisory|preserve|0.90|no
3. 审慎使用
继续调用 Drupal 的正常邮件管理器。对于已选择加入的路由,sendrepute_mail 调用核心 php_mail 的 format(),分析该最终标量正文,应用策略,然后调用同一个缓存的 php_mail 实例的 mail()。其他委托 ID 将被拒绝。它不使用 hook_mail_alter,也不重写消息。
结果、失败与限制
在 block 模式下,验证成功的请求仅在达到或超过配置的阈值时进行拦截。在 spamProbability 影响投递前,完整的嵌套分类结果和计费响应都会经过验证。API、身份验证、余额、频率限制、格式错误、多部分、附件指示符和大小失败均遵循独立的路由失败策略,受保护的关键邮件继续发送除外。已安装的 10.6.17/11.4.7 矩阵覆盖了启用状态下的安装和就地 ZIP 替换、真实管理员登录、Form API CSRF 拒绝/保存、插件发现、路由选择性加入、模拟分类、关键邮件保留以及通过本地汇点的核心 php_mail。基线源码检查还覆盖了不可变的 10.3.0 和 11.0.0 归档;两个结果均不认证所有后续补丁或贡献的邮件程序。发送配置的显示名称、非空主题和长度分帧的正文;排除地址、收件人、请求头、参数和附件。主题限制为 998 字节,正文限制为 256 KiB。仅进行一次验证 HTTPS 尝试,无重定向、重试或队列。
PrestaShop 邮件模块
0.1.1
版本 0.1.1 仅支持 PrestaShop 9.0.0, 9.0.1, 9.0.2 和 9.0.3,需配合 PHP 8.1–8.4。在“Modules > Module Manager”中上传 ZIP,然后配置 SendRepute 邮件分类。所有四个官方预构建经典版本均通过了隔离安装、经过身份验证的管理员配置以及 ZIP-update 检查;它们未更改的 Mail::send() 实现也通过了离线真实邮件矩阵。PrestaShop 8, 9.1+ 以及之后未列出的 9.0 补丁暂不支持。
该模块、付费/内容同意以及确切的模板选择默认为关闭。它会分析最终渲染的主题和每个受支持的显示正文,而无需重新构建 Symfony 消息。包含 text/plain 和 text/html 的消息会在一次有界的分类请求中发送:plain 备选项保持不活跃,保留原始 HTML,服务独立分析每个类型的备选项而不进行拼接。结果使用包含完整内容审计的最高风险项,产生一次付费分类,且绝不返回部分安全分。咨询模式永远不会中断发送。阈值拦截和故障时关闭会抛出一个同时实现 Symfony Mailer 的 ExceptionInterface 和 PrestaShop 的 ModuleErrorInterface 的异常;在每个受支持的发行版本上,已安装的测试观察到 Mail::send() 返回 false 且没有 SMTP 投递。故障策略独立于风险阈值。
下载 PrestaShop ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
下载 0.1.1 ZIP 文件,然后通过 Modules > Module Manager > Upload a module 进行选择并上传。打开 SendRepute 邮件分类的 Configure 界面。请勿在确切的 PrestaShop 9.0.0–9.0.3 范围之外强制安装:取消和签名行为依赖于经审计的 Mail::send() 路径。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-prestashop.zip
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-prestashop.git
cd sendrepute-prestashop
2. 安全配置
将 SENDREPUTE_API_BASE 设置为为此模块提供的规范生产环境 SendRepute HTTPS 源,并将 SENDREPUTE_API_TOKEN 设置为 PHP-FPM/服务器环境中的受限服务器令牌。Base 必须是不含路径的公共 DNS HTTPS 源;字面值、凭据、重定向和私有 DNS 响应将被拒绝。运行非付费账户/定价连接检查,然后显式启用模块、付费/内容同意和精确的模板名称。独立选择 advisory/block、阈值和 open/closed 失败策略。
export SENDREPUTE_API_BASE="replace-with-the-canonical-sendrepute-https-origin"
export SENDREPUTE_API_TOKEN="replace-with-a-scoped-server-token"
3. 审慎使用
继续使用 PrestaShop 正常的 Mail::send 流程。早期钩子仅记住已选择的特定模板。最终钩子读取已渲染的 Symfony Email 主题、文本正文和 HTML 正文,而不更改收件人、标题、附件或传输方式。对于双重正文,它在一次请求中将惰性纯文本和原始 HTML 作为键入的可选内容提交;独立的业务规范化可防止一段碎片吞噬另一段,同时保留用于审计的可视 HTML 链接和图像目标。单个纯文本正文保持在窄惰性文本路径上,单个 HTML 正文保持在窄 DOM 提取路径上。分类在 PrestaShop 创建单独的 DKIM 签名邮件之前完成。受支持版本矩阵验证了分类后发出的多部分结构以及 DKIM 正文哈希和 RSA 签名。PrestaShop 的固定签名路径在准备的已签名标题中省略了 Bcc,并会丢失该盲送 SMTP 收件人;因此,有效的签名证据并不能证明 Bcc 投递的兼容性。请勿在此受支持路径上同时使用 DKIM 和 Bcc。不支持的显示源、动态语义、歧义的 quoted-printable 或 base64 HTML 以及超大聚合内容将在付费前遵循配置的故障策略。除非经过刻意批准,请保持关键模板处于未选中状态。
结果、失败与限制
分类器接受一个 text/plain 正文、一个 text/html 正文或两者作为独立分析的显示备选方案。在已接受的备选方案中,字面文本、实体、隐藏内容和样式内容不能吞噬或隐藏后续的备选方案;有歧义的 quoted-printable 或 base64 HTML 将在付费前被拒绝。任何被接受的备选方案都可以决定最高风险结果,而内容审计涵盖每个备选方案;只有在完整的有界输入被接受后,分类才会计费一次。所需的遗留正文与双重邮件的惰性纯文本备选方案完全重复,该副本加上两个键入的备选方案共享精确的 524288 字节请求预算。收件人、附件和嵌入资源被排除在外,并保留原始预签名传输邮件。真实邮件固定装置分别检查 MIME/签名完整性和实际 SMTP 收件人:DKIM 签名在分类后保持有效,但经审计的上游签名路径不保留 Bcc 收件人。验证通过的分类会存储有限的最新咨询摘要。block 模式仅在达到或超过阈值时抛出;双重接口异常在钩子调度中幸存,并在所有四个已安装版本上产生 transport 前的 false。不支持的内容、API 和验证错误独立遵循 open/closed 策略。单次 HTTPS 尝试使用固定的公共 DNS、经过验证的 TLS、有限的超时、256 KiB 的响应上限,无重定向且无重试。阻断依赖于经审计的 PrestaShop Mail::send() 异常捕获,而非最终钩子的返回值。
Symfony Mailer 适配器
0.1.1
需要 PHP 8.1+,仅针对 Symfony Mailer 6.4 或 7.4;确切验证的版本为 6.4.46 和 7.4.19。不声明对 Symfony 8.1 或未测试版本的兼容性。请通过 Composer 路径仓库安装本地源码 ZIP;此包未发布到 Packagist。
该 bundle 和付费同意默认关闭,仅带有确切配置的选择性加入请求头的消息才符合资格。建议或拦截评分策略独立于 allow 或 block 故障策略。分类在官方的发送前 MessageEvent 上运行;拒绝操作使用 MessageEvent::reject()。队列克隆事件会被跳过,因此工作线程的传输事件是唯一的付费分类点。
下载 Symfony 源码 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
将下载的 ZIP 解压到保留的 packages 目录中,将该目录注册为 Composer 路径仓库,require 确切的 0.1.1 软件包,如果 Flex 没有自动注册,则手动注册 SendRepute\Symfony\SendReputeBundle。源归档文件位于本地且未发布。
mkdir -p packages
curl -fL https://www.sendrepute.com/downloads/sendrepute-symfony.zip -o packages/sendrepute-symfony.zip
unzip packages/sendrepute-symfony.zip -d packages
composer config repositories.sendrepute path ./packages/sendrepute-symfony
composer require sendrepute/symfony:0.1.1
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-symfony.git
cd sendrepute-symfony
2. 安全配置
从服务器机密信息中解析 SENDREPUTE_API_TOKEN。在查看当前定价时,请保持 enabled 和 paid_analysis_consent 为 false。模式、阈值和失败策略是相互独立的。端点固定为经过验证的 HTTPS,具有受限的截止期限,无重定向或重试,且响应上限为 1 MiB。
send_repute:
enabled: false
paid_analysis_consent: false
api_token: '%env(SENDREPUTE_API_TOKEN)%'
mode: advisory
failure_policy: allow
spam_probability_threshold: 0.8
3. 审慎使用
仅将准确的加入选择标头添加到已审核的非关键 Email 对象,然后继续通过常规 Mailer。消息、envelope、transport 和标头不会被重写。对于 Messenger 传递,请在 workers 中配置该 bundle:有意不对生产者的克隆事件进行分类。
$email->getHeaders()->addTextHeader('X-SendRepute-Classify', 'yes');
$mailer->send($email);
结果、失败与限制
仅支持一个内存中的文本或 HTML 正文。混合备选方案、文本 DataParts、流或路径、CSS 大括号、标记、quoted-printable 语法、base64 标头或全正文 base64 将在付款前失败并遵循失败策略;普通的无大括号内容保持不变。每个必需的嵌套响应字段和可选审核分支都会被验证,未知的属性将被拒绝。advisory 绝不会进行分值阻断;阻断会根据阈值通过实际的 transport 事件执行拒绝。
Rails Action Mailer 适配器
0.1.0
需要 Ruby 3.2+,并已在 Action Mailer 7.1.6 和 Mail 2.9.1 环境下经过严格验证;该回调路径也在 Action Mailer 7.2.3.2 上经过测试。这并不代表对所有允许的 Rails 7.x 版本的官方认证。请通过 Bundler 安装本地源码 ZIP;不保证在 RubyGems 上发布。
两个全局付费门控默认均为关闭状态,每个 mailer 操作必须显式调用 sendrepute_paid_preflight!。建议/拦截评分行为与保留/拦截失败行为是相互独立的。密码重置、MFA、登录、验证、账单和安全路由应保持未选中状态。每个多部分消息以及含有歧义的 CSS、quoted-printable 或看起来像 base64 的内容在付费前都会被拒绝;一个被接受的已解码文本或 HTML 主体将被分析,且不会更改原始消息或传输。
下载 Rails 源码 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
将 ZIP 准确解压到 vendor/sendrepute-rails,在 Gemfile 中添加本地路径条目,在受控环境中运行 Bundler,并在 ApplicationMailer 中包含 SendRepute::Rails::Mailer。这不属于 RubyGems 安装。
# Download sendrepute-rails.zip, then extract it into vendor/sendrepute-rails.
gem "sendrepute-rails", path: "vendor/sendrepute-rails"
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-rails.git
cd sendrepute-rails
2. 安全配置
在审查当前定价和路由之前,请保持 enabled 为 false 且 paid_consent 为 false。从 Rails credentials 或其他服务器机密中读取令牌。独立配置 advisory/block、preserve/block 以及 threshold;on_result 和 on_error 回调函数不得记录邮件内容、授权数据或完整响应。
SendRepute::Rails.configure do |config|
config.enabled = false
config.paid_consent = false
config.token = Rails.application.credentials.dig(:sendrepute, :api_token)
config.mode = :advisory
config.failure_policy = :preserve
config.score_threshold = 0.8
end
3. 审慎使用
仅在经过审慎选择的非关键 mailer action 中调用 sendrepute_paid_preflight!。普通 action 会绕过分类。付费钩子使用 Action Mailer 的 before_deliver 路由;不提供全局自动加入功能,且适配器不会重写 Mail::Message。
class ApplicationMailer < ActionMailer::Base
include SendRepute::Rails::Mailer
end
def newsletter
sendrepute_paid_preflight!
mail(to: params[:to], subject: "News")
end
结果、失败与限制
支持一个解码后的 text/plain 或 text/html 显示正文。每个多部分或模糊的规格化器输入在付费前都会失败,并遵循失败策略。完整的嵌套类型响应仅在达到或超过阈值时的 block 模式下进行拦截;advisory 模式会保留每个分数。结果和错误回调接收不可变的安全数据,回调异常或 throw(:abort) 会在本地捕获,因此它们无法终止 advisory 模式或保留投递。固定端点拒绝重定向和重试,并使用受限的总截止时间。已通过真实 Action Mailer 7.1.6 测试:19 次运行和 59 个断言;未发生付费请求或真实投递。
Spring JavaMailSender 适配器
0.1.1
要求 Java 17+ 并针对 Spring Framework 6.2.x 的 JavaMailSender;确切的依赖验证基于 Spring Framework 6.2.19。本库不提供针对 Spring Boot 4 或广泛框架版本的声明。请使用 Maven 构建本地源代码 ZIP;它未发布到 Maven Central 或其他仓库。
装饰器、付费同意、咨询模式以及故障时允许默认值均已明确。仅 sendWithSendRepute(...) 执行付费发送前分析;所有普通 send(...) 重载均会绕过分类并原样委托。除非特定邮件被刻意选择,否则关键邮件请使用普通 send。支持显示的 MIME 备选方案将以惰性方式组合成帧;不支持的、嵌套的、签名的、加密的或含义模糊的内容将在支付前失败。
下载 Spring Java 源代码 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
解压 0.1.1 源代码 ZIP 文件,运行 mvn verify,并将其仅安装到受控的本地 Maven 仓库中。调用应用程序需提供其现有的 JavaMailSender 和运行时邮件实现。精确的依赖项验证使用了 Java 17 字节码、Spring Framework 6.2.19 以及包含在 README 中的文档版本。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-spring-mail.zip
unzip sendrepute-spring-mail.zip
cd sendrepute-spring-mail-0.1.1
mvn verify
mvn install
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-java.git
cd sendrepute-java
2. 安全配置
从服务端令牌和显式开关构造 SendReputeConfiguration。在审查价格和所选调用之前,请保持 enabled 和 paidAnalysisConsent 为 false。咨询/拦截、阈值以及允许/拦截的失败策略是相互独立的。端点固定为已验证的 HTTPS,无重定向或重试。
var settings = new SendReputeConfiguration(
token, false, false,
SendReputeConfiguration.Mode.ADVISORY,
SendReputeConfiguration.FailurePolicy.ALLOW,
0.80, Duration.ofSeconds(3), Duration.ofSeconds(10));
var reviewedSender = new SendReputeJavaMailSender(existingSender, settings);
3. 审慎使用
仅针对应进行分析的单个 SimpleMailMessage、MimeMessage 或 MimeMessagePreparator 调用 sendWithSendRepute(...)。支持单个和可变参数重载。所有正常的 send(...) 重载都会绕过分类。Preparators 仅渲染一次,原始准备好的 MIME 在策略允许后进行委托。
// Paid classification is possible only on this explicit method.
reviewedSender.sendWithSendRepute(reviewedMessage);
// Every ordinary JavaMailSender send overload bypasses classification.
reviewedSender.send(criticalMessage);
结果、失败与限制
所有支持的显示文本和 HTML 部分均被分析;收件人和附件除外。遍历层级限制为 16 层、256 个部分和 524,288 个显示的 UTF-8 字节。忽略的内联二进制数据永远不会被实例化;未知或无限制的延迟显示源在打开流或发出付费请求之前就会失败,且受支持的源读取是受限的。数字实体框架使片段在经过检查的服务器规格化器顺序中保持惰性。整个可变参数批次在第一次付费请求之前完成准备和规格化,且检查过程不会生成 Jakarta Mail 标头。需要递归精确的嵌套响应。
Magento Open Source 邮件适配器
0.1.1
仅支持 Magento Open Source 2.4.7-p5 和 2.4.7-p6,且需配合经过审查的精确不可变邮件接口源码。脱机类型固定装置已通过测试,但未进行完整的 Magento 安装;未认证任何其他 Magento 或 Adobe Commerce 版本。请通过 Composer 路径仓库安装本地 ZIP;它不是 Adobe Marketplace 软件包。
该模块、付费同意和路由列表默认全部关闭。每个模板标识符均需要两个独立的精确批准;其严重性绝不会根据名称推断。aroundSendMessage 插件在最终传输边界进行分析,无需重建消息。建议/拦截阈值策略与保留/拦截失败策略相互独立;拦截操作会抛出可见的 Magento MailException。多个显示的 MIME 部分以及歧义内容将在支付前失败。
下载 Magento 源码 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
将 ZIP 解压到保留的包目录中,将其 SendRepute_MailAdapter 根注册为 Composer 路径仓库,要求版本 0.1.1,然后使用 Magento 的常规模块启用和设置升级流程。不要将此本地存档视为 Adobe Marketplace 软件包。
mkdir -p packages/sendrepute-magento
curl -fLO https://www.sendrepute.com/downloads/sendrepute-magento.zip
unzip sendrepute-magento.zip -d packages/sendrepute-magento
composer config repositories.sendrepute path ./packages/sendrepute-magento/SendRepute_MailAdapter
composer require sendrepute/magento-mail-adapter:0.1.1
bin/magento module:enable SendRepute_MailAdapter
bin/magento setup:upgrade
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-magento.git
cd sendrepute-magento
2. 安全配置
仅在 PHP-FPM 和 CLI 服务器环境中设置 SENDREPUTE_API_TOKEN。在 Stores > Configuration > Services > SendRepute 中,初始保持模块和付费同意为关闭状态。将每个精确的模板标识符添加到两个独立的路由批准列表中;名称(包括数字名称)绝不会推断出关键性。分别配置咨询/拦截、阈值以及 preserve/block 失败行为。
export SENDREPUTE_API_TOKEN="replace-with-a-scoped-server-token"
# Then configure Stores > Configuration > Services > SendRepute.
3. 审慎使用
继续使用 Magento 的正常模板和传输流。路由关联记录了通过 TransportBuilder 选择的精确标识符和商店,而最终的 aroundSendMessage 插件在调用相同传输之前读取官方类型的电子邮件和 MIME 接口。Builder 状态在 finally 中清除,builder/message 关联使用以对象为键的 WeakMap 条目,因此被遗弃的已构建传输无法留下可重复使用的数字对象 ID 授权。该适配器不提供新的 send 方法,也不改变 message。
结果、失败与限制
仅接受一个支持显示的 MIME 部分;附件会被保留但排除在分析之外。多个显示部分、不支持的传输编码或字符集、流、嵌套 MIME 以及含义不明的标准化文本将在支付前失败。一次经过验证的 HTTPS 请求具有限定的截止时间和响应大小,且没有重试或重定向。有效的嵌套结果可能会在阈值处拦截;配置的 fail-block 会抛出 Magento MailException。
.NET MailKit 适配器
0.1.0
需要 .NET 8 且必须提供 MailKit/MimeKit 4.18.0 的确切依赖证明。这是针对应用程序所有的 IMailTransport 的显式包装器,并非全局钩子、SMTP 客户端或替换传输。请构建或引用本地源码 ZIP;未声明任何 NuGet 发布。
适配器和付费同意默认关闭;咨询模式和保留发送是独立的默认设置。对 AnalyzeAsync、AnalyzeThenSend 或 AnalyzeThenSendAsync 的调用是显式的。关键的安全/账户邮件需要独立的单次调用类别和同意。每个受支持的展示纯文本/HTML 备选项都会被惰性框架化到同一个受限请求中;不支持的、嵌套的、签名的或加密的内容在支付前会失败。原始 MimeMessage 和取消令牌仅在策略允许后才会到达现有传输。
下载 .NET MailKit 源代码 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
解压源 ZIP 文件,并在调用的 .NET 8 项目中引用 src/SendRepute.MailKit/SendRepute.MailKit.csproj。Restore 会获取 MailKit/MimeKit 4.18.0。此源代码包为本地且未发布;它不是 NuGet 安装。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-mailkit.zip
unzip sendrepute-mailkit.zip
dotnet add reference ./sendrepute-mailkit-0.1.0/src/SendRepute.MailKit/SendRepute.MailKit.csproj
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-dotnet.git
cd sendrepute-dotnet
2. 安全配置
使用 SendReputeMailAdapter 包装现有应用程序拥有的 IMailTransport。从服务器配置中读取 API 令牌,并在审核前保持 Enabled 和 PaidAnalysisConsent 为 false。Advisory/block 阈值与 preserve/block 失败设置是相互独立的。Endpoint、TLS 下限、单次尝试行为、截止期限以及 1 MiB 限制是固定的。
var options = new SendReputeOptions {
Enabled = false,
PaidAnalysisConsent = false,
ApiToken = configuration["SENDREPUTE_API_KEY"]!,
Enforcement = EnforcementPolicy.Advisory,
OnFailure = FailurePolicy.PreserveSend,
SpamProbabilityThreshold = 0.80
};
var adapter = new SendReputeMailAdapter(existingTransport, new SendReputeClient(options), options);
3. 审慎使用
调用 AnalyzeAsync 仅进行分析,或调用 AnalyzeThenSend 和 AnalyzeThenSendAsync 以执行显式的发送前行为。不会拦截任何普通或全局邮件路径。在每个选定的操作中传递付费同意和邮件类别;关键的安全/账户邮件需要单独的 critical-consent 设置。
await adapter.AnalyzeThenSendAsync(message, new AnalysisConsent {
PaidAnalysisConsent = true,
Category = MessageCategory.Ordinary
}, cancellationToken);
结果、失败与限制
实际 MimeKit 解码会将所有受支持的显示文本和 HTML 备选内容收集到惰性框架中,同时排除收件人和附件。非 base64 外部框架和后期解码实体在服务规范化之前中和 CSS 大括号、quoted-printable 文本、base64 标头、全正文 base64 和标记。不受支持、嵌套、签名或加密的显示内容会在支付前失败。每个必需的响应字段均已类型化;可选的 flaggedTermCount 必须是非负整数,可选的 contentAudit 将根据公开契约进行完整且递归的验证。只有当独立的评分和失败策略允许时,原始的 MimeMessage 和取消令牌才会到达提供的传输层。
Zapier 手动草稿分析
0.2.0
手动 Zapier 配方,用于显示由所有者选定的三个草稿字符串的付费分析。这不是 SendRepute Zapier 应用、市场列表、导入工件、发送前适配器、发送器、允许/阻止路由或整条消息分类器。Zapier Webhooks 使用所有者操作的有界 HTTPS 代理,因为 SendRepute 令牌不得进入 Zap。
两个编译时常量在 HTTP 之前默认为 false。Zap 仅映射发件人显示名称、主题和正文,将 JSON 发布到包含的所有者代理设计,完全验证嵌套响应,然后在私有审核步骤中显示咨询和计费字段。它不得添加发件人、Paths 强制执行、Autoreplay 或故障保留路由;失败的 Code 或 Webhook 步骤将停止。
下载 Zapier 和 Make 配方 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
下载并解压共享的 0.2.0 配方源码。阅读包含的 Zapier 指南,并仅在所有者管理的 HTTPS 反向代理后部署包含的环回 Node 代理。本包不负责部署该代理。目前没有 SendRepute Zapier 应用或可导入的 Zap 构件。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-automation-recipes.zip
unzip sendrepute-automation-recipes.zip
cd sendrepute-automation-recipes
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-automation.git
cd sendrepute-automation
2. 安全配置
保持 Zap 关闭。在准确的预检 Code 源码中,ENABLED 和 PAID_CONSENT 在付费使用经过审核前均保持为 false。所有者代理存储 SENDREPUTE_API_TOKEN;Zap 仅从 SENDREPUTE_PROXY_CREDENTIALS 接收一个可单独撤销的凭据。编辑器和任务历史记录可能会暴露它,因此请进行限制、轮换和撤销。配置每个凭据的令牌桶和并发限制、全局连接/并发上限、持久的由所有者设置的每日付费调用预算、限制性的上游支出限制,以及匹配的 TLS 终止器大小/速率/截止日期控制。请勿启用 Autoreplay。
// In zapier/preflight.js; review charges before changing either literal.
const ENABLED = false;
const PAID_CONSENT = false;
3. 审慎使用
手动构建步骤:草拟触发器;preflight 代码仅映射发件人、主题和正文;通过 Webhooks 向所有者代理发送带有 JSON 行的 POST 请求;响应验证代码;私有审核显示。切勿手动插入原始 JSON。仅显示 requestId、model、label、spamProbability 和计费信息;请勿添加邮件操作或 Paths 决策。
{
"sender": "Mapped draft sender display name",
"subject": "Mapped draft subject",
"body": "Mapped draft body"
}
结果、失败与限制
该配方仅分析三个映射的字符串;未映射的 MIME、HTML 备选内容、附件和最终的出站内容保持未分析状态。保守的预检会拒绝已知的规范器触发器,但无法证明全消息覆盖。代理速率、并发和每日预算限制会在上游之前拒绝,且预算预留会在付费尝试前持久化;每个预算文件运行一个代理进程。代理会进行一次有界的固定 HTTPS 尝试。任何非 200 或不完整的准确响应都会抛出异常并停止;不存在保留、Resume 或替代结果。
Make 手动草稿分析
0.2.0
用于显示针对精确选定的三个草稿字符串进行付费分析的手动 Make 场景说明。这并非蓝图、经批准的 SendRepute 应用、邮件发送器、执行路径,也不构成对未映射 MIME、HTML、附件或最终出站内容的任何声明。持有者令牌仅属于 Make HTTP 的安全密钥链。
持久化的 enabled 和 paidConsent 布尔值默认为 false,且 AND 过滤器会在 HTTP 之前停止。JSON 由 Make 的 JSON 模块生成,并由 HTTP 模块发送一次,同时禁用重定向和重试。响应过滤器仅作为显示保护,并非完整验证或发送许可。HTTP 故障使用 Break,绝不使用 Resume 或替代输出。
下载 Zapier 和 Make 配方 ZIP 文件
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
下载并解压共享的 0.2.0 配方源码,然后按照随附的 Make 指南手动构建当前的原生模块。不提供任何 blueprint、商店应用或导入格式。在针对模拟端点进行测试时,请保持 scenario 调度处于关闭状态。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-automation-recipes.zip
unzip sendrepute-automation-recipes.zip
cat sendrepute-automation-recipes/make/README.md
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-automation.git
cd sendrepute-automation
2. 安全配置
创建持久化的布尔型 Tools 变量 enabled=false 和 paidConsent=false,随后通过 AND 过滤器要求两者均需为 true。使用 JSON > Create JSON 来精确处理 sender、subject 和 body。请仅将 SendRepute 持有者令牌存储在 HTTP 应用的安全密钥链中;导出的 scenarios 不得包含任何凭据。
Tools variables: enabled = false; paidConsent = false
Filter: enabled = true AND paidConsent = true
HTTP credential: secure keychain; Authorization header
Body type: Raw; Content type: application/json; map serialized JSON
Follow redirect: No; Timeout: 10 seconds; no retry
Response filter: Minimal display guard
3. 审慎使用
配置一次指向固定 classify URL 的 HTTP POST。选择 Body 类型为 Raw,并选择 application/json 内容类型控制,不要添加冲突的自由文本头,然后映射从 JSON > Create JSON 序列化的输出。启用解析响应,禁用重定向,设置 10 秒超时,并且不添加重复器或自动重试。要求使用模块的 1 MiB 响应限制;如果不可用,请改用由所有者控制的有界代理。仅在 Minimal display guard 之后添加私有审核显示——绝不要添加发件人或允许/拦截路由。
{
"sender": "Mapped draft sender display name",
"subject": "Mapped draft subject",
"body": "Mapped draft body"
}
结果、失败与限制
仅对映射的字符串进行分析;标准化与原始或出站电子邮件并不等同。响应过滤器仅检查状态以及核心结果/计费是否存在,且明确不进行完整的模式验证或强制执行。HTTP 错误使用 Break 以确保后续操作不会运行;切勿使用 Resume、虚假输出或故障保留路由。
Node.js SDK
0.1.1
仅限 Node.js 18.17+ 的服务器端 SDK。请从 npm 安装 @sendrepute/node 或使用可下载的压缩包 (tarball)。可选的 Nodemailer 适配器会保留您现有的传输方式。请在服务器环境中设置作用域 API 密钥和显式的 API 基础 URL,切勿将其用于浏览器端代码。
仅在查看定价并刻意启用付费分析同意后,才在 stream 阶段注册 createSendReputePlugin。咨询模式报告发现结果而不拦截投递。拦截模式强制执行 spamProbabilityThreshold;onApiFailure 可选择 allow 或 block,而因价格变动导致的拒绝将始终拦截投递。分类属于付费 API 操作。
下载 Node.js tarball
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
查看已验证的 npm 软件包
1. 安装
经过验证的 npm 软件包是 @sendrepute/node 版本 0.1.1;请将 registry 安装锁定为 @sendrepute/node@0.1.1。官网压缩包和锁定的公开仓库提供 0.1.1 版本的源码和构建。Nodemailer 是可选的,仅在需要传输适配器时才使用。该 SDK 支持面向 account、catalog、classification、AI 和 builders 的类型化 customer API 请求。请在 Node.js 服务器中使用它,切勿在浏览器捆绑包中使用。
npm install @sendrepute/node nodemailer
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
npm install @sendrepute/node@0.1.1
npm install nodemailer
2. 安全配置
从服务器机密库注入SENDREPUTE_API_KEY,并为托管的客户API设置下方明确的基准URL。不要将机密粘贴到命令、源文件或日志中。仅授予操作所需的作用域。此设置使用本地渲染传输,而非SMTP;此处的maxRetries设置为零,以使付费尝试变得谨慎。
export SENDREPUTE_API_BASE_URL=https://www.sendrepute.com/api
Nodemailer 设置
此示例配置了本地渲染传输,不调用 sendMail。通过配置的插件发送邮件将执行付费分析。仅在准备就绪时将本地传输替换为您现有的 SMTP 传输。
import nodemailer from "nodemailer";
import { SendReputeClient } from "@sendrepute/node";
import { createSendReputePlugin } from "@sendrepute/node/nodemailer";
const apiKey = process.env.SENDREPUTE_API_KEY;
const baseUrl = process.env.SENDREPUTE_API_BASE_URL;
if (!apiKey || !baseUrl) {
throw new Error("SENDREPUTE_API_KEY and SENDREPUTE_API_BASE_URL are required");
}
const client = new SendReputeClient({ apiKey, baseUrl, maxRetries: 0 });
const transporter = nodemailer.createTransport({
streamTransport: true,
buffer: true,
newline: "unix",
});
transporter.use("stream", createSendReputePlugin({
client,
policy: {
paidAnalysisConsent: true,
mode: "blocking",
spamProbabilityThreshold: 0.85,
onApiFailure: "block",
},
}));
3. 审慎使用
使用上方设置中的客户端。在显示同意操作前阅读账户和当前定价。仅在确认后通过经过身份验证的服务器操作调用classifyAfterConsent;它返回类型化的分类和计费响应。通过配置的Nodemailer插件发送也是一项付费分类操作。适配器要求 paidAnalysisConsent: true,并在注册前拒绝任何其他值;仅在授权后设置它。
// Uses client from the setup above; nothing calls this function automatically.
async function classifyAfterConsent({ sender, subject, body, confirmed }) {
if (confirmed !== true) throw new Error("Paid consent required");
return client.request("classifyCustomerEmail", { body: { sender, subject, body } });
}
async function readAccountAndPricing() {
return Promise.all([
client.request("customerGetAccount", {}),
client.request("customerGetPricingSettings", {}),
]);
}
标准与原生 VIP 构建器
免费的标准构建器可导入、验证、编译并将 MJML 导出为 HTML、MJML 或包含两者的 ZIP。独立的原生 VIP 构建器使用其专有的文档格式而非 MJML:其导入、验证、编译和导出操作需要有效的会员身份及所属的开放访问权限,且其 ZIP 包含三种 HTML CSS 变体。可选的 AI 生成是另行付费的,可生成可编辑的标准 MJML 或原生 VIP 设计;请显示当前的实际价格并传递已确认的 expectedPriceMillicents,切勿传递硬编码价格。ZIP 响应包含 archiveBase64,不含 html 字段:decodeExportBytes 会返回供您的应用程序保存的字节数据。这些处理端点不会抓取资源、持久化设计或发送电子邮件。
import { decodeExportBytes } from "@sendrepute/node";
async function exportStandardZip(mjml) {
const exported = await client.request("customerStandardBuilderExport", {
body: { mjml, format: "zip", filename: "newsletter.zip" },
});
return decodeExportBytes(exported);
}
async function generateNativeAfterConsent(prompt, expectedPriceMillicents, confirmed) {
if (confirmed !== true) throw new Error("Paid consent required");
return client.request("customerCreateVipEmailTemplate", {
body: { prompt, expectedPriceMillicents },
});
}
它还能做什么?
生成的 operation IDs 涵盖账户和定价读取、分类和手动编辑、AI重写/模板生成、VIP计划/状态/购买、原生模板/访问权限以及无状态的 standard/native 导入/导出。请参阅每种请求类型的源码示例和客户 API 参考,了解所需作用域及当前价格。目录读取不会购买访问权限。新的付费功能需要刻意限制作用域的令牌和明确的 UI 确认。
结果、失败与限制
SendReputeError 仅暴露 status、code 和 requestId;请仅保留这些安全的操作元数据。严禁记录正文、提示词、请求头或完整响应。AbortSignal 用于取消任务;timeoutMs 适用于单次尝试。有限重试具有操作感知能力,且收据保护受时间限制,而非无限次的精确一次计费。Nodemailer 的 advisory 模式仅报告而不拦截;blocking 模式独立使用 spamProbabilityThreshold 和 onApiFailure。请分别保留并测试您的实际传输层。
import { SendReputeError } from "@sendrepute/node";
async function readAccountSafely() {
try {
return await client.request("customerGetAccount", {});
} catch (error) {
if (error instanceof SendReputeError) {
console.error({
status: error.status, code: error.code, requestId: error.requestId,
});
}
throw error;
}
}
API 与方法参考
SendReputeClient 需要 apiKey 和 baseUrl;可选的 timeoutMs 默认为 30000(最大 300000),maxRetries 默认为 2(范围 0–10),fetch 接受兼容的服务器实现。request(operationId, input, { signal }) 返回该操作的类型化响应;input 包含其正文、路径和/或查询字段。无效配置将抛出 TypeError;API 失败则抛出包含 status、code、requestId 和 retryAfterMs 的 SendReputeError。decodeExportBytes 将 ZIP 导出转换为 Uint8Array,并拒绝非 ZIP 或无效的 base64 输入。OperationInput、OperationResponse 和生成的架构类型已为 TypeScript 调用者导出。
备选方案:包装低级 Nodemailer 传输层
createSendReputeTransport(existingTransport, options) 封装了现有的包含 send、可选 close 和 verify 方法的传输对象;它本身不是一个 sendMail 传输器。请在此时或 createSendReputePlugin 中二选一,以避免重复分析。两者都接受 client 和 policy 以及可选的 model、发送者字符串/解析器、signal 和 onDiagnostic。Diagnostic 回调无法更改投递。SendReputeNodemailerError 错误代码可区分无效的策略/消息、不支持的内容、垃圾邮件拦截和 API 失败拦截。发布的 npm 0.1.1 软件包和官网 0.1.1 下载版会将所有显示的内存中 text/plain 和 text/html 备选内容合并为一个有界的分类请求;在拦截模式下,它们会拒绝不支持的显示备选内容。原始消息、流、路径和 URL 仍不受支持。
import { createSendReputeTransport } from "@sendrepute/node/nodemailer";
function wrapExistingTransport(existingTransport) {
return createSendReputeTransport(existingTransport, {
client,
policy: {
paidAnalysisConsent: true,
mode: "advisory",
spamProbabilityThreshold: 0.85,
onApiFailure: "block",
},
onDiagnostic(diagnostic) {
console.info(diagnostic.kind, diagnostic.action);
},
});
}
所有 49 个客户 API 操作
展开操作以查看其确切的 SDK 输入类型、返回类型、作用域和已记录的 HTTP 状态。架构链接可在客户 API 参考文档中打开其完整的参数、响应字段和示例。这些封装器使用上方配置的客户端;执行需要确认,不会自动执行。读取操作不授权购买。数据变更、支付、访问关闭和付费 AI 需要相应的有意账户操作。
对单次聚合营销活动洞察分析进行报价
POST /v1/campaign-insights/quote
所需作用域: ai:generate
输入: { body: CustomerCampaignInsightsQuoteInput; }
返回: CustomerCampaignInsightsQuote
已记录的 HTTP 状态: 200, 400, 401, 403, 429, 503
参数、架构和 HTTP 示例
// The configured server-side client needs ai:generate scope.
// A quote is free; it does not authorize or start paid analysis.
const quote = await client.request("customerQuoteCampaignInsights", { body: {} });
// quote.priceMillicents: 10000 (USD 0.10) regular, 5000 (USD 0.05) active VIP.
// The quoted rate can change; obtain fresh consent before analysis.
使用 AI 分析聚合营销活动投递指标
POST /v1/campaign-insights/analyze
所需作用域: ai:generate
输入: { body: CustomerCampaignInsightsAnalyzeInput; }
返回: CustomerCampaignInsightsAnalysis
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 409, 413, 429, 502, 503
参数、架构和 HTTP 示例
import { randomUUID } from "node:crypto";
import type { CustomerCampaignInsightsMetrics } from "@sendrepute/node";
async function analyzeReviewedAggregate(
metrics: CustomerCampaignInsightsMetrics,
paidConsent: boolean,
) {
if (paidConsent !== true) throw new Error("Explicit price consent required");
// Aggregate counts/rates only: never include campaign IDs, contacts,
// message bodies or individual events. Requires ai:generate scope.
const quote = await client.request("customerQuoteCampaignInsights", { body: {} });
const body = {
analysisId: randomUUID(), // Persist this opaque ID and exact body for safe replay.
expectedPriceMillicents: quote.priceMillicents,
consent: true as const,
metrics,
};
// USD 0.10 regular or USD 0.05 active VIP; no automatic retry on a paid request.
// 409 PRICE_CHANGED requires a new quote and fresh consent, not blind retry.
// Aggregate input and result expire after 30 days.
return client.request("customerAnalyzeCampaignInsights", { body });
}
列出客户 API 分类器模型
GET /v1/models
所需作用域: models:read
输入: Record<string, never>
返回: CustomerApiModelsResponse
已记录的 HTTP 状态: 200, 401, 403, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function getCustomerApiModels(
input: OperationInput<"getCustomerApiModels">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"getCustomerApiModels">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("getCustomerApiModels", input, { signal });
}
获取客户 API 使用情况与限制
GET /v1/usage
所需作用域: usage:read
输入: Record<string, never>
返回: CustomerApiUsageResponse
已记录的 HTTP 状态: 200, 401, 403, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function getCustomerApiUsage(
input: OperationInput<"getCustomerApiUsage">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"getCustomerApiUsage">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("getCustomerApiUsage", input, { signal });
}
对一封客户电子邮件进行分类
POST /v1/classify
所需作用域: classify
输入: { body: CustomerClassificationInput; }
返回: CustomerClassificationResponse
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function classifyCustomerEmail(
input: OperationInput<"classifyCustomerEmail">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"classifyCustomerEmail">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("classifyCustomerEmail", input, { signal });
}
获取当前账户及其余额
GET /v1/account
所需作用域: account:read
输入: Record<string, never>
返回: Account
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetAccount(
input: OperationInput<"customerGetAccount">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetAccount">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetAccount", input, { signal });
}
获取当前账户的推荐链接及奖励活动
GET /v1/account/referrals
所需作用域: account:read
输入: { query?: { page?: number; pageSize?: number; }; }
返回: ReferralDashboard
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetAccountReferrals(
input: OperationInput<"customerGetAccountReferrals">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetAccountReferrals">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetAccountReferrals", input, { signal });
}
列出当前账户的额度账目明细
GET /v1/account/ledger
所需作用域: billing:read
输入: { query?: { kind?: "usage" | "payments"; limit?: number; offset?: number; }; }
返回: Array<CreditLedgerEntry>
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetCreditLedger(
input: OperationInput<"customerGetCreditLedger">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetCreditLedger">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetCreditLedger", input, { signal });
}
列出当前账户的 Bitcoin 发票
GET /v1/payments/invoices
所需作用域: billing:read
输入: { query?: { limit?: number; offset?: number; }; }
返回: Array<BitcoinInvoice>
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerListPaymentInvoices(
input: OperationInput<"customerListPaymentInvoices">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerListPaymentInvoices">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerListPaymentInvoices", input, { signal });
}
创建以 USD 计价的 Bitcoin 存款发票
POST /v1/payments/invoices
所需作用域: billing:write
输入: { body: InvoiceInput; }
返回: BitcoinInvoice
已记录的 HTTP 状态: 201, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerCreatePaymentInvoice(
input: OperationInput<"customerCreatePaymentInvoice">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerCreatePaymentInvoice">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerCreatePaymentInvoice", input, { signal });
}
隐藏未付款的 Bitcoin 发票
DELETE /v1/payments/invoices/{invoiceId}
所需作用域: billing:write
输入: { path: { invoiceId: string; }; }
返回: undefined
已记录的 HTTP 状态: 204, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerDeletePaymentInvoice(
input: OperationInput<"customerDeletePaymentInvoice">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerDeletePaymentInvoice">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerDeletePaymentInvoice", input, { signal });
}
GET /payments/methods
GET /v1/payments/methods
所需作用域: billing:read
输入: Record<string, never>
返回: Array<PaymentMethod>
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerListPaymentMethods(
input: OperationInput<"customerListPaymentMethods">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerListPaymentMethods">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerListPaymentMethods", input, { signal });
}
获取当前有效的 Bitcoin 存款奖励优惠
GET /v1/payments/deposit-offer
所需作用域: billing:read
输入: Record<string, never>
返回: DepositBonusOffer | null
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetActiveDepositOffer(
input: OperationInput<"customerGetActiveDepositOffer">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetActiveDepositOffer">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetActiveDepositOffer", input, { signal });
}
刷新当前账户发票的确认状态
POST /v1/payments/refresh
所需作用域: billing:write
输入: Record<string, never>
返回: Array<BitcoinInvoice>
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerRefreshMyPayments(
input: OperationInput<"customerRefreshMyPayments">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerRefreshMyPayments">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerRefreshMyPayments", input, { signal });
}
获取当前的公开分析与编辑价格
GET /v1/pricing
所需作用域: catalog:read
输入: Record<string, never>
返回: PricingSettings
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetPricingSettings(
input: OperationInput<"customerGetPricingSettings">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetPricingSettings">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetPricingSettings", input, { signal });
}
获取当前公开的 VIP 报价及价格对比
GET /v1/vip/plans
所需作用域: catalog:read
输入: Record<string, never>
返回: VipPlanQuote
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetVipPlans(
input: OperationInput<"customerGetVipPlans">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetVipPlans">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetVipPlans", input, { signal });
}
GET /vip
GET /v1/vip
所需作用域: vip:read
输入: Record<string, never>
返回: VipState
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetVip(
input: OperationInput<"customerGetVip">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetVip">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetVip", input, { signal });
}
POST /vip/purchase
POST /v1/vip/purchase
所需作用域: vip:purchase
输入: { body: CustomerVipPurchaseInput; }
返回: VipPurchaseResult
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerPurchaseVip(
input: OperationInput<"customerPurchaseVip">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerPurchaseVip">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerPurchaseVip", input, { signal });
}
针对已保存的分类,为修改和重新检查进行报价
POST /v1/rewrite/quote
所需作用域: rewrite
输入: { body: EditQuoteInput; }
返回: EditQuote
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerQuoteClassificationEdit(
input: OperationInput<"customerQuoteClassificationEdit">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerQuoteClassificationEdit">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerQuoteClassificationEdit", input, { signal });
}
针对已保存的分类,为修改和重新检查进行报价
POST /v1/classify/edit/quote
所需作用域: classify
输入: { body: EditQuoteInput; }
返回: EditQuote
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerQuoteManualClassificationEdit(
input: OperationInput<"customerQuoteManualClassificationEdit">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerQuoteManualClassificationEdit">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerQuoteManualClassificationEdit", input, { signal });
}
使用发件人姓名、主题和正文对邮件进行分类
POST /v1/classify/edit
所需作用域: classify
输入: { body: CustomerManualEditInput; }
返回: CustomerManualEditResult
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerClassifyEmail(
input: OperationInput<"customerClassifyEmail">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerClassifyEmail">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerClassifyEmail", input, { signal });
}
请求对选定的标记术语进行单独付费的 AI 重写,并对结果重新分类
POST /v1/rewrite
所需作用域: rewrite
输入: { body: CustomerAiRewriteInput; }
返回: AiRewriteResult
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 502, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerRewriteFlaggedTermsWithAi(
input: OperationInput<"customerRewriteFlaggedTermsWithAi">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerRewriteFlaggedTermsWithAi">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerRewriteFlaggedTermsWithAi", input, { signal });
}
根据已有的付费“全部重写”收据验证一份准确生成的最终草稿,无需再次扣费
POST /v1/rewrite/finalize
所需作用域: rewrite
输入: { body: { requestId: string; sender: string; subject: string; body: string; }; }
返回: { requestId: string; input: RewrittenClassificationInput; classification: ClassificationResult; }
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerFinalizeAiRewrite(
input: OperationInput<"customerFinalizeAiRewrite">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerFinalizeAiRewrite">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerFinalizeAiRewrite", input, { signal });
}
恢复已有的已完成付费 AI 重写收据
GET /v1/rewrite/result/{requestId}
所需作用域: rewrite
输入: { path: { requestId: string; }; }
返回: AiRewriteResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetAiRewriteResult(
input: OperationInput<"customerGetAiRewriteResult">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetAiRewriteResult">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetAiRewriteResult", input, { signal });
}
对单独付费的 AI 重写服务报出最高授权价格
POST /v1/rewrite/ai-quote
所需作用域: rewrite
输入: { body: AiRewriteQuoteInput; }
返回: AiRewriteQuote
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerQuoteAiRewrite(
input: OperationInput<"customerQuoteAiRewrite">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerQuoteAiRewrite">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerQuoteAiRewrite", input, { signal });
}
按确认的账户价格通过 AI 生成可编辑的标准 MJML 邮件设计
POST /v1/email-builder/ai-template
所需作用域: ai:generate
输入: { body: CustomerAiEmailTemplateInput; }
返回: AiEmailTemplateResult
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 502, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerCreateAiEmailTemplate(
input: OperationInput<"customerCreateAiEmailTemplate">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerCreateAiEmailTemplate">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerCreateAiEmailTemplate", input, { signal });
}
按确认的会员价格通过 AI 生成可编辑的内部 VIP 邮件设计
POST /v1/vip/email-template
所需作用域: ai:generate
输入: { body: CustomerVipEmailTemplateInput; }
返回: CustomerVipEmailTemplateResult
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 502, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerCreateVipEmailTemplate(
input: OperationInput<"customerCreateVipEmailTemplate">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerCreateVipEmailTemplate">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerCreateVipEmailTemplate", input, { signal });
}
免费开启标准邮件设计编辑器会话
POST /v1/email-builder/access
所需作用域: builder:write
输入: { body: CustomerEmailBuilderAccessInput; }
返回: EmailBuilderAccess
已记录的 HTTP 状态: 200, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerAccessEmailBuilder(
input: OperationInput<"customerAccessEmailBuilder">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerAccessEmailBuilder">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerAccessEmailBuilder", input, { signal });
}
GET /email-builder/access/{accessId}
GET /v1/email-builder/access/{accessId}
所需作用域: builder:read
输入: { query?: { designId?: string; }; path: { accessId: string; }; }
返回: EmailBuilderActiveAccess
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetEmailBuilderAccess(
input: OperationInput<"customerGetEmailBuilderAccess">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetEmailBuilderAccess">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetEmailBuilderAccess", input, { signal });
}
DELETE /email-builder/access/{accessId}
DELETE /v1/email-builder/access/{accessId}
所需作用域: builder:write
输入: { path: { accessId: string; }; }
返回: undefined
已记录的 HTTP 状态: 204, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerCloseEmailBuilderAccess(
input: OperationInput<"customerCloseEmailBuilderAccess">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerCloseEmailBuilderAccess">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerCloseEmailBuilderAccess", input, { signal });
}
POST /vip/email-builder/access
POST /v1/vip/email-builder/access
所需作用域: vip:builder
输入: { body: CustomerVipBuilderAccessInput; }
返回: VipBuilderAccess
已记录的 HTTP 状态: 201, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerCreateVipEmailBuilderAccess(
input: OperationInput<"customerCreateVipEmailBuilderAccess">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerCreateVipEmailBuilderAccess">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerCreateVipEmailBuilderAccess", input, { signal });
}
GET /vip/email-builder/access/{accessId}
GET /v1/vip/email-builder/access/{accessId}
所需作用域: builder:read
输入: { path: { accessId: string; }; }
返回: VipBuilderAccess
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetVipEmailBuilderAccess(
input: OperationInput<"customerGetVipEmailBuilderAccess">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetVipEmailBuilderAccess">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetVipEmailBuilderAccess", input, { signal });
}
DELETE /vip/email-builder/access/{accessId}
DELETE /v1/vip/email-builder/access/{accessId}
所需作用域: vip:builder
输入: { path: { accessId: string; }; }
返回: undefined
已记录的 HTTP 状态: 204, 400, 401, 402, 403, 404, 409, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerDeleteVipEmailBuilderAccess(
input: OperationInput<"customerDeleteVipEmailBuilderAccess">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerDeleteVipEmailBuilderAccess">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerDeleteVipEmailBuilderAccess", input, { signal });
}
Read permanent paid-result evidence with the original account and credential
GET /customer/paid-results/{recoveryId}
所需作用域: authenticated original credential
输入: { path: { recoveryId: string; }; }
返回: { status: "pending" | "succeeded" | "failed"; operation: "customerStandardAiGenerate" | "customerVipAiGenerate" | "customerVipBuilderAccess"; settlement: { kind: "paid_result" | "no_charge" | "confirmed_refund" | "unresolved"; accountId: string; credentialId: string | null; recoveryId: string; receiptId: string; chargeMillicents?: number; refundMillicents?: number; deletedAt?: string; }; result?: { [key: string]: unknown; }; error?: { [key: string]: unknown; }; }
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetPaidResult(
input: OperationInput<"customerGetPaidResult">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetPaidResult">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetPaidResult", input, { signal });
}
Read the authenticated account and credential identity before paid dispatch
GET /customer/paid-results/identity
所需作用域: authenticated credential
输入: Record<string, never>
返回: { accountId: string; credentialId: string; }
已记录的 HTTP 状态: 200, 401, 403, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerPaidResultIdentity(
input: OperationInput<"customerPaidResultIdentity">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerPaidResultIdentity">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerPaidResultIdentity", input, { signal });
}
Explicitly resolve an owned paid result with the original credential and service scope
POST /customer/paid-results/{recoveryId}/resolve
所需作用域: original ai:generate or vip:builder service scope
输入: { body: { action: "resolve"; reason: string; }; path: { recoveryId: string; }; }
返回: { status: "pending" | "succeeded" | "failed"; operation: "customerStandardAiGenerate" | "customerVipAiGenerate" | "customerVipBuilderAccess"; settlement: { kind: "paid_result" | "no_charge" | "confirmed_refund" | "unresolved"; accountId: string; credentialId: string | null; recoveryId: string; receiptId: string; chargeMillicents?: number; refundMillicents?: number; deletedAt?: string; }; result?: { [key: string]: unknown; }; error?: { [key: string]: unknown; }; }
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerResolvePaidResult(
input: OperationInput<"customerResolvePaidResult">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerResolvePaidResult">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerResolvePaidResult", input, { signal });
}
导入并编译标准 MJML 设计,不进行保存或发送
POST /v1/email-builder/import
所需作用域: builder:write
输入: { body: CustomerStandardBuilderInput; }
返回: CustomerStandardBuilderImportResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerStandardBuilderImport(
input: OperationInput<"customerStandardBuilderImport">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerStandardBuilderImport">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerStandardBuilderImport", input, { signal });
}
验证并编译标准 MJML 设计,不进行保存或发送
POST /v1/email-builder/validate
所需作用域: builder:write
输入: { body: CustomerStandardBuilderInput; }
返回: CustomerStandardBuilderValidateResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerStandardBuilderValidate(
input: OperationInput<"customerStandardBuilderValidate">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerStandardBuilderValidate">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerStandardBuilderValidate", input, { signal });
}
将标准 MJML 设计编译为 HTML,不进行保存或发送
POST /v1/email-builder/compile
所需作用域: builder:write
输入: { body: CustomerStandardBuilderInput; }
返回: CustomerStandardBuilderCompileResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerStandardBuilderCompile(
input: OperationInput<"customerStandardBuilderCompile">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerStandardBuilderCompile">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerStandardBuilderCompile", input, { signal });
}
将标准 MJML 设计导出为 HTML、MJML 或 ZIP,不执行发送
POST /v1/email-builder/export
所需作用域: builder:write
输入: { body: CustomerStandardBuilderInput; }
返回: CustomerStandardBuilderExportResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerStandardBuilderExport(
input: OperationInput<"customerStandardBuilderExport">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerStandardBuilderExport">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerStandardBuilderExport", input, { signal });
}
通过有效的会员身份和拥有的开放权限导入并编译原生 VIP 设计
POST /v1/vip/email-builder/import
所需作用域: vip:builder
输入: { body: CustomerNativeBuilderInput; }
返回: CustomerNativeBuilderImportResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerNativeBuilderImport(
input: OperationInput<"customerNativeBuilderImport">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerNativeBuilderImport">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerNativeBuilderImport", input, { signal });
}
通过有效的会员身份和拥有的开放权限验证并编译原生 VIP 设计
POST /v1/vip/email-builder/validate
所需作用域: vip:builder
输入: { body: CustomerNativeBuilderInput; }
返回: CustomerNativeBuilderValidateResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerNativeBuilderValidate(
input: OperationInput<"customerNativeBuilderValidate">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerNativeBuilderValidate">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerNativeBuilderValidate", input, { signal });
}
在拥有有效会员资格和开放访问权限的情况下,将原生 VIP 设计编译为 HTML
POST /v1/vip/email-builder/compile
所需作用域: vip:builder
输入: { body: CustomerNativeBuilderInput; }
返回: CustomerNativeBuilderCompileResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerNativeBuilderCompile(
input: OperationInput<"customerNativeBuilderCompile">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerNativeBuilderCompile">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerNativeBuilderCompile", input, { signal });
}
将原生 VIP 设计导出为 HTML 或包含三个变体的 HTML ZIP,且不进行发送
POST /v1/vip/email-builder/export
所需作用域: vip:builder
输入: { body: CustomerNativeBuilderInput; }
返回: CustomerNativeBuilderExportResult
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerNativeBuilderExport(
input: OperationInput<"customerNativeBuilderExport">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerNativeBuilderExport">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerNativeBuilderExport", input, { signal });
}
启动一次性标准或授权的原生 VIP 托管编辑器交接
POST /v1/email-builder/hosted-handoffs
所需作用域: builder:write
输入: { body: CustomerHostedBuilderHandoffInput; }
返回: CustomerHostedBuilderHandoff
已记录的 HTTP 状态: 201, 400, 401, 403, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerCreateHostedBuilderHandoff(
input: OperationInput<"customerCreateHostedBuilderHandoff">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerCreateHostedBuilderHandoff">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerCreateHostedBuilderHandoff", input, { signal });
}
列出 VIP 构建器模板
GET /v1/vip/email-builder/templates
所需作用域: vip:read
输入: Record<string, never>
返回: CustomerVipTemplateCatalog
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerListVipBuilderTemplates(
input: OperationInput<"customerListVipBuilderTemplates">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerListVipBuilderTemplates">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerListVipBuilderTemplates", input, { signal });
}
获取 VIP 构建器模板
GET /v1/vip/email-builder/templates/{templateId}
所需作用域: vip:read
输入: { path: { templateId: string; }; }
返回: CustomerVipTemplateDocument
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetVipBuilderTemplate(
input: OperationInput<"customerGetVipBuilderTemplate">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetVipBuilderTemplate">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetVipBuilderTemplate", input, { signal });
}
列出标准构建器模板
GET /v1/email-builder/templates
所需作用域: catalog:read
输入: Record<string, never>
返回: CustomerStandardTemplateCatalog
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerListStandardBuilderTemplates(
input: OperationInput<"customerListStandardBuilderTemplates">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerListStandardBuilderTemplates">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerListStandardBuilderTemplates", input, { signal });
}
获取标准构建器模板
GET /v1/email-builder/templates/{templateId}
所需作用域: catalog:read
输入: { path: { templateId: string; }; }
返回: CustomerStandardTemplateDetail
已记录的 HTTP 状态: 200, 400, 401, 403, 404, 413, 429, 503
参数、架构和 HTTP 示例
import type { OperationInput, OperationResponse } from "@sendrepute/node";
async function customerGetStandardBuilderTemplate(
input: OperationInput<"customerGetStandardBuilderTemplate">,
confirmed: boolean,
signal?: AbortSignal,
): Promise<OperationResponse<"customerGetStandardBuilderTemplate">> {
if (confirmed !== true) throw new Error("Explicit action confirmation required");
return client.request("customerGetStandardBuilderTemplate", input, { signal });
}
自托管 n8n 节点
0.1.0
需要 Node.js 20.19+ 以及已打补丁的自托管 n8n 安装,并提供 n8n-workflow >=2.39.3 <3。请勿强制安装到不兼容的旧版本主机中。请在您的 custom-node 目录中安装下载的 tarball 并重启 n8n。此未发布的节点无法通过 n8n Cloud 或 npm-name 社区安装获取。
付费许可默认处于关闭状态。每个许可项仅执行一次分类请求,且不具备自动重试机制。结果位于 sendrepute 命名空间下。在发送前请对 sendrepute.allowed 使用 IF 网关,并单独检查失败状态。咨询模式和拦截模式均会返回明确判定。节点本身不发送邮件。
下载 n8n tarball
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
在自托管的 n8n 主机上运行,然后使用您的常规进程管理器重启其 n8n 服务。确认 SendRepute 出现在节点选择器中。从 n8n 编辑器导入解压后的 package/examples/classify-email.workflow.json。此未发布包不支持 npm-name 社区节点安装及 n8n Cloud。
mkdir -p ~/.n8n/nodes
cd ~/.n8n/nodes
curl -fLO https://www.sendrepute.com/downloads/sendrepute-n8n.tgz
npm install ./sendrepute-n8n.tgz
tar -xzf sendrepute-n8n.tgz package/examples/classify-email.workflow.json
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/n8n-nodes-sendrepute.git
cd n8n-nodes-sendrepute
npm ci
npm run pack:check
npm pack --ignore-scripts
archive="$PWD/n8n-nodes-sendrepute-0.1.0.tgz"
mkdir -p ~/.n8n/nodes
cd ~/.n8n/nodes
npm install "$archive"
2. 安全配置
在 n8n 凭据存储中创建一个带有 classify 作用域客户密钥的 SendRepute API 凭据。严禁将其置于工作流 JSON 或表达式中。下方的 JSON 显示的是节点参数,而非完整的可导入工作流。映射发件人显示名称、主题和正文;选择 advisory/blocking 模式、阈值以及 open/closed 失败策略。在将 paidConsent 设为 true 之前请检查定价。每个获得授权的条目最多执行一次请求。
{
"operation": "classify",
"paidConsent": false,
"sender": "={{ $json.sender }}",
"subject": "={{ $json.subject }}",
"body": "={{ $json.body }}",
"decisionMode": "blocking",
"threshold": 0.8,
"failurePolicy": "closed"
}
3. 审慎使用
在 SendRepute 之后立即放置一个 IF 节点并使用此布尔条件。仅将 true 输出连接到您现有的邮件节点;将 false 路由至人工审核或停止。即使 allowed 为 true,也请单独检查 analysisStatus。包含的工作流在初始状态下已禁用付费授权且不包含凭据。SendRepute 本身从不发送邮件。
{{ $json.sendrepute.allowed === true }}
结果、失败与限制
成功的处理结果将用 analysisStatus、decision、allowed、recommendation、validated score 和 billing 字段替换 sendrepute 命名空间。失败时将忽略垃圾邮件分数并返回经过脱敏的 failureCategory/errorCode。closed 失败将执行拦截;open 失败将允许通过,但会将 analysisStatus 标记为 failed。advisory 成功将始终允许通过,无论 recommendation 为何。consent-off 将返回 not_run。不包含重试、收件人、附件、重写、模型选择器或自定义端点。更新后的源码依赖项审计报告为零发现;此为特定时间点的结果,并非安全认证。请保持自托管运行时已打补丁,并在安装前查阅 SECURITY.md。
Laravel 集成
0.1.0
适用于 PHP 8.2+ 及 Laravel 12–13。请使用本地 Composer 制品库安装 ZIP 包,或按照附带的 README 说明解压并配置 Composer 路径库。不承诺在 Packagist 上发布。
付费同意和邮件钩子默认禁用。即使启用,每条消息也必须通过 X-SendRepute-Classify: yes 明确选择加入。该标头会在投递前被移除。咨询和拦截模式具有独立的故障策略;除非刻意选择加入,否则密码重置和事务邮件将保持不受影响。
下载 Laravel ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
在您的 Laravel 应用程序内运行。这些命令用于解压下载内容并注册 Composer 路径仓库;这不属于 Packagist 安装。包发现机制会注册服务提供者,vendor:publish 会创建 config/sendrepute.php。请保持解压后的包目录对 Composer 可用。README 中还记录了另一种选择:artifact 仓库。
mkdir -p packages
curl -fL https://www.sendrepute.com/downloads/sendrepute-laravel.zip -o packages/sendrepute-laravel.zip
unzip packages/sendrepute-laravel.zip -d packages
composer config repositories.sendrepute path ./packages/sendrepute-laravel
composer require sendrepute/laravel:@dev
php artisan vendor:publish --tag=sendrepute-config
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
composer config repositories.sendrepute vcs https://github.com/sendrepute/sendrepute-laravel
composer require sendrepute/laravel:dev-main
php artisan vendor:publish --tag=sendrepute-config
2. 安全配置
将 SENDREPUTE_API_KEY 存储在服务器机密中。基础 URL 以 /api 结尾;客户端会自动追加 /v1/classify。要求精确的受信任主机匹配及经验证的 HTTPS。在您查阅定价并显式将其设为 true 之前,所示的两个开关均保持关闭。在 config/sendrepute.php 中独立选择 mail.mode、mail.spam_probability_threshold 和 mail.failure_policy。默认值为失败时允许的 advisory 模式。
SENDREPUTE_API_BASE_URL=https://www.sendrepute.com/api
SENDREPUTE_TRUSTED_HOSTS=www.sendrepute.com
SENDREPUTE_PAID_ANALYSIS_CONSENT=false
SENDREPUTE_MAIL_ENABLED=false
3. 审慎使用
仅将准确的选入 (opt-in) 请求头添加到经过慎重选择的 Mailable 类中,严禁添加到全局邮件回调。自动钩子需要全局开关和单条消息请求头同时开启。该请求头在投递前会被移除。除非经过显式测试,否则请勿将密码重置和关键通知纳入自动拦截。手动分类则可以像示例所示,通过解析 Classifier 契约并在每次调用时授予授权。
// Inside your deliberately opted-in Mailable:
public function headers(): \Illuminate\Mail\Mailables\Headers
{
return new \Illuminate\Mail\Mailables\Headers(text: [
'X-SendRepute-Classify' => 'yes',
]);
}
// Or classify manually inside an authenticated, explicitly confirmed action:
function classifyAfterConsent(bool $confirmed, string $subject, string $body): \SendRepute\Laravel\ClassificationResult
{
if (!$confirmed) {
throw new \RuntimeException('Paid consent required');
}
return app(\SendRepute\Laravel\Contracts\Classifier::class)->classify(
sender: 'Example Company',
subject: $subject,
body: $body,
paidAnalysisConsent: true,
);
}
API 与方法参考
从 Laravel 容器中解析 Classifier 接口。classify(string sender, string subject, string body, ?string model = null, bool paidAnalysisConsent = false) 返回 ClassificationResult。其公共字段包括 requestId、model、label、spamProbability、confidence、replayed 和 chargedMillicents。SendReputeException 提供脱敏的 category、HTTP 状态、API 代码和请求 ID。自动钩子是 MessageSending 上的 AnalyzeOutgoingMessage,其安全诊断为 ClassificationOutcome。此集成仅支持分类,不支持账户管理、支付、构建器或 AI 重写。
结果、失败与限制
ClassificationResult 包含经验证的结果和计费数据。MessageSending 钩子返回 false 以取消被拦截的消息;取消操作既不是 SMTP 错误也不是 MessageSent 事件。ClassificationOutcome 仅报告操作、分数和脱敏后的失败元数据,绝不包含消息内容。失败策略涵盖格式错误的输入/响应、身份验证、余额、频率限制和传输问题。不添加重试或队列。需要指定的发件人以及内存中的文本或 HTML 正文。
Mautic 草稿预检
0.1.0
针对使用 PHP 8.1+ 和 ext-curl 的单 Web 节点 Mautic 5.x 安装环境。不支持 Mautic 4、Mautic 6 及多节点集群。请将 SendReputeBundle 解压到您的 plugins 目录,按照附带的 README 文件重新加载插件并清除缓存。请配置凭据,并在服务器环境中明确确认 local-flock 锁定模式。
仅限管理员发起的、针对已保存草稿的付费咨询分析。全局选择加入、实体访问检查、CSRF 验证和单次使用确认保护每次请求。它不发送、重写或拦截电子邮件,且没有发送时强制执行。收件人替换项保持不展开状态;请先保存编辑器更改。
下载 Mautic ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
在 Mautic 根目录下使用与 Web 应用相同的 PHP 用户和环境运行,或者在重新加载插件前通过部署流程解压 ZIP。需要 Mautic 5.x、PHP 8.1+、ext-curl 以及单个 Linux/POSIX Web 节点。不支持 Mautic 4/6 和多节点集群;不声明任何实时的逐版本 (patch-by-patch) 安装认证。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-mautic.zip
unzip sendrepute-mautic.zip -d plugins
php bin/console mautic:plugins:reload
php bin/console cache:clear
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
git clone https://github.com/sendrepute/sendrepute-mautic.git
cd sendrepute-mautic
python3 package.py
2. 安全配置
在 Web 根目录之外创建所示的持久化账本 (ledger) 目录,所有者为 PHP 用户,模式为 0700。请勿使用 /tmp、临时容器、符号链接或不稳定的网络存储。在服务器端存储 SENDREPUTE_API_KEY。仅在单个 Web 节点提供共享进程锁时确认 local-flock。全局付费分析保持禁用状态 (0);仅在查阅定价和限制后将其设为 1。任何浏览器字段均不得提供凭据或端点。
SENDREPUTE_MAUTIC_PAID_ANALYSIS_ENABLED=0
SENDREPUTE_MAUTIC_ATOMIC_LOCK_MODE=local-flock
SENDREPUTE_MAUTIC_LEDGER_DIR=/var/lib/mautic/sendrepute-ledger
3. 审慎使用
请先保存编辑器更改。以具有该邮件访问权限的真实 Mautic 管理员身份,打开保存的草稿并选择 SendRepute preflight。查看确认信息并明确接受付费操作。该请求需要 CSRF 验证,以及一个绑定到已保存内容、有效期十分钟的一次性意图 (intent)。持久化锁定和不含内容的账本可防止在受支持的单节点上产生重复的并发支出。
结果、失败与限制
显示已验证的概率、标签、置信度以及实际扣费金额或收据重播。失败时不显示垃圾邮件判定,且不会自动重试。仅对保存的发件人显示名称、主题和正文进行分析;联系人替换项保持未展开状态。该插件不会重写草稿、发送电子邮件、阻止营销活动或执行发送时间策略。保存的草稿审核无法证明最终收件人渲染后的邮件情况。
Python 客户端与 Django 后端
0.1.0
需要 Python 3.9+。解压源代码 ZIP 并使用 pip 安装其目录。通用服务器客户端使用标准库;Django 是显式电子邮件后端的可选依赖项。此软件包未在 PyPI 上发布。
付费同意选项默认为关闭。Django 封装器保留了原始的 transport 和 message 对象。它分析合并了主正文、内联 text/plain 和 text/html 备用内容的单个受限字符串,不包括附件。阻塞模式会拒绝不支持或超限的显示内容。即使在允许策略下,身份验证失败默认也会进行拦截;请谨慎选择关键邮件行为。
下载 Python 源码 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
使用虚拟环境。通用客户端仅包含标准库;最后一条命令添加了可选的 Django 依赖项,对于 Flask、FastAPI 或其他通用服务器用途并非必须。该包从下载的源码目录安装,而非来自 PyPI。Python 3.9+ 是该包的最低版本要求;请选择互相支持的 Python/Django 版本。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-python.zip
unzip sendrepute-python.zip
python -m venv .venv
. .venv/bin/activate
python -m pip install ./sendrepute-python
python -m pip install './sendrepute-python[django]'
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
python -m pip install "sendrepute @ git+https://github.com/sendrepute/sendrepute-python.git@7d54935c4ae2db136800231136e4ea28d63118db"
python -m pip install "sendrepute[django] @ git+https://github.com/sendrepute/sendrepute-python.git@7d54935c4ae2db136800231136e4ea28d63118db"
2. 安全配置
通过服务器机密注入 SENDREPUTE_API_KEY。通用客户端默认使用规范的托管端点、验证的 HTTPS、无重定向且无重试。客户端同意默认为关闭;示例仅在确认检查后授予单次调用同意。端点覆盖需要明确的 HTTPS 源允许列表。返回的字典包含已验证的结果和计费数据,而不是发送决策。
import os
from sendrepute import SendReputeClient, SendReputeError
client = SendReputeClient(api_key=os.environ["SENDREPUTE_API_KEY"])
def classify_after_consent(sender, subject, body, confirmed=False):
if confirmed is not True:
raise ValueError("Paid consent required")
try:
return client.classify(
sender=sender, subject=subject, body=body,
paid_analysis_consent=True,
)
except SendReputeError as error:
# Safe metadata only; do not log message content or response bodies.
print(error.code, error.status, error.request_id)
raise
Django 邮件后端
在 SENDREPUTE_ORIGINAL_EMAIL_BACKEND 中保留现有后端,并保持其正常的 SMTP 设置。示例保持付费同意为关闭状态;仅在查看定价后将其设置为 True。advisory 模式允许分析成功;blocking 模式则与 SENDREPUTE_SPAM_THRESHOLD 进行比较。请慎重选择独立的失败策略。即便在 allow 策略下,身份验证错误默认也会导致阻止。示例遵循 README 默认值,并非针对关键邮件的失效开放(fail open)建议。
# Django settings.py
import os
EMAIL_BACKEND = "sendrepute.django.SendReputeEmailBackend"
SENDREPUTE_ORIGINAL_EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
SENDREPUTE_API_KEY = os.environ["SENDREPUTE_API_KEY"]
SENDREPUTE_PAID_ANALYSIS_CONSENT = False
SENDREPUTE_POLICY_MODE = "advisory"
SENDREPUTE_SPAM_THRESHOLD = 0.90
SENDREPUTE_FAILURE_POLICY = "allow"
SENDREPUTE_ALLOW_AUTH_FAILURE = False
SENDREPUTE_TIMEOUT = 10
3. 审慎使用
此函数仅在调用时发送。配置 Django 包装器并启用付费同意后,原始后端接收原始消息对象且保持不变。分类器接收一个组合了主要正文与内联 text/plain 和 text/html 备用内容的绑定字符串;附件和收件人不是单独的输入。请在调用前渲染模板。先使用本地测试后端,然后再使用您刻意配置的真实传输。
from django.core.mail import EmailMultiAlternatives
def send_reviewed_message(recipient):
message = EmailMultiAlternatives(
subject="Your requested summary",
body="Here is the summary you requested.",
from_email="Example Team <team@example.com>",
to=[recipient],
)
message.attach_alternative(
"<p>Here is the summary you requested.</p>", "text/html"
)
return message.send()
API 与方法参考
公共构造函数为 SendReputeClient(api_key, endpoint, allowed_origins, timeout, paid_analysis_consent),除 api_key 外均通过关键字传递。timeout 必须大于零且最多为 30 秒。classify 需要关键字参数 sender、subject 和 body;model 和单次调用的 paid_analysis_consent 为可选。Sender 为 1–320 个字符,subject 为 1–998 个,body 为 1–524,288 个,并受单独的编码请求限制。返回的 dict 包含 requestId、model、result 和 billing;result 包括 label、spamProbability、confidence、reasons 和可选的 contentAudit。billing 包含 chargedMillicents 和 replayed。错误包括 ConsentRequiredError、AuthenticationError、BalanceError、RateLimitError、TransportError 和 InvalidResponseError,均属于 SendReputeError。配置无效可能引发 ValueError。Django 后端公开 open()、close() 和 send_messages(email_messages),并返回原始后端的发送计数;它不添加任何通用的 API、构建器、重写或支付方法。
结果、失败与限制
阻止模式会拒绝不支持或超限的显示内容,而非仅分析其中较安全的子集。身份验证失败需要单独的显式覆盖方可允许。其他错误遵循所选的 allow/block 策略;fail_silently 控制是否抛出或跳过被阻止的错误。包装器不会排队、重试、交换传输、检查附件或渲染模板。通用客户端会抛出已脱敏的 SendReputeError 子类,包含 code/status/request_id;请勿记录消息正文。
Go 分类客户端
0.1.0
需要 Go 1.22+。仅限标准库的客户端支持分类,不支持邮件传输。请选择带有本地模块替换的可下载源代码 ZIP,或使用源代码备选方案中显示的已验证公共模块安装。
仅限标准库的服务器端分类,具有明确的付费同意、受限请求、验证的 HTTPS、拒绝重定向且无重试。它不发送电子邮件,也不做出发送/拦截决策。您的应用程序必须刻意选择阈值和故障行为,特别是对于关键的事务邮件。
下载 Go 源码 ZIP
公共源码仓库
完整 README 与示例
安全注意事项与已知限制
1. 安装
将源码提取到现有 Go 应用程序的目录中,并在那里运行模块命令。本地替换指向下载的模块;如果项目布局不同,请移动或调整该路径。仅在创建新应用时,才先使用您自己的模块名称运行 go mod init。此客户端不需要外部运行时模块。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-go.zip
unzip sendrepute-go.zip
# Run inside your existing application's module:
go mod edit -require=github.com/sendrepute/sendrepute-go@v0.0.0
go mod edit -replace=github.com/sendrepute/sendrepute-go=./sendrepute-go-v0.1.0
go mod tidy
备选方案:从公开源码安装
请使用此源码途径,而非上方的网站下载说明。仓库的 README 解释了剩余的激活与配置步骤;仅构建 ZIP 文件并不能安装插件。对于 Python,第二条命令将添加可选的 Django 支持。请将凭据保存在服务器机密中,并在启用付费功能前查阅安全注意事项。只有 Node 处于 npm 上;公开的 GitHub 仓库并不意味着已在 WordPress.org、n8n Cloud、Packagist 或 PyPI 发布。
go get github.com/sendrepute/sendrepute-go@bfd656f829618348232da506225a5d92587d48e2
2. 安全配置
从服务器机密注入 SENDREPUTE_API_KEY。所示函数在调用 confirmed=true 之前不执行任何工作;该调用可能会产生付费分类。它设置了 10 秒的 context 并使用规范的 HTTPS 端点。客户端同意默认为关闭;最后的 true 参数为本次请求授予同意。端点覆盖需要显式的 AllowedOrigins 条目;重定向将被拒绝。
package integration
import (
"context"
"errors"
"os"
"time"
sendrepute "github.com/sendrepute/sendrepute-go"
)
func Analyze(subject, body string, confirmed bool) error {
if !confirmed {
return errors.New("paid consent required")
}
client, err := sendrepute.NewClient(sendrepute.Config{
APIKey: os.Getenv("SENDREPUTE_API_KEY"),
})
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
result, err := client.Classify(ctx, sendrepute.ClassificationInput{
Sender: "Example Team", Subject: subject, Body: body,
}, true)
if err != nil {
return err
}
if result.Result.SpamProbability >= 0.90 {
return errors.New("review required")
}
return nil
}
3. 审慎使用
仅在查阅定价并明确同意后,从经过身份验证的应用程序调用 Analyze。0.90 阈值和 review 错误是示例应用策略,而非 SDK 默认值。在连接任何发送代码前,请决定错误意味着推迟、允许还是 closed 失败。客户端返回包含 Result.SpamProbability 和计费字段的类型化结果;它本身从不发送电子邮件或做出投递决策。
API 与方法参考
NewClient(Config) 返回 (*Client, error)。Config 接受 APIKey、Endpoint、AllowedOrigins、Timeout 和 PaidAnalysisConsent。Classify(ctx, ClassificationInput, consent) 返回 (*ClassificationResponse, error)。Input 字段包括 Sender、Subject、Body 和可选的 Model。Sender 为 1–320 个符文 (runes),subject 为 1–998 个符文,body 最多为 524,288 个 UTF-8 字节。类型化响应包含 RequestID、Model、Result 和 Billing;Billing 公开 ChargedMillicents 和 Replayed。Result 包括 Label、SpamProbability、Confidence、Reasons、FlaggedTerms 和可选的 ContentAudit。使用 errors.As 安全地检查 *Error;配置和 API 失败仍保持为错误,而非垃圾邮件评分。不存在账户、支付、构建器或重写方法。
结果、失败与限制
一次调用最多进行一次付费 HTTP 尝试且无重试。错误暴露安全类别、受限的代码/request ID 和状态,绝不暴露凭据、正文或网络细节。Context 时长、请求和响应大小均受限;畸形响应将被拒绝而非转换为评分。该客户端没有 MIME 解析、渲染、收件人、附件、队列、构建器、重写或 SMTP 功能。仅在需要时明确选择模型;否则应用账户默认值。
listmonk Custom HTTP Messenger
0.1.0
一个未发布的本地源软件包,适用于 Node.js 20+,旨在对接 listmonk 6.2.0 的 Custom HTTP Messenger 接口。该外部服务在分类后负责下游的 SMTP 投递;它既不是进程内插件,也不是 SMTP 预检代理。验证过程是隔离且离线的,并非已安装的 listmonk 部署或真实的 SMTP 服务商测试。
两个付费开关均默认关闭。该 messenger 接收一个完整渲染的正文,拒绝附件,检查最新定价,并要求严格的 Inbox 结果:标签为 inbox,垃圾邮件概率最高为 0.12,且标记的词汇为零。随后,它将通过其配置的 SMTP 连接构建并发送该经检查的正文。持久化回执可防止在出现被拦截、失败、处理中或不确定结果后自动重复操作。
下载未发布的 listmonk 源代码 ZIP
1. 安装
在专用信使主机上解压此未发布的网站源码 ZIP。查看 README.md 和 SECURITY.md,复制示例环境,并在配置前对服务器入口点进行语法检查。可下载的白名单 artifact 故意排除了仓库测试套件。不存在第三方运行时软件包。这不属于 listmonk 市场或进程内安装。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-listmonk.zip
unzip sendrepute-listmonk.zip
cd sendrepute-listmonk
cp config.example.env .env
node --check src/server.mjs
2. 安全配置
使用专用的非特权账户和权限模式为 0700 的持久化本地状态目录。在接受定价和非原子价格限制之前,请保持所示的三个安全开关处于 false 状态。仅将 SendRepute、信使 Basic Auth 和下游 SMTP 凭据存储在服务器机密中。请在受信任的反向代理处终止 HTTPS。
SENDREPUTE_ENABLED=false
SENDREPUTE_PAID_CONSENT=false
SENDREPUTE_ALLOW_NONATOMIC_PRICE_CONFIRMATION=false
SENDREPUTE_CONFIRMED_MAX_PRICE_MILLICENTS=
STATE_DIRECTORY=/var/lib/sendrepute-listmonk
SMTP_HOST=smtp.example.com
SMTP_PORT=465
SMTP_SECURE=true
3. 审慎使用
仅通过 HTTPS 和专用 Basic Auth 暴露 POST /v1/listmonk。在 listmonk Settings > Messengers 中,将其 URL 添加为 Custom HTTP Messenger,选择零重试,并仅针对需要进行检查和投递的活动选择它。请勿同时选择 listmonk SMTP:本服务会自行执行下游 SMTP 发送。
Custom HTTP Messenger URL: https://messenger.example.com/v1/listmonk
Authentication: dedicated Basic Auth username and password
Retries: 0
Select this messenger only. Do not also select SMTP for the campaign.
结果、失败与限制
已投递的重复项将返回成功,且不会再次进行分类或发送。任何被拦截 (blocked)、失败 (failed)、检查中 (inspecting)、发送中 (sending) 或不确定的回执都将拒绝再次发送。在出现不确定的 SMTP 结果后,请手动核对提供商日志和 listmonk 上下文;切勿仅为了强制重试而删除回执。当前的定价检查是实时的,但非原子性的,因为分类不接受 expectedPriceMillicents 字段。
Mailcoach Self-Hosted 适配器
0.1.0
一个针对 Laravel 12 上 Mailcoach Self-Hosted v10 的未发布本地 Composer 软件包。由于此工作区中不提供已授权的 spatie/laravel-mailcoach v10 核心,因此该软件包不声明已安装 Mailcoach v10 的端到端测试。真实的 Laravel 12 Mailer 测试涵盖了已记录的可取消 MessageSending 事件;许可证持有者必须在生产环境之前验证每一个准确的 Mailcoach 发送路径。
enabled、paid-consent 和当前定价确认开关均默认关闭。一旦启用,该挂钩将应用于通过该 Laravel 邮寄器的每条消息,而不仅仅是 Mailcoach 命名的路由。它会分析已渲染的 Symfony Email 备选方案并可以取消传输。默认采用故障关闭(fail-closed)机制;允许分析失败是一个单独的审慎策略。
下载实验性 Mailcoach 源码 ZIP
1. 安装
将下载的未发布 ZIP 放入许可的 Mailcoach 应用程序可访问的私有 Composer artifact 目录中。注册该本地 artifact 仓库,要求 0.1 版本系列,提交使用的 lockfile,并可选择发布配置。这不是 Packagist 安装。许可证持有者必须针对确切的 Mailcoach Self-Hosted v10 版本运行验证。
mkdir -p packages
curl -fL https://www.sendrepute.com/downloads/sendrepute-mailcoach.zip -o packages/sendrepute-mailcoach.zip
composer config repositories.sendrepute artifact packages
composer require sendrepute/mailcoach:^0.1
php artisan vendor:publish --tag=sendrepute-mailcoach-config
2. 安全配置
最初请保持所有三个开关为关闭状态。将 API key 存储在服务器机密中,并配置账户侧的支出上限。当前的 classify 操作没有原子级的 expectedPriceMillicents 防护,因此第三个开关明确接受当前的 API 定价,而非承诺锁定报价。请独立配置 threshold 和 allow/block 失败策略。
SENDREPUTE_MAILCOACH_ENABLED=false
SENDREPUTE_MAILCOACH_PAID_CONSENT=false
SENDREPUTE_MAILCOACH_ACCEPT_CURRENT_API_PRICING=false
SENDREPUTE_API_BASE_URL=https://www.sendrepute.com/api
3. 审慎使用
包发现机制会注册一个 Laravel MessageSending 监听器。应用程序代码中无需进行每场活动调用:在专用的 Mailcoach 安装中故意启用时,它会在传输前立即检查通过该 Laravel mailer 发送的每个 Symfony Email。在混合 Laravel 应用程序中,宿主程序的邮件也会被覆盖。
结果、失败与限制
该适配器提交发件人显示名称、主题以及每个非空的内存中 text/plain 或 text/html 备选内容,同时排除收件人、地址、附件、信封数据和原始 MIME。默认情况下,缺失或不支持的内容、格式错误的响应以及 API 失败将导致拦截。离线核心测试会练习真实的 Laravel Mailer 取消操作,但获得许可的 Mailcoach 活动、自动化、事务性邮件和测试消息路由仍保持未验证状态。
Brevo 受控发送流程
0.1.0
一个未发布的本地 Node.js 20+ 源码包,围绕 Brevo 的事务性 POST /v3/smtp/email 操作实现了一个显式的服务端发送 API。它不会拦截 Brevo 仪表板发送、营销活动、自动化、SMTP 中继或通过其他 SDK 发起的调用。测试是受控且离线的;它们不提供对实时 Brevo 账户的认证。
付费同意默认为关闭。仅接受固定的内联文本和 HTML 消息;远程模板、参数、定时发送、消息版本和由 URL 支持的内容将被拒绝。经过检查的精确不可变快照将发送至 Brevo。持久的 sendKey 账本会阻止重复和模棱两可的重试,且不确定的服务商结果需要操作员进行对账。
下载未发布的 Brevo 源码 ZIP
1. 安装
将未发布的源码 ZIP 解压到服务器应用程序中,查看其 README 和安全说明,并对 src/index.mjs 进行语法检查。可下载的白名单 artifact 故意排除了仓库测试套件。从 src/index.mjs 导入 SendReputeBrevo;这不属于 npm 或 Brevo 市场安装。需要 Node.js 20+,且没有运行时依赖项。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-brevo.zip
unzip sendrepute-brevo.zip
cd sendrepute-brevo
node --check src/index.mjs
2. 安全配置
在接受当前定价和非原子化价格限制之前,请保持 paidConsent 为 false。将两个 API keys 保留在服务器机密中,并在持久的单主机存储上使用私有持久账本目录。expectedPriceMillicents 必须等于最新获取的最大值,但 classify 扣费目前尚无法原子化地强制执行该值。
const integration = new SendReputeBrevo({
sendreputeApiKey: process.env.SENDREPUTE_API_KEY,
brevoApiKey: process.env.BREVO_API_KEY,
paidConsent: false,
expectedPriceMillicents: approvedMaximum,
ledgerDirectory: "/var/lib/my-app/sendrepute-brevo",
});
3. 审慎使用
仅从应当同时进行分类和投递的受控服务器路径调用 send。为同一意向电子邮件的每次尝试重用一个稳定的 sendKey。提供固定的内联内容;请勿提供 Brevo 模板 ID、可变参数、调度或邮件版本。在其他地方进行的发送将完全绕过此包装器。
await integration.send({
sendKey: durableBusinessEventId,
message: {
sender: { name: "Example Shop", email: "orders@example.com" },
to: [{ email: recipient }],
subject,
textContent,
htmlContent,
},
});
结果、失败与限制
在阈值内的 Inbox 结果允许为相同的不可变快照发起一次 Brevo 事务性 API 请求。在提供商调度之前,账本状态会更改为 delivery-unknown。超时、断开连接、格式错误的成功响应、崩溃以及提供商拒绝均不会自动重试;在进行任何手动决策前,请根据 Brevo 记录进行核对。
BigMailer 受控发送流
0.1.0
一个未发布的本地 Node.js 24+ 封装程序,用于显式的 BigMailer 事务性 API 调用。它不会安装到 BigMailer 中,也不会拦截仪表板和无关的 API 发送。由于 BigMailer 拥有远程可编辑的活动内容,该封装程序无法证明活动内容在审核与投递之间是否与调用者提供的渲染快照保持一致。
enabled、付费同意和远程模板限制确认均默认关闭。调用者必须提供并哈希一个完整的渲染快照,在操作上冻结匹配的远程活动,并提供一个持久的 deliveryKey。在分类前会重新检查定价,但当前的分类 API 没有原子的 expected-price 字段。重复、拦截、拒绝和歧义的投递状态绝不会自动重发。
下载实验性 BigMailer 源码 ZIP
1. 安装
将此未发布的源码 ZIP 解压到受控的 Node.js 24+ 服务器应用程序中,并查阅 README.md 和 SECURITY.md。直接从 src 导入包装器和文件投递存储。这不属于 npm 或 BigMailer 市场安装,且不包含任何第三方运行时依赖。
curl -fLO https://www.sendrepute.com/downloads/sendrepute-bigmailer.zip
unzip sendrepute-bigmailer.zip
cd sendrepute-bigmailer
node --check src/index.mjs
node --check src/file-delivery-store.mjs
2. 安全配置
在审核完成前,请保持 enabled、paidConsent 和 remoteTemplateSnapshotLimitationAcknowledged 为 false。API 密钥、品牌和活动的 UUID 仅可存储在服务器端。将 FileDeliveryStore 部署在私有持久化存储中。将审核后的最新定价复制到 expectedPricing,需了解当前的 classify API 无法对其进行原子锁定。
const integration = createBigMailerIntegration({
enabled: false,
paidConsent: false,
remoteTemplateSnapshotLimitationAcknowledged: false,
sendReputeApiKey: process.env.SENDREPUTE_API_KEY,
bigMailerApiKey: process.env.BIGMAILER_API_KEY,
brandId,
campaignId,
expectedPricing,
deliveryStore: new FileDeliveryStore("/var/lib/my-app/bigmailer-deliveries.json"),
});
3. 审慎使用
对于每个受控的 API 发送,请提供一个稳定的 deliveryKey、所有显示的 text/plain 和 text/html 备选项、准确的渲染快照以及 snapshotDigest(snapshot)。仅当操作控制冻结了与该快照匹配的 BigMailer 活动修订版本时,才确认远程模板限制。仪表板和不相关的 API 发送将跳过此包装器。
await integration.send({
deliveryKey: durableBusinessEventId,
snapshot,
snapshotSha256: snapshotDigest(snapshot),
email: recipient,
variables,
});
结果、失败与限制
文件存储在分类之前保留投递密钥。重复、冲突、阻止、拒绝和模糊的投递结果无法自动重新发送。BigMailer 的发送端点接受合并数据而非经过检查的正文,因此成功的分类并非可变远程活动内容仍然匹配的证明;当需要精确耦合时,请使用其他提供商。
隐私与付费操作
分析会将发件人显示名称、主题和邮件正文发送给 SendRepute。收件人和附件不会被单独传输,但正文中包含的内容会被传输。请确保凭据私密并禁用请求/主体日志记录。不提供收件箱投递或送达保证。
分类功能是付费的。在授予许可之前,请阅读当前的定价和您的账户支出限额。相同的账户/内容/模型请求可能会在 24 小时内重现回执;更改内容或模型可能会产生新费用。请勿假设重试是免费的。AI 重写在进行付费提交前,需要针对所选的父回执、模式和条款获取最高费用报价;请轮询进行中的回执,并使用原始请求 ID 恢复已完成的结果,而不是启动另一个请求。“全部重写”可以验证一份准确的最终渲染草稿,而不会产生额外扣费。AI 模板生成和原生 VIP 访问权限分别定价;标准构建器处理是免费的。任何分析、重写或构建器结果均不保证投递、收件箱送达率或合规性。
离线验证并非对每个框架、插件或传输版本的认证。请阅读随附的安装与安全说明,在刻意配置前保持付费分析处于禁用状态,并在为关键邮件启用前测试您选择的故障策略。
查看定价
客户 API 参考
咨询集成支持