mail_spy 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
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)