mail_spy 0.0.4 → 0.0.5

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.
data/README.rdoc CHANGED
@@ -20,6 +20,7 @@ Create the mongoid configuration for the mongo db
20
20
  rails g mail_spy:initializer
21
21
 
22
22
  Fill out the generated mailspy.rb with your esp settings (file has example)
23
+ and AWS settings
23
24
 
24
25
  Then mount the engine in the routes.rb file
25
26
  Rails.application.routes.draw do
@@ -32,13 +33,7 @@ Mailspy is centered around email templates and instances of those templates
32
33
  (aka emails).
33
34
 
34
35
  To create a template:
35
-
36
- MailSpy.create_template(template_name, html_erb, text_erb, template_values_definition)
37
-
38
- * Template name must be unique to all templates
39
- * html, and text are the contents for a multipart email
40
- * template_values_definition is a array of keys that should be present in the
41
- template values of each hash
36
+ add a template to your s3 directory, campaign/stream/component.(text|html).erb
42
37
 
43
38
 
44
39
  To create a instance:
@@ -21,8 +21,15 @@ 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
- url = url_for(:controller => "mail_spy/tracking", :action => :link, :url => url,
25
- :n => @_track_count, :eid => @_email_id)
24
+ url = url_for(
25
+ :controller => "mail_spy/tracking",
26
+ :action => :link,
27
+ :url => url,
28
+ :only_path => false,
29
+ :host => MailSpy.tracker_host,
30
+ :n => @_track_count,
31
+ :eid => @_email_id
32
+ )
26
33
 
27
34
 
28
35
  href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
@@ -33,7 +40,14 @@ module MailSpy
33
40
 
34
41
  # Support for open tracking, client support, etc
35
42
  def tracking_bug
36
- "<img src='#{url_for(:controller => "mail_spy/tracking", :action => :bug, :eid => @_email_id)}' />".html_safe
43
+ url = url_for(
44
+ :controller => "mail_spy/tracking",
45
+ :action => :bug,
46
+ :eid => @_email_id,
47
+ :only_path => false,
48
+ :host => MailSpy.tracker_host
49
+ )
50
+ "<img src='#{url}' style='display:none' width='1' height='1' border='0' />".html_safe
37
51
  end
38
52
 
39
53
  end
@@ -6,20 +6,23 @@ module MailSpy
6
6
  # Slight hack to provide information to helpers
7
7
  @_email_id = email.id
8
8
  @template_values = email.template_values
9
+ email_hash = {}
10
+
11
+
12
+ # Evaluate the subject line as erb
13
+ if email.subject.present?
14
+ subject = ERB.new(email.subject).result(binding)
15
+ email_hash[:subject] = subject
16
+ end
9
17
 
10
18
  # Set Headers
11
- email_hash = {}
12
- std_email_keys = [:to, :cc, :bcc, :from, :subject, :message_id, :sender, :reply_to]
19
+ std_email_keys = [:to, :cc, :bcc, :from, :message_id, :sender, :reply_to]
13
20
  std_email_keys.each { |key| set_if_present(email_hash,email, key) }
14
21
  headers.merge!(email.headers) if email.headers.present?
15
22
 
16
- # Content of the email
17
- html_erb = email.email_template.html_erb || ""
18
- text_erb = email.email_template.html_erb || ""
19
-
20
23
  mail_message = mail(email_hash) do |format|
21
- format.text { render :inline => text_erb }
22
- format.html { render :inline => html_erb }
24
+ format.text { render :inline => email.text_erb }
25
+ format.html { render :inline => email.html_erb }
23
26
  end
24
27
 
25
28
  # Email Service provider setup
@@ -3,6 +3,8 @@ module MailSpy
3
3
  include Mongoid::Document
4
4
  include Mongoid::Timestamps
5
5
 
6
+ @@template_cache = {}
7
+
6
8
  # Standard Email options
7
9
  field :to
8
10
  field :cc
@@ -15,9 +17,7 @@ module MailSpy
15
17
  field :message_id #Sets the unique id for each email
16
18
 
17
19
  # Email content
18
- field :template_name, :type => String
19
20
  field :template_values, :type => Hash
20
- belongs_to :email_template, :class_name => 'MailSpy::EmailTemplate'
21
21
 
22
22
  # Support for tracking which esp ran the email
23
23
  field :email_service_provider, :type => String
@@ -43,18 +43,6 @@ module MailSpy
43
43
  self.read_attribute(:template_values).try(:with_indifferent_access)
44
44
  end
45
45
 
46
-
47
- def email_parts
48
- template = self.email_template
49
- html_erb = template.html_erb
50
- text_erb = template.text_erb
51
- mail = MailSpy::DummyMailer.template(html_erb, text_erb, self.template_values)
52
- return {
53
- :html => mail.html_part.body.to_s,
54
- :text => mail.text_part.body.to_s
55
- }
56
- end
57
-
58
46
  # Great for debugging emails
59
47
  def parsed_html_content
60
48
  return MailSpy::CoreMailer.template(self).text_part.body.to_s
@@ -64,6 +52,37 @@ module MailSpy
64
52
  return MailSpy::CoreMailer.template(self).html_part.body.to_s
65
53
  end
66
54
 
55
+ def html_erb
56
+ load_template("html.erb")
57
+ end
58
+
59
+ def text_erb
60
+ load_template("text.erb")
61
+ end
62
+
63
+ protected
64
+
65
+ # Loads a template file from s3 using
66
+ def load_template(suffix)
67
+ raise "No aws_campaign_bucket_set" if MailSpy.aws_campaign_bucket.strip.blank?
68
+
69
+ # Check the cache using our convention
70
+ path = "#{self.campaign}/#{self.stream}/#{self.component}.#{suffix}"
71
+ return @@template_cache[path] if @@template_cache[path].present?
72
+
73
+ # Load the object from s3
74
+ s3 = AWS::S3.new(:access_key_id => MailSpy.aws_access_key_id,
75
+ :secret_access_key => MailSpy.aws_secret_access_key)
76
+ campaign_bucket = s3.buckets[MailSpy.aws_campaign_bucket]
77
+ campaign_bucket = buckets.create(MailSpy.aws_campaign_bucket) unless campaign_bucket.exists?
78
+ object = campaign_bucket.objects[path]
79
+ raise "no object found at path: #{path}" unless object.exists?
80
+
81
+ # Read and return
82
+ @@template_cache[path] = (object.read || "")
83
+ return @@template_cache[path]
84
+ end
85
+
67
86
 
68
87
  def self.generate_campaign_stats
69
88
 
@@ -1,3 +1,19 @@
1
+ # MailSpy configuration
2
+ # tracking_host: The hostname and port (if necessary) of the server MailSpy
3
+ # will make requests to for tracking.
4
+ #
5
+ # aws credentials: We use aws to store the templates for the emails.
6
+ #
7
+
8
+
9
+ MailSpy.configure do |config|
10
+ config.tracker_host = "myapp.herokuapp.com"
11
+ config.aws_access_key_id = "YOUR ACCESS KEY"
12
+ config.aws_secret_access_key = "YOUR SECRET ACCESS KEY"
13
+ config.aws_campaign_bucket = "campaigns-yourco-com"
14
+ end
15
+
16
+
1
17
  # MailSpy allows you to add multiple email service providers simply
2
18
  # call this method and specify the following options
3
19
  #
@@ -16,7 +32,7 @@
16
32
  MailSpy.add_email_service_provider do |esp|
17
33
  esp.name = "sendgrid"
18
34
  esp.address = "smtp.sendgrid.net"
19
- esp.port = "587",
35
+ esp.port = "587"
20
36
  esp.domain = "herokuapp.com"
21
37
  esp.user_name = ENV['SENDGRID_USERNAME']
22
38
  esp.password = ENV['SENDGRID_PASSWORD']
@@ -1,43 +1,28 @@
1
1
  module MailSpy
2
2
  module Manager
3
3
 
4
- # ------------------------------------------- ADD_TEMPLATE
5
- # Programmatically add email templates with a schema of search and
6
- # replaceable text
7
- #
8
- def create_template(name, html_erb, text_erb, template_values_definition)
9
- MailSpy::EmailTemplate.create!(
10
- {
11
- :name => name,
12
- :html_erb => html_erb,
13
- :text_erb => text_erb,
14
- :template_values_definition => template_values_definition
15
- })
16
- end
17
-
18
- # ------------------------------------------- ADD INSTANCE
4
+ # ------------------------------------------- CREATE EMAIL
19
5
  # Adds a instance of a email template to the queue to send
20
6
  #
21
7
  def create_email(options)
22
8
  options.to_options!
23
9
 
24
10
  required_options = [
25
- :template_name, :campaign, :stream, :component, :schedule_at, :subject,
11
+ :campaign, :stream, :component, :schedule_at, :subject,
26
12
  :template_values, :from, :reply_to]
27
13
  to_options = [:to, :cc, :bcc]
28
14
 
29
15
  # Ensure that we have the required options
30
16
  required_options.each { |ro| raise "create_email call missing #{ro}" unless options.include? ro }
31
17
 
18
+ # Ensure that the campaign, stream and component are not blank
19
+ # These keys are used to define the s3 paths for the templates
20
+ [:campaign, :stream, :component].each { |key| raise "##{key} can't be blank" if options[key].blank? }
21
+
32
22
  # Make sure we have someone to send to
33
23
  has_sender = options.keys.select { |option| to_options.include? option.intern }.present?
34
24
  raise "Email instance has no sender (to,cc,bcc were all blank)" unless has_sender
35
25
 
36
- # Make sure we have a template
37
- options[:template_name]
38
- template = MailSpy::EmailTemplate.first(conditions: {name: options[:template_name]})
39
- raise "No template: #{options[:template_name]} found, try create_template first" unless template
40
-
41
26
 
42
27
  # Make sure that
43
28
  (required_options + to_options).each do |option|
@@ -46,9 +31,7 @@ module MailSpy
46
31
  end
47
32
  end
48
33
 
49
-
50
34
  email = MailSpy::Email.create!(options)
51
- email.email_template = template
52
35
  email.save!
53
36
  email
54
37
  end
@@ -75,7 +58,9 @@ module MailSpy
75
58
  where(:schedule_at.lte => DateTime.now, :sent => false).all
76
59
  break if mails.blank?
77
60
  mails.each do |email|
78
- MailSpy::CoreMailer.template(email).deliver
61
+ mail = MailSpy::CoreMailer.template(email)
62
+ #TODO might be nice to flush mail out in debug mode
63
+ mail.deliver
79
64
  email.update_attribute(:sent, true)
80
65
  sent += 1
81
66
  end
@@ -1,3 +1,3 @@
1
1
  module MailSpy
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/mail_spy.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'pp' #For debugging
2
+ require 'aws-sdk'
2
3
  require "mongoid"
3
4
  require "mail_spy/engine"
4
5
  require "mail_spy/manager"
@@ -14,12 +15,17 @@ module MailSpy
14
15
  )
15
16
  @@esps = {}
16
17
 
17
- #@@config = MailSpyConfig.new
18
+ MailSpyConfig = Struct.new(
19
+ :tracker_host, :aws_access_key_id,
20
+ :aws_secret_access_key, :aws_campaign_bucket
21
+
22
+ )
23
+ @@config = MailSpyConfig.new
18
24
 
19
25
  # Allows the initializer to set the configuration
20
- #def self.configure(&block)
21
- # block.call(@@config)
22
- #end
26
+ def self.configure(&block)
27
+ block.call(@@config)
28
+ end
23
29
 
24
30
  #TODO eventually have this be a view with a interface
25
31
  def self.add_email_service_provider(&block)
@@ -32,5 +38,24 @@ module MailSpy
32
38
  @@esps
33
39
  end
34
40
 
41
+ def self.tracker_host
42
+ @@config.tracker_host
43
+ end
44
+
45
+ def self.template_directory
46
+ @@config.template_directory
47
+ end
48
+
49
+ def self.aws_access_key_id
50
+ @@config.aws_access_key_id
51
+ end
52
+
53
+ def self.aws_secret_access_key
54
+ @@config.aws_secret_access_key
55
+ end
56
+
57
+ def self.aws_campaign_bucket
58
+ @@config.aws_campaign_bucket
59
+ end
35
60
 
36
61
  end
@@ -0,0 +1,15 @@
1
+ <p>
2
+ You should be able to click on the link and have the server record the even
3
+ and forward you to the correct place.
4
+
5
+ A link : <%= track_link 'My home', 'www.google.com' %>
6
+ </p>
7
+
8
+ <br>
9
+
10
+ <p>
11
+ You should be able to show images in the email client and have the server
12
+ track the open
13
+ A Bug is in the parenthesis (<%= tracking_bug %>)
14
+ </p>
15
+
@@ -0,0 +1,11 @@
1
+ You should be able to click on the link and have the server record the even
2
+ and forward you to the correct place.
3
+
4
+ A link : <%= track_link 'My home', 'www.google.com' %>
5
+ ---------------------------
6
+
7
+ You should be able to show images in the email client and have the server
8
+ track the open
9
+ A Bug is in the parenthesis (<%= tracking_bug %>)
10
+
11
+
@@ -14,7 +14,7 @@ Dummy::Application.configure do
14
14
  config.action_controller.perform_caching = false
15
15
 
16
16
  # Don't care if the mailer can't send
17
- config.action_mailer.raise_delivery_errors = false
17
+ config.action_mailer.raise_delivery_errors = true
18
18
 
19
19
  # Print deprecation notices to the Rails logger
20
20
  config.active_support.deprecation = :log
@@ -5,7 +5,7 @@ Dummy::Application.configure do
5
5
  config.cache_classes = true
6
6
 
7
7
  # Full error reports are disabled and caching is turned on
8
- config.consider_all_requests_local = false
8
+ config.consider_all_requests_local = false
9
9
  config.action_controller.perform_caching = true
10
10
 
11
11
  # Disable Rails's static asset server (Apache or nginx will already do this)
@@ -64,4 +64,8 @@ Dummy::Application.configure do
64
64
  # Log the query plan for queries taking more than this (works
65
65
  # with SQLite, MySQL, and PostgreSQL)
66
66
  # config.active_record.auto_explain_threshold_in_seconds = 0.5
67
+
68
+ # Raise errors on mailer failure
69
+ config.action_mailer.raise_delivery_errors = true
70
+
67
71
  end
@@ -27,11 +27,14 @@ Dummy::Application.configure do
27
27
  # Tell Action Mailer not to deliver emails to the real world.
28
28
  # The :test delivery method accumulates sent emails in the
29
29
  # ActionMailer::Base.deliveries array.
30
- config.action_mailer.delivery_method = :test
30
+ config.action_mailer.delivery_method = :smtp
31
31
 
32
32
  # Raise exception on mass assignment protection for Active Record models
33
33
  config.active_record.mass_assignment_sanitizer = :strict
34
34
 
35
35
  # Print deprecation notices to the stderr
36
36
  config.active_support.deprecation = :stderr
37
+
38
+ # Raise errors on mailer failure
39
+ config.action_mailer.raise_delivery_errors = true
37
40
  end
@@ -0,0 +1,38 @@
1
+ # MailSpy configuration
2
+ # tracking_host: The hostname and port (if necessary) of the server MailSpy
3
+ # will make requests to for tracking.
4
+
5
+
6
+ MailSpy.configure do |config|
7
+ config.tracker_host = "localhost:5000"
8
+ config.aws_access_key_id = "AKIAIF6DRMAH3BR47AZQ"
9
+ config.aws_secret_access_key = "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"
10
+ config.aws_campaign_bucket = "daviacalendar-mailspy"
11
+ end
12
+
13
+
14
+ # MailSpy allows you to add multiple email service providers simply
15
+ # call this method and specify the following options
16
+ #
17
+ # :name (must be unique for all esps you add)
18
+ # :via (stmp or sendmail)
19
+ #
20
+ # SMTP OPTIONS
21
+ # :address,
22
+ # :port,
23
+ # :authentication,
24
+ # :user_name,
25
+ # :password,
26
+ # :domain,
27
+ # :enable_starttls_auto
28
+
29
+ MailSpy.add_email_service_provider do |esp|
30
+ esp.name = "sendgrid"
31
+ esp.address = "smtp.sendgrid.net"
32
+ esp.port = "587"
33
+ esp.domain = "herokuapp.com"
34
+ esp.user_name = "app2602840@heroku.com"
35
+ esp.password = "qb6qnim0"
36
+ esp.authentication = :plain
37
+ esp.enable_starttls_auto = true
38
+ end
@@ -1,4 +1,3 @@
1
1
  Rails.application.routes.draw do
2
-
3
2
  mount MailSpy::Engine => "/mail_spy"
4
3
  end
@@ -0,0 +1,8 @@
1
+ namespace :emails do
2
+
3
+ desc "Send helper test emails to test email"
4
+ task :send_helper_test => :environment do
5
+
6
+ end
7
+
8
+ end
@@ -210,3 +210,15 @@ MONGODB dummy_development['mail_spy_emails'].find({}).limit(-1).sort([[:_id, :de
210
210
  MONGODB dummy_development['mail_spy_emails'].find({}).limit(-1).sort([[:_id, :desc]])
211
211
  MONGODB dummy_development['system.namespaces'].find({})
212
212
  MONGODB dummy_development['mail_spy_emails'].find({}).limit(-1).sort([[:_id, :desc]])
213
+ MONGODB [WARNING] Please note that logging negatively impacts client-side performance. You should set your logging level no lower than :info in production.
214
+ MONGODB admin['$cmd'].find({:ismaster=>1}).limit(-1)
215
+ MONGODB [WARNING] Please note that logging negatively impacts client-side performance. You should set your logging level no lower than :info in production.
216
+ MONGODB admin['$cmd'].find({:ismaster=>1}).limit(-1)
217
+ MONGODB [WARNING] Please note that logging negatively impacts client-side performance. You should set your logging level no lower than :info in production.
218
+ MONGODB admin['$cmd'].find({:ismaster=>1}).limit(-1)
219
+ MONGODB [WARNING] Please note that logging negatively impacts client-side performance. You should set your logging level no lower than :info in production.
220
+ MONGODB admin['$cmd'].find({:ismaster=>1}).limit(-1)
221
+ MONGODB [WARNING] Please note that logging negatively impacts client-side performance. You should set your logging level no lower than :info in production.
222
+ MONGODB admin['$cmd'].find({:ismaster=>1}).limit(-1)
223
+ MONGODB [WARNING] Please note that logging negatively impacts client-side performance. You should set your logging level no lower than :info in production.
224
+ MONGODB admin['$cmd'].find({:ismaster=>1}).limit(-1)