Socket
Book a DemoInstallSign in
Socket

@bigbinary/neeto-email-notifications-frontend

Package Overview
Dependencies
Maintainers
3
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bigbinary/neeto-email-notifications-frontend

A repo acts as the source of truth for the new nano's structure, configs, data etc.

latest
npmnpm
Version
2.2.16
Version published
Maintainers
3
Created
Source

neeto-email-notifications-nano

The neeto-email-notifications-nano is a comprehensive email notification management solution designed for the Neeto ecosystem. Implemented as a Ruby on Rails engine with associated React frontend components (@bigbinary/neeto-email-notifications-frontend), it provides a unified interface for managing email notifications across neeto applications.

Table of Contents

Installation (Backend Engine)

Follow these steps to integrate the neeto-email-notifications-engine into your host Rails application:

1. Add the Gem

Add the gem to your application's Gemfile:

# Gemfile
source "NEETO_GEM_SERVER_URL" do
  gem "neeto-email-notifications-engine"
end

2. Install Gems

Run bundler to install the gem and its dependencies:

bundle install

3. Install Migrations

Add required migrations in the db/migrate folder. Run the following commands to generate the migrations.

bundle exec rails g neeto_email_notifications_engine:install

This will generate the migration to create the neeto_email_notifications_engine_email_notifications table, which holds the data for the email notifications, and have custom_fields column to include custom attributes.

4. Run Migrations

Apply the migrations to your database:

bundle exec rails db:migrate

5. Mount the Engine

Add the engine's routes to your application's config/routes.rb:

# config/routes.rb
mount NeetoEmailNotificationsEngine::Engine, at: "/neeto_email_notifications"

NOTE: The mount point & base URL must be /neeto_email_notifications and cannot be changed to any other path.

Note: The engine uses the liquid gem for template rendering. This will be installed automatically as a dependency.

Configuration (Backend Engine)

1. Initializer Setup

Create an initializer file config/initializers/neeto_email_notifications_engine.rb to configure the engine:

# 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

The allowed_notification_holder_types configuration is mandatory. Failing to configure this will result in validation errors when creating email notifications.

2. Models

NeetoEmailNotificationsEngine::EmailNotification (source code)

Key Associations:

belongs_to :notification_holder, polymorphic: true
has_rich_text :message

Key Validations:

  • notification_holder_type must be in the configured allowed_notification_holder_types.
  • subject, message are required when is_enabled is true.
  • send_from must be a valid email format when required.
  • All email fields (notify_emails, notify_cc_emails, notify_bcc_emails) are validated for proper email format.

Available Methods:

  • message_body_content: Returns HTML content of the rich text message.
  • custom_field_key: Abstract method that subclasses must implement.
  • notification_type: Returns the notification type from custom fields.
  • disabled_by_user?: Checks if the notification was disabled by user action.

Setting Up Host Application Models

Ensure the models specified in allowed_notification_holder_types have the correct associations defined:

Single Notification Per Model (Most Common)

# 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.secrets.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

Multiple Notification Types Per Model

# 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: "meetings@company.com",
        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: "meetings@company.com",
        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

Creating Custom Notification Models

# 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

Database Schema Information The engine creates a table neeto_email_notifications_engine_email_notifications with these key columns:

  • notification_holder_type & notification_holder_id: Polymorphic association.
  • notify_emails: Array of recipient email addresses.
  • notify_cc_emails & notify_bcc_emails: Arrays for CC and BCC recipients.
  • send_from: Sender email address.
  • subject: Email subject (supports Liquid templates).
  • message: Rich text message content (supports Liquid templates).
  • is_enabled: Boolean flag to enable/disable notifications.
  • custom_fields: JSONB column for additional metadata.
  • reply_to_id: Optional reference for reply-to configuration.
  • type: String column for Single Table Inheritance (STI) support.

Default Attributes Class Method

Important: Host applications must define the default_attributes class method in their custom notification models that inherit from NeetoEmailNotificationsEngine::EmailNotification. This method is required and will receive the notification_holder as a parameter. This method should return a hash with the default attributes for the email notification.

Variables in the subject and message must always be wrapped like this:

<span data-variable data-label="label" data-id="key">{{key}}</span>

Example Implementation

def self.default_attributes(quiz)
  {
    send_from: Rails.application.secrets.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

Frontend Integration

1. Install Frontend Package

yarn add @bigbinary/neeto-email-notifications-frontend

This package will provide a single component NeetoEmailNotification, which uses components from neeto-molecules.

2. Install Peer Dependencies

If the host app doesn't already include these peer dependencies, install them:

# 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@^1.47.16 @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

Note: Carefully manage potential version conflicts with your host application.

3. Components

NeetoEmailNotificationForm (source code)

Props

PropTypeDefaultDescription
emailNotificationParamsObject{}Required. Parameters for fetching email notification data
titleString"Email notification"Title displayed above the notification toggle
notificationToggleLabelString"Send an email notification when a new event occurred"The label displayed beside the notification toggle switch
disabledBooleanfalseDisables the entire component
onSuccessFunctionnoopCallback function triggered after successful notification update
breadcrumbsArray[]Breadcrumb navigation data
childrenReactNodeundefinedAdditional content rendered when notifications are enabled
blockNavigationBooleanfalseShows block navigation alert for unsaved changes
helpPopoverPropsObject{}Props for the help popover component
tooltipPropsObject{}Props for tooltip shown when component is disabled
emailFormPropsObject{}Props passed to the underlying EmailForm component
emailFormikPropsObject{}Props passed to the EmailFormProvider component
emailPreviewPropsObject{}Props passed to the EmailPreview component
fieldsVisibilityObject{}Controls which fields are visible in the email form

FieldsVisibility

Default visibility for each field is as follows:

{
  showSendToField: true,
  showReplyToField: false,
  showSendToAsRadio: false,
  showCcField: false,
  showBccField: false,
}

You can override any of these by passing a fieldsVisibility prop with your desired values.

emailNotificationParams Object Structure

{
  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
  }
}

Usage Example

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. Hooks

useFetchEmailNotifications (source code)

Fetches email notification data for a specific notification holder.

import { useFetchEmailNotifications } from "@bigbinary/neeto-email-notifications-frontend";

const { data, isLoading, error } = useFetchEmailNotifications({
  notificationHolderId: "form-uuid",
  notificationHolderType: "Form",
  customFields: { notificationType: "submission" }
});

useUpdateEmailNotification (source code)

Updates email notification settings.

import { useUpdateEmailNotification } from "@bigbinary/neeto-email-notifications-frontend";

const { mutate: updateEmailNotification, isPending } = useUpdateEmailNotification();

const handleUpdate = (notificationData) => {
  updateEmailNotification({
    ...notificationData,
    notificationHolderId: "form-uuid",
    notificationHolderType: "Form"
  });
};

Usage Examples

Creating Custom Notification Models

You can create specialized notification models that inherit from the base EmailNotification class:

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

Setting Up Notification Holders

Configure your models to support email notifications:

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: "meetings@company.com",
        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: "meetings@company.com",
        subject: "Meeting Confirmed: {{meeting-title}}",
        message: "Your meeting {{meeting-title}} has been confirmed for {{meeting-date}}.",
        custom_fields: { notification_type: "confirmation" }
      )
    end
end

Seeding Default Email Notification Content

It is recommended to automatically create a default email notification record for each instance of your model. This ensures the notification UI and API always have a record to fetch and update, preventing errors and missing functionality. You can use an after_create callback in your model to seed this record.

Example:
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

Using the Email Notification Service

Create service classes that include the email notification functionality:

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 Endpoints

The engine exposes API endpoints under the configured mount path (default /neeto_email_notifications):

MethodPathDescriptionParameters
GET/email_notificationFetch email notification settingsnotification_holder_id, notification_holder_type, custom_fields
PUT/email_notificationUpdate email notification settingsnotification_holder_id, notification_holder_type, email_notification params

Example API Usage:

// 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: ['admin@company.com'],
    send_from: 'forms@company.com'
  }
})

Liquid Template Variables

Email subjects and messages support Liquid templating for dynamic content:

# 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

Development Environment Setup

Instructions for Development

Check the Frontend package development guide for step-by-step instructions to develop the frontend package.

Backend Development

  • Rails Server: Start the main application

    bundle exec rails server
    
  • Database Setup: Ensure migrations are run

    bundle exec rails db:migrate
    
  • Testing: Run the test suite

    bundle exec rails test
    

Testing & Debugging

Test Helpers

The engine provides factories for testing:

# Use in your tests
FactoryBot.create(:neeto_email_notification_engine_email_notification,
  notification_holder: your_model_instance
)

Use the test/dummy app within the engine's repository for isolated testing.

Publishing

For instructions on building and releasing the @bigbinary/neeto-email-notifications-frontend NPM package and the neeto-email-notifications-engine Ruby gem, please refer to the internal guide: Building and Releasing Packages.

FAQs

Package last updated on 04 Oct 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts