email_campaign 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,11 +2,9 @@
2
2
 
3
3
  For mailings related to Rails apps, email_campaign is designed to be a more flexible, more integrated (yet well-abstracted) alternative to email campaign services like Campaign Monitor and MailChimp. Designed to use SendGrid for delivery, but this is easy changed.
4
4
 
5
- Does its best to prevent clients from sending too frequently and ruining your sender reputation, but no guarantees.
6
-
7
5
  =Roadmap
8
6
 
9
- 0.x: Basic campaign authoring and delivery, using template created by developer as a standard Rails mailer layout.
7
+ 0.x: Basic campaign authoring, delivery and tracking.
10
8
  1.0: Robust enough for production use, will be able to deal with 90% of common failure modes on its own.
11
9
  1.2: Delivery stats and graphs.
12
10
 
@@ -14,6 +12,102 @@ Does its best to prevent clients from sending too frequently and ruining your se
14
12
 
15
13
  Still pre-1.0. If you have some time, write some code or tests, exercise existing functionality on non-critical apps, submit bug reports... otherwise stay away for now.
16
14
 
15
+ =How to Use
16
+
17
+ Add to Gemfile and install:
18
+
19
+ gem 'email_campaign'
20
+
21
+ # required
22
+ gem 'delayed_job'
23
+ gem 'daemons'
24
+
25
+ # pick a dj backend (we'll assume ActiveRecord, but there are others):
26
+ gem 'delayed_job_active_record
27
+
28
+ # recommended but not required
29
+ gem 'sanitize_email'
30
+ gem 'inline-style'
31
+
32
+ Run migrations:
33
+
34
+ rake email_campaign:install:migrations
35
+ rails generate delayed_job:active_record
36
+ rake db:migrate
37
+
38
+ Create a mailer, be sure to use EmailCampaign::EmailHelper:
39
+
40
+ class Campaign < ActionMailer::Base
41
+ default from: 'me@mysite.com'
42
+ helper EmailCampaign::EmailHelper
43
+ layout 'campaign'
44
+
45
+ def campaign2013a(recipient)
46
+ # @method, and @identifier are used by our EmailHelper for tracking
47
+ @method = __method__
48
+ @identifier = recipient.identifier
49
+
50
+ # @subject is used so we can use the same template for email and web
51
+ @subject = 'First mailing with email_campaign'
52
+ mail(:to => recipient.to_s, :subject => @subject)
53
+ end
54
+ end
55
+
56
+ Add some of these to your mailer layout and template:
57
+
58
+ <!-- web version link -->
59
+ <%- if @identifier -%>
60
+ <div id="top-notice">
61
+ Not seeing any images in this email? <a href="<%= email_web_version_url %>">View it online &raquo;</a>
62
+ </div>
63
+ <%- end -%>
64
+
65
+ <!-- trackable link -->
66
+ <%= email_link_url('http://www.mysite.com/') %>
67
+
68
+ <!-- unsubscribe link -->
69
+ <%- if @identifier -%>
70
+ <p>If you do not wish to receive these emails, you may <a href="<%= email_unsubscribe_url %>">unsubscribe now</a>.</p>
71
+ <%- end -%>
72
+
73
+ <!-- inserts invisible tracking image to track opens -->
74
+ <%= email_tracking_tag %>
75
+
76
+ You'll need a controller to handle tracking, unsubscribe/resubscribe and web versions.
77
+
78
+ class EmailController < ApplicationController
79
+ # reuse the email layout (optional, but recommended)
80
+ layout 'campaign'
81
+
82
+ # include the helper, just like we did in the mailer
83
+ helper EmailCampaign::EmailHelper
84
+
85
+ # adds #open, #link, #unsubscribe/#resubscribe, #web_version
86
+ include EmailCampaign::Handler
87
+
88
+ # must be named the same way as your mailer method
89
+ # Again, @method is used for tracking, and @subject is used so we can use the same template for email and web.
90
+ # Here, we copy the subject directly from the mailer. Not pretty, but does avoid duplication.
91
+ def campaign2013a
92
+ @method = __method__
93
+ @subject = Campaign.send(__method__, EmailCampaign::Recipient.new).subject
94
+ render :template => '/campaign/campaign2013a'
95
+ end
96
+ end
97
+
98
+ Add routes. In this case, the old-style default works well:
99
+
100
+ match 'email(/:action(/:id))' => 'email'
101
+
102
+ Finally, create an initializer that sets base_url (since urls in emails need to include hostname and protocol) and optionally controller_name (to tell email_campaign about the controller you created above):
103
+
104
+ # Set base url that will be prepended to url paths in emails
105
+ EmailCampaign::Config.base_url = ENV['BaseURL'] || 'http://mysite.com'
106
+
107
+ # (Optional, can be auto-detected) Specify the name of the controller that includes
108
+ # EmailCampaign::Handler as it would appear in url_for(:controller => '...')
109
+ EmailCampaign::Config.controller_name = 'email'
110
+
17
111
  =Getting Help
18
112
 
19
113
  Get paid support for EmailCampaign straight from the people who made it: {Bigger Bird Creative, Inc.}[https://www.biggerbird.com] Not required, of course. :-) Free support is up top (Issues).
@@ -3,7 +3,7 @@ module EmailCampaign
3
3
 
4
4
  def email_tracking_tag
5
5
  if @identifier
6
- image_tag(EmailCampaign::Config.base_url + url_for(:controller => 'email', :action => 'open', :method => @method, :k => @identifier), :size => '1x1', :alt => '')
6
+ image_tag(EmailCampaign::Config.base_url + url_for(:controller => EmailCampaign::Config.controller_name, :action => 'open', :method => @method, :k => @identifier), :size => '1x1', :alt => '')
7
7
  else
8
8
  image_tag(EmailCampaign::Config.base_url + path_to_image('email_campaign/open-tracker.gif'), :size => '1x1', :alt => '')
9
9
  end
@@ -11,18 +11,18 @@ module EmailCampaign
11
11
 
12
12
  def email_link_url(url)
13
13
  if @identifier
14
- EmailCampaign::Config.base_url + url_for(:controller => 'email', :action => 'link', :url => url, :k => @identifier)
14
+ EmailCampaign::Config.base_url + url_for(:controller => EmailCampaign::Config.controller_name, :action => 'link', :url => url, :k => @identifier)
15
15
  else
16
16
  url
17
17
  end
18
18
  end
19
19
 
20
20
  def email_unsubscribe_url
21
- EmailCampaign::Config.base_url + url_for(:controller => 'email', :action => 'unsubscribe', :k => @identifier)
21
+ EmailCampaign::Config.base_url + url_for(:controller => EmailCampaign::Config.controller_name, :action => 'unsubscribe', :k => @identifier)
22
22
  end
23
23
 
24
24
  def email_web_version_url
25
- EmailCampaign::Config.base_url + url_for(:controller => 'email', :action => 'web_version', :method => @method, :k => @identifier)
25
+ EmailCampaign::Config.base_url + url_for(:controller => EmailCampaign::Config.controller_name, :action => 'web_version', :method => @method, :k => @identifier)
26
26
  end
27
27
 
28
28
  end
@@ -0,0 +1,9 @@
1
+ module EmailCampaign
2
+ class Config
3
+
4
+ class << self
5
+ attr_accessor :base_url, :controller_name
6
+ end
7
+
8
+ end
9
+ end
@@ -16,10 +16,4 @@ module EmailCampaign
16
16
 
17
17
  end
18
18
 
19
- class Config
20
- class << self
21
- attr_accessor :base_url
22
- end
23
- end
24
-
25
19
  end
@@ -0,0 +1,60 @@
1
+ module EmailCampaign
2
+ module Handler
3
+
4
+ def self.included(base)
5
+ EmailCampaign::Config.controller_name = base.controller_name
6
+ end
7
+
8
+ def open
9
+ EmailCampaign::Recipient.record_open(params[:k]) if params[:k]
10
+
11
+ options = {}
12
+ options[:disposition] = 'inline'
13
+ path = File.join(Rails.root, 'public/assets/email_campaign/open-tracker.gif')
14
+ send_file path, options
15
+ end
16
+
17
+ # deprecated, remove after 4/1/2013
18
+ def asset
19
+ EmailCampaign::Recipient.record_open(params[:k]) if params[:k]
20
+
21
+ options = {}
22
+ options[:disposition] = [ 'jpg', 'jpeg', 'gif', 'png' ].include?(params[:format].downcase) ? 'inline' : 'attachment'
23
+
24
+ path = File.join(Rails.root, 'app', 'assets', 'images', 'email', params[:method].to_s, params[:filename] + '.' + params[:format])
25
+ if !File.exists?(path)
26
+ path = File.join(Rails.root, 'app', 'assets', 'images', 'email', params[:filename] + '.' + params[:format])
27
+ end
28
+ render :text => 'Not Found', :status => 404 and return if !File.exists?(path)
29
+
30
+ send_file path, options
31
+ end
32
+
33
+ def link
34
+ EmailCampaign::Recipient.record_click(params[:k]) if params[:k]
35
+ redirect_to params[:url]
36
+ end
37
+
38
+ def unsubscribe
39
+ if params[:k]
40
+ @success = EmailCampaign::Recipient.unsubscribe(params[:k])
41
+ else
42
+ render :text => "No subscriber identifier given, cannot continue."
43
+ end
44
+ end
45
+
46
+ def resubscribe
47
+ if params[:k]
48
+ @success = EmailCampaign::Recipient.resubscribe(params[:k])
49
+ else
50
+ render :text => "No subscriber identifier given, cannot continue."
51
+ end
52
+ end
53
+
54
+ def web_version
55
+ EmailCampaign::Recipient.record_click(params[:k]) if params[:k]
56
+ redirect_to :action => params[:id]
57
+ end
58
+
59
+ end
60
+ end
@@ -1,3 +1,3 @@
1
1
  module EmailCampaign
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: email_campaign
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -119,7 +119,9 @@ files:
119
119
  - db/migrate/201302281520_add_recipient_identifier.rb
120
120
  - email_campaign.gemspec
121
121
  - lib/email_campaign.rb
122
+ - lib/email_campaign/config.rb
122
123
  - lib/email_campaign/engine.rb
124
+ - lib/email_campaign/handler.rb
123
125
  - lib/email_campaign/version.rb
124
126
  - script/rails
125
127
  - test/dummy/README.rdoc