需要电子邮件-通知-nano
这个 neeto-email-notifications-nano 是一个针对尼托生态系统的电子邮件通知管理综合解决方案。 与相关React前端组件一起作为Ruby on Rails引擎执行(@bigbinary/neeto-email-notifications-frontend),它为管理所有neto应用程序的电子邮件通知提供了统一的接口.
目录
安装( 后端引擎)
遵循这些步骤,整合 neeto-email-notifications-engine 输入您的主机 Rails 应用程序 :
1. 添加宝石
在您的应用程序中添加宝石 Gemfile数字 :
# Gemfile
source "NEETO_GEM_SERVER_URL" do
gem "neeto-email-notifications-engine"
end
2. 安装宝石
运行捆绑器以安装宝石及其依赖性 :
bundle install
3. 安置移民
在表格中添加所需的迁移 db/migrate 文件夹。 运行以下
命令生成迁移.
bundle exec rails g neeto_email_notifications_engine:install
这将产生迁移来创建
neeto_email_notifications_engine_email_notifications 表格,该表格将保留
用于电子邮件通知的数据,并且有 custom_fields 包含
自定义属性.
4. 管理移徙
将移入数据库 :
bundle exec rails db:migrate
5. 上发动机
将引擎路径添加到您的应用程序 config/routes.rb数字 :
# config/routes.rb
mount NeetoEmailNotificationsEngine::Engine, at: "/neeto_email_notifications"
注:挂载点和基址必须是 /neeto_email_notifications 并且不能更改为其它路径.
说明: 发动机使用
liquid用于模板渲染的宝石。 这将自动安装为 a 依赖性.
配置( 后端引擎)
1. 初始化设置
创建初始化文件 config/initializers/neeto_email_notifications_engine.rb 来配置引擎 :
# config/initializers/neeto_email_notifications_engine.rb
NeetoEmailNotificationsEngine.configure do |config|
# IMPORTANT: Configure which model types can hold email notifications.
# This configuration is MANDATORY for the engine to work properly.
config.allowed_notification_holder_types = ["PaymentPlan", "SomeOtherModel"]
end
允许的 通知 持有者 类型配置是强制的 。 如果无法配置, 将会在创建电子邮件通知时出现校验错误 .
2. 模式
NeetoEmailNotificationsEngine::EmailNotification (单位:千美元)源代码(中文(简体) )
主要协会:
belongs_to :notification_holder, polymorphic: true
has_rich_text :message
密钥验证 :
notification_holder_type必须在配置中allowed_notification_holder_types。 。 。 .subject, (中文(简体) ),message需要时is_enabled这是真的.send_from需要时必须是有效的电子邮件格式.- 所有电子邮件字段( E)
notify_emails, (中文(简体) ),notify_cc_emails, (中文(简体) ),notify_bcc_emails)被验证为适当的电子邮件格式.
可用方法:
message_body_content: 返回丰富文本信息的 HTML 内容.custom_field_key: 子类必须执行的抽象方法.notification_type: 从自定义字段返回通知类型.disabled_by_user?:检查通知是否通过用户动作被禁用.
设置主机应用程序模型
确保其中指定的模式 allowed_notification_holder_types 界定正确的协会:
每个模式的单一通知(最常见的)
# app/models/form.rb
class Form < ApplicationRecord
# Standard single notification association
has_one :email_notification, as: :notification_holder,
class_name: "::NeetoEmailNotificationsEngine::EmailNotification", dependent: :destroy
# Optional: Create default notification after model creation
after_create :seed_email_notification
private
def seed_email_notification
self.create_email_notification!(
send_from: Rails.application.vault.mailer[:default_from_email],
notify_emails: [],
is_enabled: false,
subject: "New {{form-name}} submission",
message: "A new submission has been received for {{form-name}}."
)
end
end
每个模型的多通知类型
# app/models/meeting.rb
class Meeting < ApplicationRecord
# General association for all notifications
has_many :email_notifications, as: :notification_holder,
class_name: "::NeetoEmailNotificationsEngine::EmailNotification", dependent: :destroy
# Specific notification types using custom fields
has_one :reminder_notification,
-> { where("custom_fields -> 'notification_type' ? :value", value: "reminder") },
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
has_one :confirmation_notification,
-> { where("custom_fields -> 'notification_type' ? :value", value: "confirmation") },
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
has_one :cancellation_notification,
-> { where("custom_fields -> 'notification_type' ? :value", value: "cancellation") },
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
after_create :setup_default_notifications
private
def setup_default_notifications
create_reminder_notification!(
send_from: "[email protected]",
subject: "Reminder: {{meeting-title}} starts in 1 hour",
message: "Your meeting {{meeting-title}} is scheduled to start in 1 hour.",
custom_fields: { notification_type: "reminder" },
is_enabled: false
)
create_confirmation_notification!(
send_from: "[email protected]",
subject: "Meeting Confirmed: {{meeting-title}}",
message: "Your meeting {{meeting-title}} has been confirmed for {{meeting-date}}.",
custom_fields: { notification_type: "confirmation" },
is_enabled: true
)
end
end
创建自定义通知模式
# app/models/submission_email_notification.rb
class SubmissionEmailNotification < ::NeetoEmailNotificationsEngine::EmailNotification
# Scope to only submission notifications
default_scope { where("custom_fields -> 'notification_type' ? :value", value: "submission") }
after_initialize :set_notification_type
def custom_field_key
"notification_type"
end
private
def set_notification_type
self.custom_fields ||= {}
self.custom_fields[custom_field_key] = "submission"
end
end
# Usage in host model
class Form < ApplicationRecord
has_one :submission_email_notification, as: :notification_holder, dependent: :destroy
# You can still have the general association too
has_one :email_notification, as: :notification_holder,
class_name: "::NeetoEmailNotificationsEngine::EmailNotification", dependent: :destroy
end
数据库Schema信息
引擎创建一个表格 neeto_email_notifications_engine_email_notifications 带有这些密钥列:
notification_holder_type打开notification_holder_id:多态关系.notify_emails: 收件人电子邮件地址阵列.notify_cc_emails打开notify_bcc_emails: CC 和BCC 收件人的矩阵.send_from: 发件人电子邮件地址.subject: 电子邮件主题(支持液态模板).message: 丰富的短信内容(支持 Liquid模板).is_enabled: 启用/失效通知的布尔旗.custom_fields: JSONB 为额外的元数据栏.reply_to_id:回复配置的可选参考.type: 单表继承支持的字符串列.
默认属性分类方法
重要内容: 主机应用程序必须定义 default_attributes 在自定义通知模式中继承 NeetoEmailNotificationsEngine::EmailNotification。这种方法是必需的,并将收到 notification_holder 作为参数。 这种方法应该返回带有电子邮件通知默认属性的散列 .
主题和消息中的变量必须总是这样包裹着:
<span data-variable data-label="label" data-id="key">{{key}}</span>
实例
def self.default_attributes(quiz)
{
send_from: Rails.application.vault.mailer[:default_from_email],
notify_emails: [quiz.user.email],
is_enabled: true,
subject: "A new submission has arrived for {{quiz-name}}",
message: <<~HTML.squish
<b><span data-variable data-label="Quiz name" data-id="quiz-name">{{quiz-name}}</span></b>
has a new submission.<br/><br/>
<span data-variable data-label="All answers" data-id="all-answers">{{all-answers}}</span>
HTML
}
end
前端整合
1. 安装前端软件包
yarn add @bigbinary/neeto-email-notifications-frontend
这个包将提供一个单一的组件 NeetoEmailNotification,哪个
使用来自 neeto-molecules。 。 。 .
2. 安装同伴依赖关系
如果主机应用程序还没有包含这些对等依赖,则安装它们:
# DO NOT INSTALL THE EXACT VERSIONS MENTIONED BELOW AS THEY MIGHT BE OUTDATED.
# ALWAYS PREFER INSTALLING THE LATEST COMPATIBLE VERSIONS.
yarn add @babel/runtime@^7.26.10 @bigbinary/neeto-cist@^1.0.17 @bigbinary/neeto-commons-frontend@^4.13.43 @bigbinary/neeto-editor-frontend@^2.0.1 @bigbinary/neeto-filters-frontend@^4.3.21 @bigbinary/neeto-icons@^1.20.49 @bigbinary/neeto-molecules@^3.16.63 @bigbinary/neetoui@^8.3.9 @honeybadger-io/js@^6.10.1 @honeybadger-io/react@^6.1.25 @tailwindcss/container-queries@^0.1.1 @tanstack/react-query@^5.59.20 @tanstack/react-query-devtools@^5.59.20 antd@^5.22.0 axios@^1.8.2 buffer@^6.0.3 classnames@^2.5.1 crypto-browserify@^3.12.1 dompurify@^3.2.4 formik@^2.4.6 https-browserify@^1.0.0 i18next@^22.5.1 js-logger@^1.6.1 mixpanel-browser@^2.47.0 os-browserify@^0.3.0 path-browserify@^1.0.1 qs@^6.11.2 ramda@^0.29.0 react@^18.3.1 react-dom@^18.3.1 react-helmet@^6.1.0 react-i18next@^12.3.1 react-router-dom@^5.3.3 react-toastify@^8.0.2 source-map-loader@^4.0.1 stream-browserify@^3.0.0 stream-http@^3.2.0 tailwindcss@^3.4.14 tty-browserify@^0.0.1 url@^0.11.0 util@^0.12.5 vm-browserify@^1.1.2 yup@^0.32.11 zustand@^4.4.2
注意: 仔细管理与您主机应用程序的潜在版本冲突 .
3. 构成部分
NeetoEmailNotificationForm (单位:千美元)源代码(中文(简体) )
道具
| Prop | 类型 | 默认 | 说明 |
|---|---|---|---|
emailNotificationParams | 对象 | {} | 要求. 获取电子邮件通知数据的参数 |
title | 字符串 | "Email notification" | 通知切换上方显示的标题 |
notificationToggleLabel | 字符串 | "Send an email notification when a new event occurred" | 在通知切换开关旁显示的标签 |
disabled | 布尔 | false | 禁用整个组件 |
onSuccess | 函数 | noop | 成功更新通知后触发的召回功能 |
breadcrumbs | 阵列 | [] | Breadcrumb 导航数据 |
children | 反应节点 | undefined | 启用通知时提供的其他内容 |
blockNavigation | 布尔 | false | 显示未保存更改的块导航提示 |
helpPopoverProps | 对象 | {} | 帮助弹出组件的道具 |
tooltipProps | 对象 | {} | 组件禁用时显示的工具提示道具 |
emailFormProps | 对象 | {} | 向基本的电子邮件格式组件传递道具 |
emailFormikProps | 对象 | {} | 向电子邮件格式提供组件传递道具 |
emailPreviewProps | 对象 | {} | 传送到电子邮件审查组件的道具 |
fieldsVisibility | 对象 | {} | 控制电子邮件表格中可见的字段 |
可视性
每个字段的默认能见度如下:
{
showSendToField: true,
showReplyToField: false,
showSendToAsRadio: false,
showCcField: false,
showBccField: false,
}
你可以通过一个 fieldsVisibility 与你的道具
理想价值.
电子邮件通知Params 对象结构
{
notificationHolderId: "uuid-string", // ID of the notification holder
notificationHolderType: "Form", // Type of the notification holder
customFields: { // Optional custom fields for filtering
notificationType: "submission" // Example: different notification types
}
}
用法示例
import React from "react";
import { NeetoEmailNotificationForm } from "@bigbinary/neeto-email-notifications-frontend";
const FormSettingsPage = ({ formId }) => {
const handleNotificationUpdate = () => {
console.log("Email notification updated successfully!");
};
return (
<NeetoEmailNotificationForm
title="Form Submission Notification"
notificationToggleLabel="Get notified when someone submits your form"
emailNotificationParams={{
notificationHolderId: formId,
notificationHolderType: "Form",
customFields: { notificationType: "submission" }
}}
emailPreviewProps={{
formatBody: message => replaceVariablesWithDummyValues(message, values),
}}
breadcrumbs={[
{ text: "Forms", link: "/forms" },
{ text: "Settings", link: `/forms/${formId}/settings` }
]}
onSuccess={handleNotificationUpdate}
/>
);
};
export default FormSettingsPage;
4. 钩子
useFetchEmailNotifications (单位:千美元)源代码(中文(简体) )
为特定通知持有人获取电子邮件通知数据.
import { useFetchEmailNotifications } from "@bigbinary/neeto-email-notifications-frontend";
const { data, isLoading, error } = useFetchEmailNotifications({
notificationHolderId: "form-uuid",
notificationHolderType: "Form",
customFields: { notificationType: "submission" }
});
useUpdateEmailNotification (单位:千美元)源代码(中文(简体) )
更新电子邮件通知设置 .
import { useUpdateEmailNotification } from "@bigbinary/neeto-email-notifications-frontend";
const { mutate: updateEmailNotification, isPending } = useUpdateEmailNotification();
const handleUpdate = (notificationData) => {
updateEmailNotification({
...notificationData,
notificationHolderId: "form-uuid",
notificationHolderType: "Form"
});
};
用法实例
创建自定义通知模式
您可以创建从基部继承的专业通知模型 EmailNotification 类 :
class SubmissionEmailNotification < ::NeetoEmailNotificationsEngine::EmailNotification
default_scope { where("custom_fields -> 'notification_type' ? :value", value: "submission") }
after_initialize :set_notification_type
def custom_field_key
"notification_type"
end
private
def set_notification_type
self.custom_fields ||= {}
self.custom_fields[custom_field_key] = "submission"
end
end
建立通知持有人
配置支持电子邮件通知的模型 :
class Meeting < ApplicationRecord
has_one :reminder_notification, -> { where("custom_fields -> 'notification_type' ? :value", value: "reminder") },
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
has_one :confirmation_notification, -> { where("custom_fields -> 'notification_type' ? :value", value: "confirmation") },
as: :notification_holder, class_name: "::NeetoEmailNotificationsEngine::EmailNotification"
after_create :setup_notifications
private
def setup_notifications
create_reminder_notification!(
send_from: "[email protected]",
subject: "Reminder: {{meeting-title}} in 1 hour",
message: "Your meeting {{meeting-title}} is scheduled to start in 1 hour.",
custom_fields: { notification_type: "reminder" }
)
create_confirmation_notification!(
send_from: "[email protected]",
subject: "Meeting Confirmed: {{meeting-title}}",
message: "Your meeting {{meeting-title}} has been confirmed for {{meeting-date}}.",
custom_fields: { notification_type: "confirmation" }
)
end
end
种子默认电子邮件通知内容
建议自动为您的模型创建默认的电子邮件通知记录 。 这保证了通知UI和API总是有记录可以获取和更新,防止出错和功能缺失. 你可以使用一个 after_create 在您的模型中调用此记录 .
示例
class Quiz < ApplicationRecord
has_many :email_notifications, as: :notification_holder,
class_name: "NeetoEmailNotificationsEngine::EmailNotification", dependent: :destroy
has_one :push_email_notification, as: :notification_holder
after_create :create_default_email_notification
private
def create_default_email_notification
self.create_push_email_notification!(PushEmailNotification.default_attributes(self))
end
end
使用电子邮件通知服务
创建包含电子邮件通知功能的服务类 :
class MeetingReminderService
include ::NeetoEmailNotificationsEngine::EmailNotificationService
def initialize(meeting)
@meeting = meeting
@email_notification = meeting.reminder_notification
end
private
def send_emails
return unless @email_notification.is_enabled?
MeetingMailer.reminder_email(
recipients: @email_notification.notify_emails,
cc: @email_notification.notify_cc_emails,
bcc: @email_notification.notify_bcc_emails,
subject: @subject,
message: @message,
meeting: @meeting
).deliver_now
end
def load_liquid_parameters
@liquid_parameters[:text] = {
"meeting-title" => @meeting.title,
"meeting-date" => @meeting.scheduled_at.strftime("%B %d, %Y"),
"meeting-time" => @meeting.scheduled_at.strftime("%I:%M %p")
}
@liquid_parameters[:html] = @liquid_parameters[:text]
end
end
# Usage
meeting = Meeting.find(params[:id])
MeetingReminderService.new(meeting).process
API 终点
引擎在所配置的挂载路径( 默认) 下曝光 API 端点 /neeto_email_notifications:
| 方法 | 路径 | 说明 | 参数 |
|---|---|---|---|
| 获取 | /email_notification | 获取电子邮件通知设置 | notification_holder_id, (中文(简体) ), notification_holder_type, (中文(简体) ), custom_fields |
| 点 | /email_notification | 更新电子邮件通知设置 | notification_holder_id, (中文(简体) ), notification_holder_type, (中文(简体) ), email_notification 段落 |
示例 API 用法 :
// Fetch notification settings
axios.get('/neeto_email_notifications/email_notification', {
params: {
notification_holder_id: 'form-uuid',
notification_holder_type: 'Form',
custom_fields: { notification_type: 'submission' }
}
})
// Update notification settings
axios.put('/neeto_email_notifications/email_notification', {
notification_holder_id: 'form-uuid',
notification_holder_type: 'Form',
email_notification: {
is_enabled: true,
subject: 'New form submission',
message: 'A new submission was received.',
notify_emails: ['[email protected]'],
send_from: '[email protected]'
}
})
液态模板变量
电子邮件主题和信息支持动态内容的液体诱导:
# In your notification setup
email_notification.update!(
subject: "New {{form-name}} submission from {{user-name}}",
message: "Hello {{admin-name}}, a new submission was received for {{form-name}} on {{submission-date}}."
)
# In your service class
def load_liquid_parameters
@liquid_parameters[:text] = {
"form-name" => @form.name,
"user-name" => @submission.user.name,
"admin-name" => @form.owner.name,
"submission-date" => @submission.created_at.strftime("%B %d, %Y")
}
@liquid_parameters[:html] = @liquid_parameters[:text]
end
两者都与 NeetoCommonsBackend::LiquidRenderer: 主题为
纯文本从 liquid_parameters[:text],以 HTML 格式发送的信息
liquid_parameters[:html]。信件值是 HTML 的,除非它们安全
缓冲器,所以通过 HTML 你建造自己(一个部分, tag 帮助者)
作为 html_safe 输出, 绝不是普通字符串 。 传递的信息就是
与 NeetoCommonsBackend::EmailHtml.admin_html。 。 。 .
开发环境设置
发展指示
检查 前端软件包开发指南 用于开发前端软件包的分步指令.
后端开发
-
铁路服务器 : 启动主应用程序
bundle exec rails server -
数据库设置 : 确保移徙运行
bundle exec rails db:migrate -
测试 : 运行测试套件
bundle exec rails test
测试调试( D)
测试助手
发动机提供工厂进行测试:
# Use in your tests
FactoryBot.create(:neeto_email_notification_engine_email_notification,
notification_holder: your_model_instance
)
使用 test/dummy 应用在引擎的仓库内进行孤立测试.
出版
关于建造和释放 @bigbinary/neeto-email-notifications-frontend 国家防范机制一揽子计划 neeto-email-notifications-engine Ruby Gem 请参考内部指南: 建造和放行套件。 。 。 .