emailbutler 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -2
- data/app/controllers/emailbutler/ui/messages_controller.rb +3 -3
- data/app/controllers/emailbutler/ui_controller.rb +6 -6
- data/app/controllers/emailbutler/webhooks_controller.rb +5 -2
- data/app/helpers/emailbutler/application_helper.rb +1 -1
- data/app/views/emailbutler/ui/index.html.erb +1 -1
- data/lib/emailbutler/configuration.rb +4 -2
- data/lib/emailbutler/version.rb +1 -1
- data/lib/emailbutler/webhooks/mappers/smtp2go.rb +38 -0
- data/lib/emailbutler/webhooks/receiver.rb +11 -9
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 612e4bc27184b6105020c585995ebb90cf6bc7f1d1d18cdd8833d22e762cc7c1
|
4
|
+
data.tar.gz: fc6c91f52ffdde4dba4585d685b7a5c4173793aa2c355d9593b2fcf852189781
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fb3f49d372b3bc87a0131913796bd0073d95a41521f53f351420223dbf14e0067d62d6e3f58b4bc9efee591736fc6e922d7e97d21aae4b373a32e92d446b317
|
7
|
+
data.tar.gz: a7930ffe63ac272075fe9af8bb1201b388bda1045c228815cb26ad64885c1189bdf84a2d610addcbeaa0c5bb73d6e2187aea1cb375d1b3a2e8a3773f455a5816
|
data/README.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# Emailbutler
|
2
2
|
Simple email tracker for Ruby on Rails applications.
|
3
|
-
Emailbutler allows you to track delivery status of emails sent by your app.
|
3
|
+
Emailbutler allows you to track delivery status of emails sent by your app through Sendgrid and/or SMTP2GO.
|
4
|
+
|
5
|
+
There are situations when you need to check whether a certain letter or certain type of letters was successfully sent from the application, and through the UI of some providers you can try to find such a letter by the recipient or the subject of the letter, but sometimes it's not enough.
|
6
|
+
|
7
|
+
Emailbutler allows you to monitor the sending of letters, collects notifications from providers about the success of delivery and adds an UI for monitoring deliveries with filtering by recipients, mailers and actions.
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
@@ -32,6 +36,7 @@ Emailbutler.configure do |config|
|
|
32
36
|
config.ui_username = 'username'
|
33
37
|
config.ui_password = 'password'
|
34
38
|
config.ui_secured_environments = ['production']
|
39
|
+
config.skip_before_actions = %i[verify_authenticity_token]
|
35
40
|
end
|
36
41
|
```
|
37
42
|
|
@@ -42,6 +47,37 @@ Add this line to config/routes.rb
|
|
42
47
|
mount Emailbutler::Engine => '/emailbutler'
|
43
48
|
```
|
44
49
|
|
50
|
+
#### Custom routes
|
51
|
+
|
52
|
+
If you need some custom behaviour you can specify your own route and use custom controller, something like
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class SendgridController < ApplicationController
|
56
|
+
skip_before_action :basic_authentication
|
57
|
+
skip_before_action :verify_authenticity_token
|
58
|
+
|
59
|
+
def create
|
60
|
+
... you can add some logic here
|
61
|
+
|
62
|
+
::Emailbutler::Webhooks::Receiver.call(
|
63
|
+
user_agent: request.headers['HTTP_USER_AGENT'],
|
64
|
+
payload: receiver_params.to_h
|
65
|
+
)
|
66
|
+
|
67
|
+
head :ok
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def receiver_params
|
73
|
+
params.permit(
|
74
|
+
'event', 'sendtime', 'message-id',
|
75
|
+
'_json' => %w[event timestamp smtp-id sg_message_id]
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
```
|
80
|
+
|
45
81
|
### UI styles
|
46
82
|
|
47
83
|
For adding styles for UI you need to add this line to assets/config/manifest.js
|
@@ -49,6 +85,12 @@ For adding styles for UI you need to add this line to assets/config/manifest.js
|
|
49
85
|
//= link emailbutler.css
|
50
86
|
```
|
51
87
|
|
88
|
+
Or in some cases you can specify it in assets/javascript/application.js
|
89
|
+
|
90
|
+
```js
|
91
|
+
//= require emailbutler_manifest
|
92
|
+
````
|
93
|
+
|
52
94
|
### Mailers
|
53
95
|
|
54
96
|
Update you application mailer
|
@@ -68,6 +110,14 @@ end
|
|
68
110
|
- select all deliverability data,
|
69
111
|
- save settings.
|
70
112
|
|
113
|
+
#### SMTP2GO
|
114
|
+
|
115
|
+
- go to [Mail settings](https://app-eu.smtp2go.com/settings/webhooks),
|
116
|
+
- turn on Webhooks,
|
117
|
+
- in the HTTP POST URL field, paste the URL to webhook controller of your app,
|
118
|
+
- select all deliverability data,
|
119
|
+
- save settings.
|
120
|
+
|
71
121
|
## Usage
|
72
122
|
|
73
123
|
1. Each event with sending email will create new record with message params in database.
|
@@ -81,6 +131,5 @@ Emailbutler provides UI with rendering email tracking statistics - /emailbutler/
|
|
81
131
|
|
82
132
|
<img width="1461" alt="ui_show" src="https://user-images.githubusercontent.com/6195394/202743225-b0ba0ca2-d373-428c-973d-5ec4566a3784.png">
|
83
133
|
|
84
|
-
|
85
134
|
## License
|
86
135
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -6,19 +6,19 @@ module Emailbutler
|
|
6
6
|
before_action :find_message
|
7
7
|
|
8
8
|
def update
|
9
|
-
Emailbutler.resend_message(@message)
|
9
|
+
::Emailbutler.resend_message(@message)
|
10
10
|
redirect_to ui_index_path
|
11
11
|
end
|
12
12
|
|
13
13
|
def destroy
|
14
|
-
Emailbutler.destroy_message(@message)
|
14
|
+
::Emailbutler.destroy_message(@message)
|
15
15
|
redirect_to ui_index_path
|
16
16
|
end
|
17
17
|
|
18
18
|
private
|
19
19
|
|
20
20
|
def find_message
|
21
|
-
@message = Emailbutler.find_message_by(uuid: params[:id])
|
21
|
+
@message = ::Emailbutler.find_message_by(uuid: params[:id])
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -4,18 +4,18 @@ require 'pagy'
|
|
4
4
|
|
5
5
|
module Emailbutler
|
6
6
|
class UiController < Emailbutler::ApplicationController
|
7
|
-
include Pagy::Backend
|
7
|
+
include ::Pagy::Backend
|
8
8
|
|
9
|
-
http_basic_authenticate_with name: Emailbutler.configuration.ui_username,
|
10
|
-
password: Emailbutler.configuration.ui_password,
|
9
|
+
http_basic_authenticate_with name: ::Emailbutler.configuration.ui_username,
|
10
|
+
password: ::Emailbutler.configuration.ui_password,
|
11
11
|
if: -> { basic_auth_enabled? }
|
12
12
|
|
13
13
|
def index
|
14
|
-
@summary = Emailbutler.count_messages_by_status
|
14
|
+
@summary = ::Emailbutler.count_messages_by_status
|
15
15
|
end
|
16
16
|
|
17
17
|
def show
|
18
|
-
@pagy, @messages = pagy(Emailbutler.find_messages_by(search_condition))
|
18
|
+
@pagy, @messages = pagy(::Emailbutler.find_messages_by(search_condition))
|
19
19
|
end
|
20
20
|
|
21
21
|
private
|
@@ -30,7 +30,7 @@ module Emailbutler
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def basic_auth_enabled?
|
33
|
-
configuration = Emailbutler.configuration
|
33
|
+
configuration = ::Emailbutler.configuration
|
34
34
|
|
35
35
|
return false if configuration.ui_username.blank?
|
36
36
|
return false if configuration.ui_password.blank?
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Emailbutler
|
4
4
|
class WebhooksController < Emailbutler::ApplicationController
|
5
|
-
skip_before_action
|
5
|
+
skip_before_action(*Emailbutler.configuration.skip_before_actions)
|
6
6
|
|
7
7
|
def create
|
8
8
|
::Emailbutler::Webhooks::Receiver.call(
|
@@ -16,7 +16,10 @@ module Emailbutler
|
|
16
16
|
private
|
17
17
|
|
18
18
|
def receiver_params
|
19
|
-
params.permit(
|
19
|
+
params.permit(
|
20
|
+
'event', 'sendtime', 'message-id',
|
21
|
+
'_json' => %w[event timestamp smtp-id sg_message_id]
|
22
|
+
)
|
20
23
|
end
|
21
24
|
end
|
22
25
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<span>Total</span>
|
7
7
|
<% end %>
|
8
8
|
</li>
|
9
|
-
<% Emailbutler.adapter.message_class.statuses.each_key do |status| %>
|
9
|
+
<% ::Emailbutler.adapter.message_class.statuses.each_key do |status| %>
|
10
10
|
<li>
|
11
11
|
<%= link_to ui_path(status), class: 'status-summary' do %>
|
12
12
|
<span><%= @summary[status].to_i %></span>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Emailbutler
|
4
4
|
class Configuration
|
5
|
-
attr_accessor :adapter, :ui_username, :ui_password, :ui_secured_environments
|
5
|
+
attr_accessor :adapter, :ui_username, :ui_password, :ui_secured_environments, :skip_before_actions
|
6
6
|
|
7
7
|
def initialize
|
8
8
|
@adapter = nil
|
@@ -10,9 +10,11 @@ module Emailbutler
|
|
10
10
|
# It's required to specify these 3 variables to enable basic auth to UI
|
11
11
|
@ui_username = ''
|
12
12
|
@ui_password = ''
|
13
|
-
|
14
13
|
# Secured environments variable must directly contains environment names
|
15
14
|
@ui_secured_environments = []
|
15
|
+
|
16
|
+
# Skip before_actions from your ApplicationController
|
17
|
+
@skip_before_actions = %i[verify_authenticity_token]
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
data/lib/emailbutler/version.rb
CHANGED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Emailbutler
|
4
|
+
module Webhooks
|
5
|
+
module Mappers
|
6
|
+
class Smtp2Go
|
7
|
+
DELIVERABILITY_MAPPER = {
|
8
|
+
'processed' => 'processed',
|
9
|
+
'delivered' => 'delivered',
|
10
|
+
'open' => 'delivered',
|
11
|
+
'click' => 'delivered',
|
12
|
+
'bounce' => 'failed',
|
13
|
+
'reject' => 'failed',
|
14
|
+
'spam' => 'failed'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
def self.call(...)
|
18
|
+
new.call(...)
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(payload:)
|
22
|
+
payload.stringify_keys!
|
23
|
+
message_uuid = payload['message-id']
|
24
|
+
status = DELIVERABILITY_MAPPER[payload['event']]
|
25
|
+
return [] if message_uuid.nil? || status.nil?
|
26
|
+
|
27
|
+
[
|
28
|
+
{
|
29
|
+
message_uuid: message_uuid,
|
30
|
+
status: status,
|
31
|
+
timestamp: payload['sendtime'] ? Time.at(payload['sendtime'].to_i).utc.to_datetime : nil
|
32
|
+
}
|
33
|
+
]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,18 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'emailbutler/webhooks/mappers/sendgrid'
|
4
|
+
require 'emailbutler/webhooks/mappers/smtp2go'
|
4
5
|
|
5
6
|
module Emailbutler
|
6
7
|
module Webhooks
|
7
8
|
class Receiver
|
8
9
|
SENDGRID_USER_AGENT = 'SendGrid Event API'
|
10
|
+
SMTP2GO_USER_AGENT = 'Go-http-client/1.1'
|
11
|
+
|
12
|
+
RECEIVERS_MAPPER = {
|
13
|
+
'SendGrid Event API' => Emailbutler::Webhooks::Mappers::Sendgrid,
|
14
|
+
'Go-http-client/1.1' => Emailbutler::Webhooks::Mappers::Smtp2Go
|
15
|
+
}.freeze
|
9
16
|
|
10
17
|
def self.call(...)
|
11
18
|
new.call(...)
|
12
19
|
end
|
13
20
|
|
14
21
|
def call(user_agent:, payload:)
|
15
|
-
|
22
|
+
mapper = RECEIVERS_MAPPER[user_agent]
|
23
|
+
return unless mapper
|
24
|
+
|
25
|
+
mapper
|
16
26
|
.call(payload: payload)
|
17
27
|
.each { |event|
|
18
28
|
message = Emailbutler.find_message_by(uuid: event.delete(:message_uuid))
|
@@ -21,14 +31,6 @@ module Emailbutler
|
|
21
31
|
Emailbutler.update_message(message, event)
|
22
32
|
}
|
23
33
|
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def select_mapper(user_agent)
|
28
|
-
case user_agent
|
29
|
-
when SENDGRID_USER_AGENT then Emailbutler::Webhooks::Mappers::Sendgrid
|
30
|
-
end
|
31
|
-
end
|
32
34
|
end
|
33
35
|
end
|
34
36
|
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.7.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: 2023-
|
11
|
+
date: 2023-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pagy
|
@@ -202,6 +202,7 @@ files:
|
|
202
202
|
- lib/emailbutler/mailers/helpers.rb
|
203
203
|
- lib/emailbutler/version.rb
|
204
204
|
- lib/emailbutler/webhooks/mappers/sendgrid.rb
|
205
|
+
- lib/emailbutler/webhooks/mappers/smtp2go.rb
|
205
206
|
- lib/emailbutler/webhooks/receiver.rb
|
206
207
|
- lib/generators/emailbutler/active_record_generator.rb
|
207
208
|
- lib/generators/emailbutler/templates/migration.erb
|