需要电子邮件 - 交付 - 诺
这个 neeto-email-delivery-nano 作为新纳米的真相来源
结构、配置、数据等.
目录
用主机应用程序开发
发动机
安装
-
将此行添加到您的应用程序的 Gemfile 中 :
source "NEETO_GEM_SERVER_URL" do # ..existing gems gem 'neeto-email-delivery-engine' end -
然后执行:
bundle install -
将此行添加到您的应用程序
config/routes.rb文件mount NeetoEmailDeliveryEngine::Engine, at: "/neeto_email_delivery" -
在表格中添加所需的迁移
db/migrate文件夹。 运行以下 命令复制从引擎到主机应用程序的迁移.bundle exec rails neeto_email_delivery_engine:install:migrations bundle exec rails db:migrate -
在主机中包含 Neeto 电子邮件 交付引擎 :: 交付方法选择器 应用程序( mailer.rb)
class ApplicationMailer < NeetoCommonsBackend::ApplicationMailer
+ include NeetoEmailDeliveryEngine::DeliveryMethodSelector
# ...
end
6. Include NeetoEmailDeliveryEngine::HasEmailIntegrations in the host's owner model and override the `email_delivery_redirect_url` and `get_organization_id` method
```diff
class Form < ApplicationRecord
# ...
+ include NeetoEmailDeliveryEngine::HasEmailIntegrations
# ...
def email_delivery_redirect_url
# "/admin/..."
end
def get_organization_id
# organization_id
end
end
- 添加
config/initializers/neeto_email_delivery_engine.rb并添加所有者 课。 示例
NeetoEmailDeliveryEngine.owner_class = "Form"
- 覆盖
load_owner基础控制器的私人方法.
# app/overrides/controllers/neeto_email_delivery_engine/base_controller_override.rb
NeetoEmailDeliveryEngine::Api::V1::BaseController.class_eval do
private
def load_owner
# @owner = current_user
# OR
# @owner = @organization.forms.find(params[:owner_id])
end
end
- 覆盖
send_disconnection_email财务报告和审定财务报表send_delivery_failure_email私人方法 -
- app/overrides/service/neto email 交付 引擎/base email service override.rb (英语)
send_disconnection_email 当账户本身变成
无法使用,例如证书被拒绝时,账户已经
运行时已断开 .
send_delivery_failure_email 当提供者永久拒绝
单个邮件, 例如当信件超过大小限制时 。 账户
仍然可以连接和工作,所以只需要报告一个电子邮件.
在这种情况下没有退后发送:提供者给予永久拒绝
所以通过尼多的账户重新发行
又拒绝了 执行这个钩子,否则一个被拒绝的电子邮件就会被报告,并且
店主从来不知道它没有交付.
两个钩子都接收每个供应商 所以 type 这是其中之一 gmail, (中文(简体) ), outlook 或者说
smtp 每一个.
reason 每个钩子都不同,每个钩子都有一个
形状,所以没有主机方法可以键入:
send_disconnection_email总是收到一个 符号 分类 账户被放弃——其中之一:authentication_failure, (中文(简体) ),:authorization_revoked, (中文(简体) ),:invalid_configuration或者说:unknown_error处理 它是一个检索键, 总是保留一个倒置的分支, 因为可能增加更多.send_delivery_failure_email总是得到提供者自己的 字符串, (中文(简体) ), 例如"552 5.3.4 Message size exceeds fixed maximum message size"这是 打算逐字向账户所有者显示;它是他们自己的提供者 描述他们自己的信息,而不是尼托基础设施的细节.
失败如何分类
每个供应商都会把故障分到三个桶里 只有中间一个 销毁账户.
| 弹夹 | SMTP 软件 | 邮件 | 展望 |
|---|---|---|---|
| 瞬间——再审,账号未受影响 | 4x (中文(简体) )Net::SMTPServerBusy),超时 | 429和403份配额答复 | 429, 5xx, 瞬间信号刷新故障 |
| 账户无法使用 - 断开 | 53个(Net::SMTPAuthenticationError,无效的 SSL 配置 | 第401和403段 PERMISSION_DENIED 编号 : failedPrecondition 未启用邮件服务 | 页:1, invalid_grant 刷新时 |
| 消息被拒绝——报告,账户存续 | 其他 5xx (中文(简体) )Net::SMTPFatalError(中文(简体) ) | 其他 4xx,例如,信息大小过大或收件人畸形 | NON_DISCONNECTION_ERROR_CODES,比如说. ErrorMessageSizeExceeded |
默认比表格更重要 。 未识别出故障即视为 信件级别问题,而不是账户级别问题,因为删除工作 合并对客户来说比报告一个失败的电子邮件要昂贵得多. 在账户一级列表中有意添加;不要让任何东西落入其中 无意中.
NeetoEmailDeliveryEngine::BaseEmailService.class_eval do
private
def send_disconnection_email(integrable, organization_id, type, reason: nil)
# Call your mailer logic
# type: gmail, outlook, smtp
# reason: why the account was disconnected, e.g. :authentication_failure
# DisconnectionMailer
# .with(organization_id: organization_id)
# .send_email(user: integrable, type:, reason:)
# .deliver_later
end
def send_delivery_failure_email(integrable, organization_id, type, reason: nil)
# Call your mailer logic
# type: gmail, outlook, smtp
# reason: the rejection reported by the provider, e.g.
# "552 5.3.4 Message size exceeds fixed maximum message size"
# DeliveryFailureMailer
# .with(organization_id: organization_id)
# .send_email(user: integrable, type:, reason:)
# .deliver_later
end
end
- 在应用程序中添加邮件枪入侵配置. rb
config.action_mailbox.ingress = :mailgun
-
添加
:gmail财务报告和审定财务报表:outlook到自定义( o) 配置/ 初始化器/ extend user omniauth. rb. -
以下env变量需要添加到主机应用程序中.
GOOGLE_OAUTH_CLIENT_ID
GOOGLE_OAUTH_CLIENT_SECRET
MICROSOFT_OAUTH_CLIENT_ID
MICROSOFT_OAUTH_CLIENT_SECRET
SPARKPOST_SENDING_DOMAINS_KEY
## The following are needed, but they should already be present in the host application. So ensure that they are present.
APP_LOCAL_TO_INTERNET_PROXY_URL
CONNECT_PRIVATE_KEY
CONNECT_PUBLIC_KEY
MAILGUN_INGRESS_SIGNING_KEY (needed for our custom logic to verify the Outlook account.)
- 在秘密中 yml 添加
sparkpost:
sending_domains_key: <%= ENV['SPARKPOST_SENDING_DOMAINS_KEY'] %>
sending_domains_user_name: SMTP_Injection
sending_domains_address: smtp.sparkpostmail.com
-
确保域
<app-name>email.com(生产)和<app-name>email.net在Mailgun中正确设置( stage)以接受 收到的邮件 例:对NeetoForm来说,这将是需要formemail.com (制作)和需要formemail.net (stage). -
添加以下内容到应用程序Mailbox
routing /neetoemaildelivery/i => "neeto_email_delivery_engine/inbound"
- 覆盖
skip_rate_limits?页:1NeetoEmailPipelineEngine::MailDeliveryJob如果用户配置了SMTP集成,则跳过速率限制.
# app/overrides/neeto_email_pipeline_engine/jobs/mail_delivery_job_override.rb
NeetoEmailPipelineEngine::MailDeliveryJob.class_eval do
private
def skip_rate_limits?
is_smtp_email_job?
end
def is_smtp_email_job?
return false if params[:delivery_account].blank?
account_klass, account_id = params[:delivery_account].values_at(:klass, :id)
delivery_account = account_klass.constantize.find_by(id: account_id)
delivery_account.present? &&
delivery_account.is_a?(NeetoEmailDeliveryEngine::SmtpAccount) &&
delivery_account.active?
end
end
前端软件包
安装
-
添加数据
neeto-email-delivery-frontend软件包到package.jsonyarn add @bigbinary/neeto-email-delivery-frontend
发展指示
检查 前端软件包开发指南 用于开发前端软件包的分步指令.
使用量
导出组件
电子邮件传送Screen
| Prop | 类型 | 说明 |
|---|---|---|
canManageIntegrations | 布尔 | 此特性的授权/许可检查 . |
ownerId | uuid/字符串 | 车主的身份证. |
indexRoute | 字符串 | 电子邮件发送页面索引路由 . |
ownDomainSetupRoute | 字符串 | SparkPoost"Own Domain"设置组件的嵌入路由. |
ownDomainVerifyRoute | 字符串 | SparkPoost"验证域"组件的已嵌入路由 . |
Sparkpost 域设置
| Prop | 类型 | 说明 |
|---|---|---|
canManageIntegrations | 布尔 | 此特性的授权/许可检查 . |
ownerId | uuid/字符串 | 车主的身份证. |
alreadyVerifiedRoute | 字符串 | “ 已核实” 页面的路径; 通常为电子邮件发送索引 . |
verifyRoute | 字符串 | 显示 DKIM 记录的校验页面的路径 . |
onCancelRoute | 字符串 | 取消时重定向用户的路线;一般是电子邮件发送索引. |
Sparkpost 域认证
| Prop | 类型 | 说明 |
|---|---|---|
canManageIntegrations | 布尔 | 此特性的授权/许可检查 . |
ownerId | uuid/字符串 | 车主的身份证. |
emailDeliveryIndexRoute | 字符串 | 电子邮件发送页面索引路由 . |
火花站验证的业务逻辑
-
如果域未在 Sparkpost 上创建
- 在火花点上创建域
- 向用户提交 DKIM 值, 并要求用户将其添加到 DNS 中
- 出示一个验证按钮.
- 关于核查,我们给NeetoTower发出API呼叫,有域和当前 组织.
-
如果在 Sparkpost 上创建了域而未验证, 那么
- 向用户提交 DKIM 值, 并要求用户将其添加到 DNS 中
- 出示一个验证按钮.
- 关于核查,我们给NeetoTower发出API呼叫,有域和当前 组织.
-
如果在 Sparkpost 上创建并验证域名, 那么( 新流量)
- 给 NeetoTower 打电话检查域名 + 当前组织 guid 记录是存在的.
- 如果来自 NeetoTower 的回复表示域名 + 当前组织 guid 已存在,然后自动批准域.
- 如果来自 NeetoTower 的回复表示域名 + 当前组织 guid
不存在,那么
- 显示自定义的 TXT 值并请求用户将其添加到他们的 DNS 中.
- 显示检查以上 TXT 值的验证按钮 .
- 关于核查,我们给NeetoTower发出API呼叫,有域和当前 组织.
火花站域状态
- 待定 -- -- 火花站域创建时的默认状态 .
- sp dkim 已校验 - 域名的 DKIM 记录已在 Sparkpost 中被校验 .
- sp dkim 未验证 - 域名的 DKIM 记录尚未被校验 火花点.
- 失败 - 当任何用于校验的 Sparkpost API 失败时失败状态 .
- txt 未验证 - 当一个域被验证为 不同的组织。 我们存储域+组织映射到 涅盘多尔. 如果 NeetoTower 中没有域+组织映射 但是域名在Sparkpost上被验证 然后我们用这个状态来表示 该域需要通过验证 TXT 记录来进一步验证。 如果 域+组织映射已经存在于 NeetoTower, 然后我们直接 标记域为活动.
- 活动 - 最终状态。 如果活动, 那么我们将允许通过 此域.
展望一体化流程
确保 MAILGUN_INGRESS_SIGNING_KEY 环境变量设置在
主机应用程序. 这是核查《展望》账户所需的.
-
从 UI 连接展望
- 用户点击主机应用程序中的"Connect Outlook"动作.
- 引擎将用户重定向到 Microsoft OAuth 使用
User.Read, (中文(简体) ),Mail.Send,以及offline_access范围,以便我们能发送电子邮件和 刷新符号,不用换回.
-
存储 Outlook 账户并发送校验邮件
- 在OAuth成功回电后,
NeetoEmailDeliveryEngine::Integrations::Outlook::ConnectService创建 或更新一个OutlookAccount并确定其地位:inactive。 。 。 . - 服务生成一个
test_email_token并存于帐中 元数据(以及时间戳和主题),并通过NeetoEmailDeliveryEngine::Outlook::SendEmailService使用微软 图sendMailAPI 到生成的验证地址, 如outlook.neetoemaildelivery@<application_name>email.(com|net)。 。 。 .
- 在OAuth成功回电后,
-
入境核查处理
- 输入核查地址的电子邮件由
NeetoEmailDeliveryEngine::InboundMailbox。 。 。 . - 该信箱按收件人和
主题,取出
test_email_token从主体,并找到 相应OutlookAccount。 。 。 . - 如果邮件来自合法用户邮箱,则账户不是
已激活,邮箱将账户状态更新到
active如果 发送者看起来像一个Outlook 阴影账户(例如:.[email protected],邮箱将账户标记为shadow_account并标记为forbidden而不是启动它.
- 输入核查地址的电子邮件由
断开电子邮件
如果电子邮件发送失败 使用 Gmail/ Outlook 集成, 我们 连接集成并发送电子邮件。 为了定制电子邮件 主机应用程序需要添加一个覆盖,以便控制 寄来者.
覆盖上述安装第9步中提及的base email service.rb.
自动化测试终点
该引擎暴露了测试终点
/neeto_email_delivery/api/v1/testing 用于自动化测试。 他们让
测试连接 Gmail/ Outlook 并校验没有浏览器 OAuth 的发送邮件
流动,在生产中被禁用。 参见
测试终点指南 联 合 国
请求/回复形状和获取刷新符号的指示.
## Instructions for Publishing
Consult the
[building and releasing packages](https://neeto-engineering.neetokb.com/articles/building-and-releasing-packages)
guide for details on how to publish..