email_campaign 0.1.5 → 0.1.6
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
@@ -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
|
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 »</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 =>
|
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 =>
|
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 =>
|
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 =>
|
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,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
|
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.
|
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
|