emailbutler 0.2.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +8 -0
- data/app/assets/config/emailbutler_manifest.js +1 -1
- data/app/assets/stylesheets/emailbutler/core/base.scss +42 -0
- data/app/assets/stylesheets/emailbutler/shared/footer.scss +10 -0
- data/app/assets/stylesheets/emailbutler/shared/header.scss +26 -0
- data/app/assets/stylesheets/emailbutler/views/dashboard.scss +121 -0
- data/app/assets/stylesheets/emailbutler.scss +4 -0
- data/app/controllers/emailbutler/ui/messages_controller.rb +25 -0
- data/app/controllers/emailbutler/ui_controller.rb +37 -0
- data/app/controllers/emailbutler/webhooks_controller.rb +1 -1
- data/app/views/emailbutler/ui/index.html.erb +16 -0
- data/app/views/emailbutler/ui/shared/_footer.html.erb +8 -0
- data/app/views/emailbutler/ui/shared/_header.html.erb +9 -0
- data/app/views/emailbutler/ui/show.html.erb +52 -0
- data/app/views/layouts/emailbutler/application.html.erb +8 -4
- data/config/routes.rb +5 -0
- data/lib/emailbutler/adapters/active_record.rb +25 -0
- data/lib/emailbutler/configuration.rb +8 -1
- data/lib/emailbutler/dsl.rb +20 -0
- data/lib/emailbutler/helpers.rb +36 -0
- data/lib/emailbutler/mailers/helpers.rb +2 -9
- data/lib/emailbutler/version.rb +1 -1
- data/lib/emailbutler.rb +2 -1
- metadata +28 -17
- data/app/assets/stylesheets/emailbutler/application.css +0 -15
- data/db/migrate/20220916162720_create_emailbutler_tables.rb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 97c7cc6c31716442ed040ee06b451d2a3a6abdac9262c08e5fee1c9c6de4f385
|
|
4
|
+
data.tar.gz: '048cacc8bb87d36cd5bd7b5ccced2b726dcde665ec3398adc348a605a2dd6774'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ed85dfd33c8f3a0e3f2a091db4921f1a70d696abbfd0869408bca4a1fa66f6f90bfd3d542a88f204b29c0e2c2c9b0a328e9252d1ba5183b7de8edeafc889abb1
|
|
7
|
+
data.tar.gz: 688b1af36d7eaa8ce68f5467ed4a7c22cdd442e0d126e013ac1b9c890f1ff1e308079fe9ee32696403aa21921d1f04f7b78ed3ca68f643bd735981cef571d4c4
|
data/README.md
CHANGED
|
@@ -29,6 +29,9 @@ require 'emailbutler/adapters/active_record'
|
|
|
29
29
|
|
|
30
30
|
Emailbutler.configure do |config|
|
|
31
31
|
config.adapter = Emailbutler::Adapters::ActiveRecord.new
|
|
32
|
+
config.ui_username = 'username'
|
|
33
|
+
config.ui_password = 'password'
|
|
34
|
+
config.ui_secured_environments = ['production']
|
|
32
35
|
end
|
|
33
36
|
```
|
|
34
37
|
|
|
@@ -63,5 +66,10 @@ end
|
|
|
63
66
|
1. Each event with sending email will create new record with message params in database.
|
|
64
67
|
2. Each webhook event will update status of message in database.
|
|
65
68
|
|
|
69
|
+
### UI
|
|
70
|
+
|
|
71
|
+
Emailbutler provides UI with rendering email tracking statistics - /emailbutler/ui.
|
|
72
|
+
And with opportunity to resend and/or destroy emails.
|
|
73
|
+
|
|
66
74
|
## License
|
|
67
75
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
//= link_directory ../stylesheets
|
|
1
|
+
//= link_directory ../stylesheets .css
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600&display=swap&subset=cyrillic');
|
|
2
|
+
|
|
3
|
+
#emailbutler, #emailbutler body {
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 0;
|
|
6
|
+
min-height: 100vh;
|
|
7
|
+
height: 100%;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
#emailbutler {
|
|
11
|
+
font-family: "Source Sans Pro", "Helvetica", "Open Sans", sans-serif;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
position: relative;
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
|
|
19
|
+
* {
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
|
|
22
|
+
&:focus {
|
|
23
|
+
outline: none;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
p {
|
|
28
|
+
margin: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.content {
|
|
32
|
+
flex: 1;
|
|
33
|
+
width: 100%;
|
|
34
|
+
max-width: 90rem;
|
|
35
|
+
margin: 0 auto;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
h1, h2, h3, h4, h5, h6 {
|
|
39
|
+
margin: 0;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
header {
|
|
2
|
+
border-bottom: 1px solid #e5e7eb;
|
|
3
|
+
|
|
4
|
+
.header-wrapper {
|
|
5
|
+
display: flex;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
align-items: center;
|
|
8
|
+
width: 100%;
|
|
9
|
+
max-width: 90rem;
|
|
10
|
+
margin: 0 auto;
|
|
11
|
+
padding: .5rem 0;
|
|
12
|
+
|
|
13
|
+
a {
|
|
14
|
+
text-decoration: none;
|
|
15
|
+
color: #000;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@media screen and (max-width: 48rem) {
|
|
21
|
+
header {
|
|
22
|
+
.header-wrapper {
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#emailbutler {
|
|
2
|
+
#dashboard {
|
|
3
|
+
padding-top: 1rem;
|
|
4
|
+
display: flex;
|
|
5
|
+
|
|
6
|
+
.summary {
|
|
7
|
+
list-style: none;
|
|
8
|
+
flex: 1;
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: row;
|
|
11
|
+
padding: .75rem 1rem;
|
|
12
|
+
background: #e5e7eb;
|
|
13
|
+
border-radius: .125rem;
|
|
14
|
+
margin: 0;
|
|
15
|
+
|
|
16
|
+
li {
|
|
17
|
+
flex: 1;
|
|
18
|
+
text-align: center;
|
|
19
|
+
|
|
20
|
+
a {
|
|
21
|
+
text-decoration: none;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.status-summary {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
color: #000;
|
|
29
|
+
padding: .5rem 0;
|
|
30
|
+
|
|
31
|
+
&:hover {
|
|
32
|
+
background: #d1d5db;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
span:nth-of-type(1) {
|
|
36
|
+
margin-bottom: .25rem;
|
|
37
|
+
font-weight: 600;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.search-form {
|
|
43
|
+
width: 20rem;
|
|
44
|
+
padding-right: 2rem;
|
|
45
|
+
|
|
46
|
+
.form-field {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
margin-bottom: .5rem;
|
|
50
|
+
|
|
51
|
+
label {
|
|
52
|
+
margin-bottom: .25rem;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
input {
|
|
56
|
+
padding: .25rem;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.messages {
|
|
62
|
+
flex: 1;
|
|
63
|
+
height: 100%;
|
|
64
|
+
|
|
65
|
+
thead {
|
|
66
|
+
tr {
|
|
67
|
+
th {
|
|
68
|
+
text-align: left;
|
|
69
|
+
padding: .125rem .25rem;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
tbody {
|
|
75
|
+
tr {
|
|
76
|
+
&:nth-of-type(odd) {
|
|
77
|
+
background: #e5e7eb;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
&:hover {
|
|
81
|
+
background: #d1d5db;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
td {
|
|
85
|
+
padding: .125rem .25rem;
|
|
86
|
+
|
|
87
|
+
&.actions {
|
|
88
|
+
display: flex;
|
|
89
|
+
|
|
90
|
+
button {
|
|
91
|
+
&:nth-of-type(1) {
|
|
92
|
+
margin-right: .5rem;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.button {
|
|
103
|
+
box-shadow: none;
|
|
104
|
+
border: none;
|
|
105
|
+
cursor: pointer;
|
|
106
|
+
padding: .25rem;
|
|
107
|
+
background: #bbf7d0;
|
|
108
|
+
|
|
109
|
+
&:hover {
|
|
110
|
+
background: #86efac;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
&.warning {
|
|
114
|
+
background: #fecaca;
|
|
115
|
+
|
|
116
|
+
&:hover {
|
|
117
|
+
background: #fca5a5;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emailbutler
|
|
4
|
+
module Ui
|
|
5
|
+
class MessagesController < Emailbutler::UiController
|
|
6
|
+
before_action :find_message
|
|
7
|
+
|
|
8
|
+
def update
|
|
9
|
+
Emailbutler.resend_message(@message)
|
|
10
|
+
redirect_to ui_index_path
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def destroy
|
|
14
|
+
Emailbutler.destroy_message(@message)
|
|
15
|
+
redirect_to ui_index_path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def find_message
|
|
21
|
+
@message = Emailbutler.find_message_by(uuid: params[:id])
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emailbutler
|
|
4
|
+
class UiController < Emailbutler::ApplicationController
|
|
5
|
+
http_basic_authenticate_with name: Emailbutler.configuration.ui_username,
|
|
6
|
+
password: Emailbutler.configuration.ui_password,
|
|
7
|
+
if: -> { basic_auth_enabled? }
|
|
8
|
+
|
|
9
|
+
def index
|
|
10
|
+
@summary = Emailbutler.count_messages_by_status
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def show
|
|
14
|
+
@messages = Emailbutler.find_messages_by(search_condition)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def search_condition
|
|
20
|
+
{
|
|
21
|
+
status: params[:id],
|
|
22
|
+
mailer: params[:mailer_name].presence,
|
|
23
|
+
action: params[:action_name].presence,
|
|
24
|
+
send_to: [params[:receiver].presence].compact.presence
|
|
25
|
+
}.compact
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def basic_auth_enabled?
|
|
29
|
+
configuration = Emailbutler.configuration
|
|
30
|
+
|
|
31
|
+
return false if configuration.ui_username.blank?
|
|
32
|
+
return false if configuration.ui_password.blank?
|
|
33
|
+
|
|
34
|
+
configuration.ui_secured_environments.include?(Rails.env)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<div id="dashboard">
|
|
2
|
+
<ul class="summary">
|
|
3
|
+
<li class="status-summary">
|
|
4
|
+
<span><%= @summary.values.sum %></span>
|
|
5
|
+
<span>Total</span>
|
|
6
|
+
</li>
|
|
7
|
+
<% Emailbutler.adapter.message_class.statuses.each_key do |status| %>
|
|
8
|
+
<li>
|
|
9
|
+
<%= link_to ui_path(status), class: 'status-summary' do %>
|
|
10
|
+
<span><%= @summary[status].to_i %></span>
|
|
11
|
+
<span><%= status.capitalize %></span>
|
|
12
|
+
<% end %>
|
|
13
|
+
</li>
|
|
14
|
+
<% end %>
|
|
15
|
+
</ul>
|
|
16
|
+
</div>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<div id="dashboard">
|
|
2
|
+
<section class="search-form">
|
|
3
|
+
<%= form_with url: ui_path(params[:id]), method: :get do |form| %>
|
|
4
|
+
<div class="form-field">
|
|
5
|
+
<%= form.label :mailer_name, 'Mailer', class: 'form-label' %>
|
|
6
|
+
<%= form.text_field :mailer_name, class: 'form-value', value: params[:mailer_name] %>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="form-field">
|
|
9
|
+
<%= form.label :action_name, 'Action', class: 'form-label' %>
|
|
10
|
+
<%= form.text_field :action_name, class: 'form-value', value: params[:action_name] %>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="form-field">
|
|
13
|
+
<%= form.label :receiver, 'Receiver', class: 'form-label' %>
|
|
14
|
+
<%= form.text_field :receiver, class: 'form-value', value: params[:receiver] %>
|
|
15
|
+
</div>
|
|
16
|
+
<%= form.submit 'Search', class: 'button' %>
|
|
17
|
+
<% end %>
|
|
18
|
+
</section>
|
|
19
|
+
<table class="messages" cellspacing="0">
|
|
20
|
+
<thead>
|
|
21
|
+
<tr>
|
|
22
|
+
<th>ID</th>
|
|
23
|
+
<th>Mailer</th>
|
|
24
|
+
<th>Action</th>
|
|
25
|
+
<th>Send to</th>
|
|
26
|
+
<th>Action params</th>
|
|
27
|
+
<th>Mailer params</th>
|
|
28
|
+
<th></th>
|
|
29
|
+
</tr>
|
|
30
|
+
</thead>
|
|
31
|
+
<tbody>
|
|
32
|
+
<% @messages.each do |message| %>
|
|
33
|
+
<tr>
|
|
34
|
+
<td><%= message.id %></td>
|
|
35
|
+
<td><%= message.mailer %></td>
|
|
36
|
+
<td><%= message.action %></td>
|
|
37
|
+
<td>
|
|
38
|
+
<% message.send_to.each do |receiver| %>
|
|
39
|
+
<p><%= receiver %></p>
|
|
40
|
+
<% end %>
|
|
41
|
+
</td>
|
|
42
|
+
<td><%= message.params['action_params'] %></td>
|
|
43
|
+
<td><%= message.params['mailer_params'] %></td>
|
|
44
|
+
<td class="actions">
|
|
45
|
+
<%= button_to 'Resend', ui_message_path(message.uuid), method: :patch, class: 'button' %>
|
|
46
|
+
<%= button_to 'Destroy', ui_message_path(message.uuid), method: :delete, class: 'button warning' %>
|
|
47
|
+
</td>
|
|
48
|
+
</tr>
|
|
49
|
+
<% end %>
|
|
50
|
+
</tbody>
|
|
51
|
+
</table>
|
|
52
|
+
</div>
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
2
|
+
<html id="emailbutler">
|
|
3
3
|
<head>
|
|
4
4
|
<title>Emailbutler</title>
|
|
5
5
|
<%= csrf_meta_tags %>
|
|
6
6
|
<%= csp_meta_tag %>
|
|
7
|
-
<%= stylesheet_link_tag 'emailbutler
|
|
7
|
+
<%= stylesheet_link_tag 'emailbutler', media: 'all' %>
|
|
8
8
|
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<%=
|
|
9
|
+
<body id="emailbutler-body">
|
|
10
|
+
<%= render 'emailbutler/ui/shared/header' %>
|
|
11
|
+
<div class="content">
|
|
12
|
+
<%= yield %>
|
|
13
|
+
</div>
|
|
14
|
+
<%= render 'emailbutler/ui/shared/footer' %>
|
|
11
15
|
</body>
|
|
12
16
|
</html>
|
data/config/routes.rb
CHANGED
|
@@ -5,6 +5,8 @@ require 'active_record'
|
|
|
5
5
|
module Emailbutler
|
|
6
6
|
module Adapters
|
|
7
7
|
class ActiveRecord
|
|
8
|
+
include Emailbutler::Helpers
|
|
9
|
+
|
|
8
10
|
# Abstract base class for internal models
|
|
9
11
|
class Model < ::ActiveRecord::Base
|
|
10
12
|
self.abstract_class = true
|
|
@@ -68,6 +70,29 @@ module Emailbutler
|
|
|
68
70
|
rescue ::ActiveRecord::StaleObjectError
|
|
69
71
|
update_message(message.reload, args)
|
|
70
72
|
end
|
|
73
|
+
|
|
74
|
+
# Public: Groups messages by status and count them.
|
|
75
|
+
def count_messages_by_status
|
|
76
|
+
@message_class.group(:status).count
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Public: Finds messages by args.
|
|
80
|
+
def find_messages_by(args={})
|
|
81
|
+
@message_class.where(args).order(created_at: :desc)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Public: Resends the message.
|
|
85
|
+
def resend_message(message)
|
|
86
|
+
::ActiveRecord::Base.transaction do
|
|
87
|
+
message.destroy
|
|
88
|
+
resend_message_with_mailer(message)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Public: Destroy the message.
|
|
93
|
+
def destroy_message(message)
|
|
94
|
+
message.destroy
|
|
95
|
+
end
|
|
71
96
|
end
|
|
72
97
|
end
|
|
73
98
|
end
|
|
@@ -2,10 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
module Emailbutler
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :adapter
|
|
5
|
+
attr_accessor :adapter, :ui_username, :ui_password, :ui_secured_environments
|
|
6
6
|
|
|
7
7
|
def initialize
|
|
8
8
|
@adapter = nil
|
|
9
|
+
|
|
10
|
+
# It's required to specify these 3 variables to enable basic auth to UI
|
|
11
|
+
@ui_username = ''
|
|
12
|
+
@ui_password = ''
|
|
13
|
+
|
|
14
|
+
# Secured environments variable must directly contains environment names
|
|
15
|
+
@ui_secured_environments = []
|
|
9
16
|
end
|
|
10
17
|
end
|
|
11
18
|
end
|
data/lib/emailbutler/dsl.rb
CHANGED
|
@@ -35,5 +35,25 @@ module Emailbutler
|
|
|
35
35
|
def update_message(message, args={})
|
|
36
36
|
adapter.update_message(message, args)
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
# Public: Groups messages by status and count them.
|
|
40
|
+
def count_messages_by_status
|
|
41
|
+
adapter.count_messages_by_status
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Public: Finds messages by args.
|
|
45
|
+
def find_messages_by(args={})
|
|
46
|
+
adapter.find_messages_by(args)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Public: Resends the message.
|
|
50
|
+
def resend_message(message)
|
|
51
|
+
adapter.resend_message(message)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Public: Destroys the message.
|
|
55
|
+
def destroy_message(message)
|
|
56
|
+
adapter.destroy_message(message)
|
|
57
|
+
end
|
|
38
58
|
end
|
|
39
59
|
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Emailbutler
|
|
4
|
+
module Helpers
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
def resend_message_with_mailer(message)
|
|
8
|
+
params = message.params
|
|
9
|
+
|
|
10
|
+
mailer = message.mailer.constantize
|
|
11
|
+
mailer = mailer.with(serialize(params['mailer_params'])) if params['mailer_params'].present?
|
|
12
|
+
mailer = mailer.method(message.action)
|
|
13
|
+
mailer = params['action_params'] ? mailer.call(*serialize(params['action_params'])) : mailer.call
|
|
14
|
+
mailer.deliver_now
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def serialize(value, reverse=true)
|
|
18
|
+
return value.map { |element| serialize(element, reverse) } if value.is_a?(Array)
|
|
19
|
+
return value.transform_values { |element| serialize(element, reverse) } if value.is_a?(Hash)
|
|
20
|
+
|
|
21
|
+
reverse ? deserialize_value(value) : serialize_value(value)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def serialize_value(value)
|
|
25
|
+
return value.to_global_id.to_s if value.respond_to?(:to_global_id)
|
|
26
|
+
|
|
27
|
+
value
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def deserialize_value(value)
|
|
31
|
+
return GlobalID::Locator.locate(value) if value.is_a?(String) && value.starts_with?('gid://')
|
|
32
|
+
|
|
33
|
+
value
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -4,6 +4,7 @@ module Emailbutler
|
|
|
4
4
|
module Mailers
|
|
5
5
|
module Helpers
|
|
6
6
|
extend ActiveSupport::Concern
|
|
7
|
+
include Emailbutler::Helpers
|
|
7
8
|
|
|
8
9
|
included do
|
|
9
10
|
after_action :save_emailbutler_message
|
|
@@ -21,18 +22,10 @@ module Emailbutler
|
|
|
21
22
|
@message = Emailbutler.build_message(
|
|
22
23
|
mailer: self.class.to_s,
|
|
23
24
|
action: action_name,
|
|
24
|
-
params:
|
|
25
|
+
params: serialize({ mailer_params: params, action_params: args[1..] }, false)
|
|
25
26
|
)
|
|
26
27
|
end
|
|
27
28
|
|
|
28
|
-
def serialize_params(value)
|
|
29
|
-
return value.map { |element| serialize_params(element) } if value.is_a?(Array)
|
|
30
|
-
return value.transform_values { |element| serialize_params(element) } if value.is_a?(Hash)
|
|
31
|
-
return value.to_global_id.to_s if value.respond_to?(:to_global_id)
|
|
32
|
-
|
|
33
|
-
value
|
|
34
|
-
end
|
|
35
|
-
|
|
36
29
|
def save_emailbutler_message
|
|
37
30
|
Emailbutler.set_message_attribute(@message, :send_to, mail.to)
|
|
38
31
|
Emailbutler.save_message(@message)
|
data/lib/emailbutler/version.rb
CHANGED
data/lib/emailbutler.rb
CHANGED
|
@@ -7,6 +7,7 @@ require 'emailbutler/engine'
|
|
|
7
7
|
require 'emailbutler/configuration'
|
|
8
8
|
require 'emailbutler/dsl'
|
|
9
9
|
require 'emailbutler/webhooks/receiver'
|
|
10
|
+
require 'emailbutler/helpers'
|
|
10
11
|
require 'emailbutler/mailers/helpers'
|
|
11
12
|
|
|
12
13
|
module Emailbutler
|
|
@@ -42,5 +43,5 @@ module Emailbutler
|
|
|
42
43
|
# Public: All the methods delegated to instance. These should match the interface of Emailbutler::DSL.
|
|
43
44
|
def_delegators :instance,
|
|
44
45
|
:adapter, :build_message, :set_message_attribute, :save_message, :find_message_by,
|
|
45
|
-
:update_message
|
|
46
|
+
:update_message, :count_messages_by_status, :find_messages_by, :resend_message, :destroy_message
|
|
46
47
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: emailbutler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bogdanov Anton
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-11-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -25,19 +25,19 @@ dependencies:
|
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
26
|
version: 6.0.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: sass-rails
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
31
|
+
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: '0'
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- - "
|
|
38
|
+
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: '0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: bundler
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -70,16 +70,16 @@ dependencies:
|
|
|
70
70
|
name: puma
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
72
72
|
requirements:
|
|
73
|
-
- - "
|
|
73
|
+
- - "~>"
|
|
74
74
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '
|
|
75
|
+
version: '6.0'
|
|
76
76
|
type: :development
|
|
77
77
|
prerelease: false
|
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
79
|
requirements:
|
|
80
|
-
- - "
|
|
80
|
+
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '
|
|
82
|
+
version: '6.0'
|
|
83
83
|
- !ruby/object:Gem::Dependency
|
|
84
84
|
name: rake
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,14 +100,14 @@ dependencies:
|
|
|
100
100
|
requirements:
|
|
101
101
|
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '1.
|
|
103
|
+
version: '1.39'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '1.
|
|
110
|
+
version: '1.39'
|
|
111
111
|
- !ruby/object:Gem::Dependency
|
|
112
112
|
name: rubocop-performance
|
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -150,7 +150,8 @@ dependencies:
|
|
|
150
150
|
- - "~>"
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
152
|
version: '2.0'
|
|
153
|
-
description:
|
|
153
|
+
description: Emailbutler allows you to track delivery status of emails sent by your
|
|
154
|
+
app.
|
|
154
155
|
email:
|
|
155
156
|
- kortirso@gmail.com
|
|
156
157
|
executables: []
|
|
@@ -161,17 +162,27 @@ files:
|
|
|
161
162
|
- README.md
|
|
162
163
|
- Rakefile
|
|
163
164
|
- app/assets/config/emailbutler_manifest.js
|
|
164
|
-
- app/assets/stylesheets/emailbutler
|
|
165
|
+
- app/assets/stylesheets/emailbutler.scss
|
|
166
|
+
- app/assets/stylesheets/emailbutler/core/base.scss
|
|
167
|
+
- app/assets/stylesheets/emailbutler/shared/footer.scss
|
|
168
|
+
- app/assets/stylesheets/emailbutler/shared/header.scss
|
|
169
|
+
- app/assets/stylesheets/emailbutler/views/dashboard.scss
|
|
165
170
|
- app/controllers/emailbutler/application_controller.rb
|
|
171
|
+
- app/controllers/emailbutler/ui/messages_controller.rb
|
|
172
|
+
- app/controllers/emailbutler/ui_controller.rb
|
|
166
173
|
- app/controllers/emailbutler/webhooks_controller.rb
|
|
174
|
+
- app/views/emailbutler/ui/index.html.erb
|
|
175
|
+
- app/views/emailbutler/ui/shared/_footer.html.erb
|
|
176
|
+
- app/views/emailbutler/ui/shared/_header.html.erb
|
|
177
|
+
- app/views/emailbutler/ui/show.html.erb
|
|
167
178
|
- app/views/layouts/emailbutler/application.html.erb
|
|
168
179
|
- config/routes.rb
|
|
169
|
-
- db/migrate/20220916162720_create_emailbutler_tables.rb
|
|
170
180
|
- lib/emailbutler.rb
|
|
171
181
|
- lib/emailbutler/adapters/active_record.rb
|
|
172
182
|
- lib/emailbutler/configuration.rb
|
|
173
183
|
- lib/emailbutler/dsl.rb
|
|
174
184
|
- lib/emailbutler/engine.rb
|
|
185
|
+
- lib/emailbutler/helpers.rb
|
|
175
186
|
- lib/emailbutler/mailers/helpers.rb
|
|
176
187
|
- lib/emailbutler/version.rb
|
|
177
188
|
- lib/emailbutler/webhooks/mappers/sendgrid.rb
|
|
@@ -204,5 +215,5 @@ requirements: []
|
|
|
204
215
|
rubygems_version: 3.3.7
|
|
205
216
|
signing_key:
|
|
206
217
|
specification_version: 4
|
|
207
|
-
summary:
|
|
218
|
+
summary: Email tracker for Ruby on Rails applications.
|
|
208
219
|
test_files: []
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
-
* listed below.
|
|
4
|
-
*
|
|
5
|
-
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
-
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
-
*
|
|
8
|
-
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
-
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
-
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
-
* It is generally better to create a new file per style scope.
|
|
12
|
-
*
|
|
13
|
-
*= require_tree .
|
|
14
|
-
*= require_self
|
|
15
|
-
*/
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
class CreateEmailbutlerTables < ActiveRecord::Migration[7.0]
|
|
2
|
-
def self.up
|
|
3
|
-
enable_extension 'pgcrypto' unless extensions.include?('pgcrypto')
|
|
4
|
-
enable_extension 'uuid-ossp' unless extensions.include?('uuid-ossp')
|
|
5
|
-
|
|
6
|
-
create_table :emailbutler_messages do |t|
|
|
7
|
-
t.uuid :uuid, null: false, default: ''
|
|
8
|
-
t.string :mailer, null: false
|
|
9
|
-
t.string :action, null: false
|
|
10
|
-
t.jsonb :params, null: false, default: {}
|
|
11
|
-
t.string :send_to, array: true
|
|
12
|
-
t.integer :status, null: false, default: 0
|
|
13
|
-
t.datetime :timestamp
|
|
14
|
-
t.integer :lock_version
|
|
15
|
-
t.timestamps
|
|
16
|
-
end
|
|
17
|
-
add_index :emailbutler_messages, :uuid, unique: true
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def self.down
|
|
21
|
-
drop_table :emailbutler_messages
|
|
22
|
-
end
|
|
23
|
-
end
|