forked from forem/forem
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add custom emails to admin area (forem#21340)
* Add custom emails to admin area * Fix i18n * Adjust newsletters * Adjust newsletters * Newsletter i18n * Newsletter i18n * Fix email spec * Get headers working * Get headers working
- Loading branch information
1 parent
88336eb
commit f87ca82
Showing
25 changed files
with
501 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
module Admin | ||
class EmailsController < Admin::ApplicationController | ||
layout "admin" | ||
|
||
def index | ||
@emails = Email.page(params[:page] || 1).includes([:audience_segment]).order("id DESC").per(25) | ||
end | ||
|
||
def new | ||
@audience_segments = AudienceSegment.all | ||
@email = Email.new | ||
end | ||
|
||
def show | ||
@email = Email.find(params[:id]) | ||
end | ||
|
||
def create | ||
@email = Email.new(email_params) | ||
if @email.save | ||
flash[:success] = I18n.t("admin.emails_controller.created") | ||
redirect_to admin_email_path(@email.id) | ||
else | ||
@audience_segments = AudienceSegment.all | ||
flash[:danger] = @email.errors_as_sentence | ||
render :new | ||
end | ||
end | ||
|
||
private | ||
|
||
def email_params | ||
params.permit(:subject, :body, :audience_segment_id) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
class CustomMailer < ApplicationMailer | ||
default from: -> { email_from(I18n.t("mailers.custom_mailer.from")) } | ||
|
||
def custom_email | ||
@user = params[:user] | ||
@content = params[:content] | ||
@unsubscribe = generate_unsubscribe_token(@user.id, :email_newsletter) | ||
|
||
# set sendgrid category in the header using smtp api | ||
# https://docs.sendgrid.com/for-developers/sending-email/building-an-x-smtpapi-header | ||
if ForemInstance.sendgrid_enabled? | ||
smtpapi_header = { category: "Custom Email" }.to_json | ||
headers["X-SMTPAPI"] = smtpapi_header | ||
end | ||
|
||
mail(to: @user.email, subject: params[:subject]) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
class Email < ApplicationRecord | ||
belongs_to :audience_segment, optional: true | ||
|
||
after_create :deliver_to_users | ||
|
||
validates :subject, presence: true | ||
validates :body, presence: true | ||
|
||
BATCH_SIZE = Rails.env.production? ? 1000 : 10 | ||
|
||
def deliver_to_users | ||
user_scope = if audience_segment | ||
audience_segment.users.registered.joins(:notification_setting) | ||
.where(notification_setting: { email_newsletter: true }) | ||
.where.not(email: "") | ||
else | ||
User.registered.joins(:notification_setting) | ||
.where(notification_setting: { email_newsletter: true }) | ||
.where.not(email: "") | ||
end | ||
|
||
user_scope.find_in_batches(batch_size: BATCH_SIZE) do |users_batch| | ||
Emails::BatchCustomSendWorker.perform_async(users_batch.map(&:id), subject, body) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<div class="grid l:grid-cols-2 gap-6 mb-4"> | ||
<div class="flex flex-col gap-4"> | ||
|
||
<div class="crayons-field"> | ||
<%= label_tag :audience_segment_id, "Audience Segment:", class: "crayons-field__label" %> | ||
<%= select_tag :audience_segment_id, options_for_select([["Entire list", nil]] + @audience_segments.map { |s| [s.name || s.type_of, s.id]}), class: "crayons-textfield", autocomplete: "off" %> | ||
</div> | ||
|
||
<div class="crayons-field"> | ||
<%= label_tag :subject, "Subject:", class: "crayons-field__label" %> | ||
<%= text_field_tag :subject, @email.subject, class: "crayons-textfield", autocomplete: "off" %> | ||
</div> | ||
|
||
<div class="crayons-field"> | ||
<%= label_tag :body, "Body Content:", class: "crayons-field__label" %> | ||
<%= text_area_tag :body, @email.body, size: "100x5", class: "crayons-textfield" %> | ||
</div> | ||
</div> | ||
|
||
<div> | ||
<div class="crayons-card crayons-card--secondary"> | ||
<% if @email.persisted? %> | ||
<h2 class="crayons-title mb-2">Preview</h2> | ||
<p><strong>Subject:</strong> <%= @email.subject %></p> | ||
<p><strong>Body:</strong></p> | ||
<div class="crayons-article__body text-styles"> | ||
<%= simple_format(@email.body) %> | ||
</div> | ||
<% else %> | ||
<div class="flex flex-col gap-3"> | ||
<p> | ||
Use this form to compose a new email. Fill in the subject, body, and specify the recipients. | ||
</p> | ||
<p> | ||
You can choose to send the email immediately or schedule it for a later time. | ||
</p> | ||
<p> | ||
Select the appropriate recipient group or provide a custom list of email addresses. | ||
</p> | ||
</div> | ||
<% end %> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<%#= javascript_include_tag "admin/emails", defer: true %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<h1 class="crayons-title mb-3">Emails</h1> | ||
|
||
<div | ||
data-controller="confirmation-modal" | ||
data-confirmation-modal-root-selector-value="#confirmation-modal-root" | ||
data-confirmation-modal-content-selector-value="#confirmation-modal" | ||
data-confirmation-modal-title-value="Confirm changes" | ||
data-confirmation-modal-size-value="m"> | ||
|
||
<nav class="flex mb-4" aria-label="Emails navigation"> | ||
<%= form_tag(admin_emails_path, method: "get") do %> | ||
<%= text_field_tag(:search, params[:search], aria: { label: "Search" }, class: "crayons-header--search-input crayons-textfield", placeholder: "Search", autocomplete: "off") %> | ||
<% end %> | ||
<div class="ml-auto"> | ||
<div class="justify-end"> | ||
<%= link_to "Compose New Email", new_admin_email_path, class: "crayons-btn" %> | ||
</div> | ||
</div> | ||
</nav> | ||
|
||
<%= paginate @emails %> | ||
|
||
|
||
<table class="crayons-table" width="100%"> | ||
<thead> | ||
<tr> | ||
<th scope="col">Subject</th> | ||
<th scope="col">Sent At</th> | ||
<th scope="col">Segment</th> | ||
<th scope="col">Body</th> | ||
</tr> | ||
</thead> | ||
<tbody class="crayons-card"> | ||
<% @emails.each do |email| %> | ||
<tr data-row-id="<%= email.id %>"> | ||
<td><%= link_to email.subject, admin_email_path(email) %></td> | ||
<td><%= email.created_at %></td> | ||
<td><%= email.audience_segment&.name || email.audience_segment&.type_of || "All" %></td> | ||
<td><%= truncate(email.body, length: 100) %></td> | ||
<td><%= link_to "Details", admin_email_path(email), class: "crayons-btn" %></td> | ||
<td> | ||
<button | ||
class="crayons-btn crayons-btn--danger" | ||
data-item-id="<%= email.id %>" | ||
data-endpoint="/admin/emails" | ||
data-username="<%= current_user.username %>" | ||
data-action="click->confirmation-modal#openModal">Destroy</button> | ||
</td> | ||
</tr> | ||
<% end %> | ||
</tbody> | ||
</table> | ||
|
||
<%= render partial: "admin/shared/destroy_confirmation_modal" %> | ||
<%= paginate @emails %> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<h1 class="crayons-title mb-4">Make a new Email</h1> | ||
<div class="crayons-card p-6"> | ||
<%= form_for([:admin, @email], url: admin_emails_path, method: :post) do %> | ||
<%= render "form" %> | ||
<%= submit_tag "Send Billboard", class: "c-btn c-btn--primary" %> | ||
<% end %> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<h1 class="crayons-title mb-4"><%= @email.subject %></h1> | ||
<div class="crayons-card p-6"> | ||
<%= @email.body %> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<%= @content.html_safe %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
module Emails | ||
class BatchCustomSendWorker | ||
include Sidekiq::Job | ||
|
||
sidekiq_options queue: :medium_priority, retry: 15 | ||
|
||
def perform(user_ids, subject, content) | ||
user_ids.each do |id| | ||
CustomMailer.with(user: User.find(id), subject: subject, content: subject).custom_email.deliver_now | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
class CreateEmails < ActiveRecord::Migration[7.0] | ||
def change | ||
create_table :emails do |t| | ||
t.string :subject, null: false | ||
t.text :body, null: false | ||
t.references :audience_segment, foreign_key: true | ||
t.timestamps | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
class AddNameToAudienceSegments < ActiveRecord::Migration[7.0] | ||
def change | ||
add_column :audience_segments, :name, :string | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
FactoryBot.define do | ||
factory :email do | ||
subject { Faker::Lorem.sentence } | ||
body { Faker::Lorem.sentence } | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.