mail_spy 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +58 -2
- data/app/assets/javascripts/mail_spy/application.js +2 -0
- data/app/assets/javascripts/mail_spy/sendgrid.js +2 -0
- data/app/assets/stylesheets/mail_spy/application.css +0 -1
- data/app/assets/stylesheets/mail_spy/global.css.scss +0 -0
- data/app/assets/stylesheets/mail_spy/sendgrid.css +4 -0
- data/app/controllers/mail_spy/sendgrid_controller.rb +26 -0
- data/app/controllers/mail_spy/tracking_controller.rb +3 -10
- data/app/helpers/mail_spy/email_helper.rb +13 -4
- data/app/helpers/mail_spy/sendgrid_helper.rb +4 -0
- data/app/mailers/mail_spy/core_mailer.rb +6 -12
- data/app/models/mail_spy/email.rb +19 -4
- data/app/views/mail_spy/reports/campaigns.html.erb +48 -0
- data/config/routes.rb +6 -0
- data/lib/generators/mail_spy/templates/mail_spy.rb +5 -0
- data/lib/mail_spy/manager.rb +68 -16
- data/lib/mail_spy/sendgrid/smtp_api_header.rb +68 -0
- data/lib/mail_spy/version.rb +1 -1
- data/lib/mail_spy.rb +4 -1
- data/test/dummy/config/initializers/mail_spy.rb +4 -0
- data/test/dummy/config/routes.rb +1 -1
- data/test/dummy/log/test.log +2204 -0
- data/test/functional/mail_spy/sendgrid_controller_test.rb +9 -0
- data/test/functional/mail_spy/tracking_controller_test.rb +2 -1
- data/test/unit/helpers/mail_spy/sendgrid_helper_test.rb +6 -0
- metadata +13 -2
data/README.rdoc
CHANGED
@@ -24,7 +24,7 @@ and AWS settings
|
|
24
24
|
|
25
25
|
Then mount the engine in the routes.rb file
|
26
26
|
Rails.application.routes.draw do
|
27
|
-
mount MailSpy::Engine => "/
|
27
|
+
mount MailSpy::Engine => "/mail"
|
28
28
|
end
|
29
29
|
|
30
30
|
== Usage
|
@@ -42,7 +42,6 @@ MailSpy.create_email(options)
|
|
42
42
|
|
43
43
|
required options include:
|
44
44
|
|
45
|
-
* :template_name
|
46
45
|
* :campaign :top level grouping
|
47
46
|
* :stream : mid level grouping
|
48
47
|
* :component : bottom level grouping
|
@@ -54,6 +53,63 @@ required options include:
|
|
54
53
|
* one of [:to, :cc, :bcc]
|
55
54
|
|
56
55
|
|
56
|
+
== Sendgrid
|
57
|
+
|
58
|
+
MailSpy has bindings baked in for sendgrid event notification.
|
59
|
+
|
60
|
+
To enable simply configure sendgrid to send post notifications (no batch support yet)
|
61
|
+
to YOUR_HOST/mount_path/sendgrid/notification
|
62
|
+
|
63
|
+
The mount path is usually 'mail' but is configurable in your routes file
|
64
|
+
|
65
|
+
finally add
|
66
|
+
|
67
|
+
esp.options = {
|
68
|
+
:enable_sendgrid_event_tracking => true
|
69
|
+
}
|
70
|
+
|
71
|
+
to your initializers/mail_spy.rb file
|
72
|
+
|
73
|
+
This will automatically add in the sendgrid smtp api headers and record all
|
74
|
+
events you have setup using the sendgrid admin interface.
|
75
|
+
|
76
|
+
Reminder: If you are using open and click tracking using MailSpy adding them
|
77
|
+
to sendgrid will be redundant and harmful.
|
78
|
+
|
79
|
+
== Google Analytics
|
80
|
+
|
81
|
+
MailSpy has automatic bindings for google analytics.
|
82
|
+
|
83
|
+
MailSpy requires that all emails form into the campaign, stream, component
|
84
|
+
structure which lends itself nicely to a direct mapping in google analytics.
|
85
|
+
|
86
|
+
utm_source => MailSpy - #{tracker_host}
|
87
|
+
utm_medium => email
|
88
|
+
utm_campaign => campaign
|
89
|
+
utm_term => stream
|
90
|
+
utm_content => component
|
91
|
+
|
92
|
+
To enable automatic bindings with all links generated by 'track_link' and
|
93
|
+
helper simply add
|
94
|
+
|
95
|
+
esp.options = {
|
96
|
+
:enable_auto_google_analytics => true
|
97
|
+
}
|
98
|
+
|
99
|
+
to your initializers/mail_spy.rb file
|
100
|
+
|
101
|
+
if you prefer to assign GA settings manually you can do that directly as
|
102
|
+
a option to MailSpy.create_email
|
103
|
+
|
104
|
+
the keys are:
|
105
|
+
|
106
|
+
* utm_source
|
107
|
+
* utm_medium
|
108
|
+
* utm_campaign
|
109
|
+
* utm_term
|
110
|
+
* utm_content
|
111
|
+
|
112
|
+
Again only links built with track_link will benefit from the GA tokens
|
57
113
|
|
58
114
|
== Testing
|
59
115
|
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module MailSpy
|
2
|
+
class SendgridController < ApplicationController
|
3
|
+
|
4
|
+
#Parses a notification from the sendgrid system
|
5
|
+
def notification
|
6
|
+
#Must be passed in via SendGrids SMTP API Headers
|
7
|
+
email_id = params['eid']
|
8
|
+
return head 400 if email_id.blank? || params[:event].blank?
|
9
|
+
|
10
|
+
#Send grid event name
|
11
|
+
event_action = "sendgrid-#{params[:event]}"
|
12
|
+
|
13
|
+
case event
|
14
|
+
when 'bounce', 'dropped'
|
15
|
+
MailSpy.track_action(email_id, event_action, {:reason => params[:reason]})
|
16
|
+
when 'click'
|
17
|
+
MailSpy.track_action(email_id, event_action, {:url => params[:url]})
|
18
|
+
when 'deferred', 'delivered', 'processed', 'open', 'spamreport', 'unsubscribe'
|
19
|
+
MailSpy.track_action(email_id, event_action)
|
20
|
+
end
|
21
|
+
|
22
|
+
head :ok
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -33,20 +33,13 @@ module MailSpy
|
|
33
33
|
def action
|
34
34
|
email_id = params[:eid]
|
35
35
|
action_type = params[:action_type]
|
36
|
-
|
36
|
+
count = params[:count] || 1
|
37
|
+
details = params[:details] || {}
|
37
38
|
|
38
39
|
head :unprocessable_entity and return if email_id.blank? || action_type.blank?
|
39
40
|
head :unprocessable_entity and return if details.present? && !details.kind_of?(Hash)
|
40
41
|
|
41
|
-
|
42
|
-
hash[:action_type] = action_type
|
43
|
-
hash[:count] = params[:count] if !params[:count].nil?
|
44
|
-
hash[:details] = details if details.present? && details.kind_of?(Hash)
|
45
|
-
|
46
|
-
# Save it up
|
47
|
-
email = MailSpy::Email.find(email_id)
|
48
|
-
email.actions.create!(hash)
|
49
|
-
|
42
|
+
MailSpy.track_action(email_id, action_type, details, count)
|
50
43
|
head 200
|
51
44
|
end
|
52
45
|
end
|
@@ -21,15 +21,24 @@ module MailSpy
|
|
21
21
|
tag_options = tag_options(html_options)
|
22
22
|
|
23
23
|
# Inject our tracking url, and pass in the redirect_url
|
24
|
-
|
24
|
+
hash = {
|
25
25
|
:controller => "mail_spy/tracking",
|
26
26
|
:action => :link,
|
27
27
|
:url => url,
|
28
28
|
:only_path => false,
|
29
29
|
:host => MailSpy.tracker_host,
|
30
30
|
:n => @_track_count,
|
31
|
-
:eid => @
|
32
|
-
|
31
|
+
:eid => @_email.id
|
32
|
+
}
|
33
|
+
|
34
|
+
# Add in the GA tokens if present
|
35
|
+
hash[:utm_source] = @_email.utm_source if @_email.utm_source.present?
|
36
|
+
hash[:utm_medium] = @_email.utm_medium if @_email.utm_medium.present?
|
37
|
+
hash[:utm_campaign] = @_email.utm_campaign if @_email.utm_campaign.present?
|
38
|
+
hash[:utm_term] = @_email.utm_term if @_email.utm_term.present?
|
39
|
+
hash[:utm_content] = @_email.utm_content if @_email.utm_content.present?
|
40
|
+
|
41
|
+
url = url_for(hash)
|
33
42
|
|
34
43
|
|
35
44
|
href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
|
@@ -43,7 +52,7 @@ module MailSpy
|
|
43
52
|
url = url_for(
|
44
53
|
:controller => "mail_spy/tracking",
|
45
54
|
:action => :bug,
|
46
|
-
:eid => @
|
55
|
+
:eid => @_email.id,
|
47
56
|
:only_path => false,
|
48
57
|
:host => MailSpy.tracker_host
|
49
58
|
)
|
@@ -4,34 +4,28 @@ module MailSpy
|
|
4
4
|
|
5
5
|
def template(email)
|
6
6
|
# Slight hack to provide information to helpers
|
7
|
-
@
|
7
|
+
@_email = email
|
8
8
|
@template_values = email.template_values
|
9
|
+
esp = MailSpy.esps[email.email_service_provider]
|
9
10
|
email_hash = {}
|
10
11
|
|
11
|
-
|
12
12
|
# Evaluate the subject line as erb
|
13
13
|
if email.subject.present?
|
14
14
|
subject = ERB.new(email.subject).result(binding)
|
15
|
-
email_hash[:subject] =
|
15
|
+
email_hash[:subject] = subject
|
16
16
|
end
|
17
17
|
|
18
18
|
# Set Headers
|
19
19
|
std_email_keys = [:to, :cc, :bcc, :from, :message_id, :sender, :reply_to]
|
20
|
-
std_email_keys.each { |key| set_if_present(email_hash,email, key) }
|
21
|
-
|
20
|
+
std_email_keys.each { |key| set_if_present(email_hash, email, key) }
|
21
|
+
email.headers.each {|key, value| headers[key] = value} if email.headers.present?
|
22
22
|
|
23
|
+
# Create the mail message
|
23
24
|
mail_message = mail(email_hash) do |format|
|
24
25
|
format.text { render :inline => email.text_erb }
|
25
26
|
format.html { render :inline => email.html_erb }
|
26
27
|
end
|
27
28
|
|
28
|
-
# Email Service provider setup
|
29
|
-
# TODO Only support smtp at the moment
|
30
|
-
raise "No Email service providers installed" unless MailSpy.esps.present?
|
31
|
-
esp = MailSpy.esps[email.email_service_provider]
|
32
|
-
esp_key = MailSpy.esps.keys[rand(MailSpy.esps.keys.count)]
|
33
|
-
esp = MailSpy.esps[esp_key] if esp.blank?
|
34
|
-
|
35
29
|
mail_message.delivery_method.settings.merge!(
|
36
30
|
{
|
37
31
|
:address => esp.address,
|
@@ -13,14 +13,15 @@ module MailSpy
|
|
13
13
|
field :subject
|
14
14
|
field :sender #Sets envelope from (aka sender header)
|
15
15
|
field :reply_to
|
16
|
-
field :headers
|
16
|
+
field :headers, :type => Hash, :default => {}
|
17
17
|
field :message_id #Sets the unique id for each email
|
18
18
|
|
19
19
|
# Email content
|
20
|
-
field :template_values, :type => Hash
|
20
|
+
field :template_values, :type => Hash, :default => {}
|
21
21
|
|
22
22
|
# Support for tracking which esp ran the email
|
23
23
|
field :email_service_provider, :type => String
|
24
|
+
validates_presence_of :email_service_provider
|
24
25
|
|
25
26
|
# References back to a user in another db
|
26
27
|
field :user_id, :type => Integer
|
@@ -34,10 +35,24 @@ module MailSpy
|
|
34
35
|
field :schedule_at, :type => DateTime
|
35
36
|
field :sent, :type => Boolean, :default => false
|
36
37
|
index :schedule_at
|
38
|
+
index :sent
|
39
|
+
|
40
|
+
# Error reporting
|
41
|
+
field :failed, :type => Boolean, :default => false
|
42
|
+
field :error_message, :type => String
|
43
|
+
field :error_backtrace, :type => Array
|
44
|
+
index :failed
|
37
45
|
|
38
46
|
# Record keeping of what happened
|
39
47
|
embeds_many :actions, :class_name => "MailSpy::Action"
|
40
48
|
|
49
|
+
# Google Analytics tracking
|
50
|
+
field :utm_source, :type => String
|
51
|
+
field :utm_medium, :type => String
|
52
|
+
field :utm_campaign, :type => String
|
53
|
+
field :utm_term, :type => String
|
54
|
+
field :utm_content, :type => String
|
55
|
+
|
41
56
|
|
42
57
|
def template_values
|
43
58
|
self.read_attribute(:template_values).try(:with_indifferent_access)
|
@@ -45,11 +60,11 @@ module MailSpy
|
|
45
60
|
|
46
61
|
# Great for debugging emails
|
47
62
|
def parsed_html_content
|
48
|
-
return MailSpy::CoreMailer.template(self).
|
63
|
+
return MailSpy::CoreMailer.template(self).html_part.body.to_s
|
49
64
|
end
|
50
65
|
|
51
66
|
def parsed_text_content
|
52
|
-
return MailSpy::CoreMailer.template(self).
|
67
|
+
return MailSpy::CoreMailer.template(self).text_part.body.to_s
|
53
68
|
end
|
54
69
|
|
55
70
|
def html_erb
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<% @campaigns = [{
|
2
|
+
:name=>"Valentine's Day",
|
3
|
+
:last_sent => Date.today(),
|
4
|
+
:sent=>5320
|
5
|
+
},{
|
6
|
+
:name=>"Mother's Day"
|
7
|
+
}] %>
|
8
|
+
<%= debug @campaigns %>
|
9
|
+
<%# ------------------------------------- Backbone Templates %>
|
10
|
+
<script type="text/javascript">
|
11
|
+
|
12
|
+
Campaign = Backbone.Model.extend({
|
13
|
+
initialize: function(){
|
14
|
+
alert("Welcome to this world");
|
15
|
+
}
|
16
|
+
});
|
17
|
+
CampaignView = Backbone.View.extend({
|
18
|
+
initialize: function(){
|
19
|
+
this.render();
|
20
|
+
},
|
21
|
+
render: function(){
|
22
|
+
// Compile the template using underscore
|
23
|
+
var template = _.template( $("#campaign_template").html(), {} );
|
24
|
+
// Load the compiled HTML into the Backbone "el"
|
25
|
+
this.el.html( template );
|
26
|
+
}
|
27
|
+
});
|
28
|
+
|
29
|
+
var search_view = new SearchView({ el: $("#search_container") });
|
30
|
+
</script>
|
31
|
+
<%# ------------------------------------- Backbone Templates %>
|
32
|
+
<script type="text/template" id="campaign_template">
|
33
|
+
<div class="Campaign">
|
34
|
+
<h2><%= c[:name] %></h2>
|
35
|
+
</div>
|
36
|
+
</script>
|
37
|
+
<%# ------------------------------------- Start actual view %>
|
38
|
+
|
39
|
+
<h1>All Campaigns</h1>
|
40
|
+
|
41
|
+
<div class="CampaignReport">
|
42
|
+
<%# For each campaign %>
|
43
|
+
<% @campaigns.each do |c| %>
|
44
|
+
<div class="CampaignSummary">
|
45
|
+
<h2><%= c[:name] %></h2>
|
46
|
+
</div>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
data/config/routes.rb
CHANGED
@@ -4,4 +4,10 @@ MailSpy::Engine.routes.draw do
|
|
4
4
|
match "b", :controller => :tracking, :action => :bug
|
5
5
|
match "a", :controller => :tracking, :action => :action
|
6
6
|
|
7
|
+
match "reports", :controller => :reports, :action => :campaigns
|
8
|
+
match "email", :controller => :reports, :action => :email
|
9
|
+
|
10
|
+
# Sendgrid notification api
|
11
|
+
post "sendgrid/notification", :controller => :sendgrid, :action => :notification
|
12
|
+
|
7
13
|
end
|
@@ -28,6 +28,7 @@ end
|
|
28
28
|
# :password,
|
29
29
|
# :domain,
|
30
30
|
# :enable_starttls_auto
|
31
|
+
# :options (esp specific options)
|
31
32
|
|
32
33
|
MailSpy.add_email_service_provider do |esp|
|
33
34
|
esp.name = "sendgrid"
|
@@ -38,4 +39,8 @@ MailSpy.add_email_service_provider do |esp|
|
|
38
39
|
esp.password = ENV['SENDGRID_PASSWORD']
|
39
40
|
esp.authentication = :plain
|
40
41
|
esp.enable_starttls_auto = true
|
42
|
+
esp.options = {
|
43
|
+
:enable_sendgrid_event_tracking => true,
|
44
|
+
:enable_auto_google_analytics => true
|
45
|
+
}
|
41
46
|
end
|
data/lib/mail_spy/manager.rb
CHANGED
@@ -23,15 +23,45 @@ module MailSpy
|
|
23
23
|
has_sender = options.keys.select { |option| to_options.include? option.intern }.present?
|
24
24
|
raise "Email instance has no sender (to,cc,bcc were all blank)" unless has_sender
|
25
25
|
|
26
|
-
|
27
|
-
#
|
28
|
-
|
26
|
+
# Make sure that all options passed map to a accessor so we don't errantly
|
27
|
+
# think we are passing something correctly and really its getting silently
|
28
|
+
# ignored
|
29
|
+
options.keys.each do |option|
|
29
30
|
unless MailSpy::Email.method_defined? "#{option}=".intern
|
30
31
|
raise "MailSpy::Email doesn't have #{option} as a setter '"
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
35
|
+
# Ensure that a esp (forced or random) exists for the email
|
36
|
+
forced_esp = options[:email_service_provider]
|
37
|
+
if forced_esp.present?
|
38
|
+
raise "No esp configured with name: #{forced_esp}" if MailSpy.esps[forced_esp].blank?
|
39
|
+
else
|
40
|
+
raise "No esps configured" if MailSpy.esps.blank?
|
41
|
+
esp_key = MailSpy.esps.keys[rand(MailSpy.esps.keys.count)]
|
42
|
+
options[:email_service_provider] = esp_key
|
43
|
+
end
|
44
|
+
|
45
|
+
# Google Analytics aupport for automatic population of utm_tokens
|
46
|
+
esp = MailSpy.esps[options[:email_service_provider]]
|
47
|
+
if esp.options[:enable_auto_google_analytics].present?
|
48
|
+
options[:utm_source] ||= 'mailspy'
|
49
|
+
options[:utm_medium] ||= 'email'
|
50
|
+
options[:utm_campaign] ||= options[:campaign]
|
51
|
+
options[:utm_term] ||= options[:stream]
|
52
|
+
options[:utm_content] ||= options[:component]
|
53
|
+
end
|
54
|
+
|
55
|
+
#Create the email
|
34
56
|
email = MailSpy::Email.create!(options)
|
57
|
+
|
58
|
+
#Enable sendgrid specific enhancements
|
59
|
+
if esp.options[:enable_sendgrid_event_tracking].present?
|
60
|
+
header = MailSpy::Sendgrid::SmtpApiHeader.new
|
61
|
+
header.setUniqueArgs({:eid => email.id})
|
62
|
+
email.headers = {'X-SMTPAPI' => header.asJSON}.merge(email.headers)
|
63
|
+
end
|
64
|
+
|
35
65
|
email.save!
|
36
66
|
email
|
37
67
|
end
|
@@ -52,17 +82,24 @@ module MailSpy
|
|
52
82
|
pony_hash[pony_key] = value if value.present?
|
53
83
|
end
|
54
84
|
|
55
|
-
while
|
56
|
-
|
85
|
+
while true
|
86
|
+
emails = MailSpy::Email.
|
57
87
|
limit(step).offset(offset).
|
58
|
-
where(:schedule_at.lte => DateTime.now, :sent => false).all
|
88
|
+
where(:schedule_at.lte => DateTime.now, :sent => false, :failed => false).all
|
59
89
|
break if mails.blank?
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
90
|
+
emails.each do |email|
|
91
|
+
begin
|
92
|
+
mail = MailSpy::CoreMailer.template(email)
|
93
|
+
#TODO might be nice to flush mail out in debug mode
|
94
|
+
mail.deliver
|
95
|
+
email.update_attribute(:sent, true)
|
96
|
+
sent += 1
|
97
|
+
rescue Exception => e
|
98
|
+
email.failed = true
|
99
|
+
email.error_message = e.message
|
100
|
+
email.error_backtrace = e.backtrace
|
101
|
+
email.save!
|
102
|
+
end
|
66
103
|
end
|
67
104
|
offset += step
|
68
105
|
end
|
@@ -72,10 +109,25 @@ module MailSpy
|
|
72
109
|
|
73
110
|
|
74
111
|
# ------------------------------------------- TRACKING
|
75
|
-
#
|
76
|
-
|
77
|
-
|
78
|
-
|
112
|
+
# MailSpy will automatically track opens and clicks if the tracking bugs
|
113
|
+
# and track_link helpers are used. This action allows tracking of
|
114
|
+
# arbitrary actions. Please be careful to standardize on action names
|
115
|
+
# email_id: The id from the MailSpy::Email record
|
116
|
+
# action_type: String denoting the action that occured
|
117
|
+
# details: Hash of any details of that action (again strive for standards)
|
118
|
+
# count: how many of this action occurred (defaults to 1)
|
119
|
+
def track_action(email_id, action_type, details={}, count=1)
|
120
|
+
raise "track_action missing email_id" if email_id.blank?
|
121
|
+
raise "track_Action missing action_type" if action_type.blank?
|
122
|
+
|
123
|
+
hash ={}
|
124
|
+
hash[:action_type] = action_type
|
125
|
+
hash[:count] = count
|
126
|
+
hash[:details] = details if details.present? && details.kind_of?(Hash)
|
127
|
+
|
128
|
+
# Save it up
|
129
|
+
email = MailSpy::Email.find(email_id)
|
130
|
+
email.actions.create!(hash)
|
79
131
|
end
|
80
132
|
|
81
133
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Version 1.0
|
2
|
+
# Last Updated 6/22/2009
|
3
|
+
# Header support for send grids smtp api
|
4
|
+
#
|
5
|
+
#
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module MailSpy
|
9
|
+
module Sendgrid
|
10
|
+
class SmtpApiHeader
|
11
|
+
|
12
|
+
def initialize()
|
13
|
+
@data = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def addTo(to)
|
17
|
+
@data['to'] ||= []
|
18
|
+
@data['to'] += to.kind_of?(Array) ? to : [to]
|
19
|
+
end
|
20
|
+
|
21
|
+
def addSubVal(var, val)
|
22
|
+
if not @data['sub']
|
23
|
+
@data['sub'] = {}
|
24
|
+
end
|
25
|
+
if val.instance_of?(Array)
|
26
|
+
@data['sub'][var] = val
|
27
|
+
else
|
28
|
+
@data['sub'][var] = [val]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def setUniqueArgs(val)
|
33
|
+
if val.instance_of?(Hash)
|
34
|
+
@data['unique_args'] = val
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def setCategory(cat)
|
39
|
+
@data['category'] = cat
|
40
|
+
end
|
41
|
+
|
42
|
+
def addFilterSetting(fltr, setting, val)
|
43
|
+
if not @data['filters']
|
44
|
+
@data['filters'] = {}
|
45
|
+
end
|
46
|
+
if not @data['filters'][fltr]
|
47
|
+
@data['filters'][fltr] = {}
|
48
|
+
end
|
49
|
+
if not @data['filters'][fltr]['settings']
|
50
|
+
@data['filters'][fltr]['settings'] = {}
|
51
|
+
end
|
52
|
+
@data['filters'][fltr]['settings'][setting] = val
|
53
|
+
end
|
54
|
+
|
55
|
+
def asJSON()
|
56
|
+
json = JSON.generate @data
|
57
|
+
return json.gsub(/(["\]}])([,:])(["\[{])/, '\\1\\2 \\3')
|
58
|
+
end
|
59
|
+
|
60
|
+
def as_string()
|
61
|
+
json = asJSON()
|
62
|
+
str = 'X-SMTPAPI: %s' % json.gsub(/(.{1,72})( +|$\n?)|(.{1,72})/, "\\1\\3\n")
|
63
|
+
return str
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/mail_spy/version.rb
CHANGED
data/lib/mail_spy.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'pp' #For debugging
|
2
2
|
require 'aws-sdk'
|
3
|
+
require 'mail_spy/sendgrid/smtp_api_header'
|
3
4
|
require "mongoid"
|
4
5
|
require "mail_spy/engine"
|
5
6
|
require "mail_spy/manager"
|
@@ -11,7 +12,7 @@ module MailSpy
|
|
11
12
|
# Allows the client to configure and add esps to MailSpy
|
12
13
|
MailSpyESP = Struct.new(
|
13
14
|
:address, :port, :authentication, :user_name, :password, :domain,
|
14
|
-
:enable_starttls_auto, :name
|
15
|
+
:enable_starttls_auto, :name, :options
|
15
16
|
)
|
16
17
|
@@esps = {}
|
17
18
|
|
@@ -30,7 +31,9 @@ module MailSpy
|
|
30
31
|
#TODO eventually have this be a view with a interface
|
31
32
|
def self.add_email_service_provider(&block)
|
32
33
|
esp = MailSpyESP.new
|
34
|
+
esp.options = {} # Important! provides default options list for internals
|
33
35
|
block.call(esp)
|
36
|
+
esp.options.to_options!
|
34
37
|
@@esps[esp.name] = esp
|
35
38
|
end
|
36
39
|
|
data/test/dummy/config/routes.rb
CHANGED