smailer 0.2.1 → 0.2.3
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.md +93 -4
- data/generators/smailer/migration/migration_generator.rb +15 -0
- data/lib/generators/smailer/migration_generator.rb +18 -0
- data/lib/generators/{smailer_migration/templates/migration.rb → smailer/templates/migration.rb.erb} +1 -1
- data/lib/smailer/version.rb +1 -1
- data/rails/init.rb +1 -0
- metadata +7 -5
- data/lib/generators/smailer_migration/smailer_migration_generator.rb +0 -19
data/README.md
CHANGED
@@ -4,21 +4,110 @@
|
|
4
4
|
|
5
5
|
This project is a simple mailer for newsletters, which implements simple queue processing, basic campaign management and has some unsubscribe support.
|
6
6
|
|
7
|
-
It is intended to be used within a Rails project.
|
7
|
+
It is intended to be used within a Rails project. It has been tested with Rails 3.1.0 and Rails 2.3.5.
|
8
8
|
|
9
9
|
## Install
|
10
10
|
|
11
|
+
### Install the Gem
|
12
|
+
|
11
13
|
For Rails 3 projects, update your Gemfile and add:
|
14
|
+
|
12
15
|
gem 'smailer'
|
13
|
-
|
16
|
+
|
17
|
+
Then run `bundle install`. For Rails 2.x projects which do not use Bundler, add `gem 'smailer'` to your `environment.rb` file and then run `rake gems:install` in your project's root.
|
18
|
+
|
19
|
+
### Generate and run the migration
|
20
|
+
|
21
|
+
To create the tables needed by Smailer to operate, run the `smailer_migration` generator after installing the Gem. For Rails 3, you can do this:
|
22
|
+
|
23
|
+
rails g smailer_migration
|
24
|
+
|
25
|
+
For Rails 2.x projects, use `script/generate smailer_migration`.
|
14
26
|
|
15
27
|
## Usage and documentation
|
16
28
|
|
17
|
-
|
29
|
+
Sending out newsletters consists of a couple of steps:
|
30
|
+
|
31
|
+
* At least one record should exist in `Smailer::Models::MailingList`. This record can then be used for unsubscribe requests if your system supports multiple newsletter types.
|
32
|
+
* For each newsletter issue you intend to send, you should create a `Smailer::Models::MailCampaign` record. This record contains the subject and body contents of the newsletter you will be sending out.
|
33
|
+
* Given a list of active subscribers your application provides, you then enqueue mails to be send via the `MailCampaign#queued_mails` list (see the example below).
|
34
|
+
* Finally, you should call `Smailer::Tasks::Send.execute` repeatedly to process and send-out the enqueued emails.
|
35
|
+
|
36
|
+
### Issuing a newsletter
|
37
|
+
|
38
|
+
This is an example how you could proceed with creating and issuing a newsletter:
|
39
|
+
|
40
|
+
# locate the mailing list we'll be sending to
|
41
|
+
list = Smailer::Models::MailingList.first
|
42
|
+
|
43
|
+
# create a corresponding mail campaign
|
44
|
+
campaign_params = {
|
45
|
+
:from => 'noreply@example.org',
|
46
|
+
:subject => 'My First Campaign!',
|
47
|
+
:body_html => '<h1>Hello</h1><p>World</p>',
|
48
|
+
:body_text => 'Hello, world!',
|
49
|
+
:mailing_list_id => list.id,
|
50
|
+
}
|
51
|
+
campaign = Smailer::Models::MailCampaign.new campaign_params
|
52
|
+
campaign.add_unsubscribe_method :all
|
53
|
+
campaign.save!
|
54
|
+
|
55
|
+
# enqueue mails to be sent out
|
56
|
+
subscribers = %w[
|
57
|
+
subscriber@domain.com
|
58
|
+
office@company.com
|
59
|
+
contact@store.com
|
60
|
+
]
|
61
|
+
subscribers.each do |subscriber|
|
62
|
+
campaign.queued_mails.create! :to => subscriber
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
### Managing unsubscriptions
|
67
|
+
|
68
|
+
There are a few unsubscription methods supported. The most common one is probably via a unsubscribe link in the email.
|
69
|
+
|
70
|
+
In order to help you with implementing it, Smailer provides you with some interpolations you can use in the email's body:
|
71
|
+
|
72
|
+
* `%{email}` -- the concrete email this message will be sent to (example: `someone@company.com`)
|
73
|
+
* `%{escaped_email}` -- the same as `%{email}`, but safe to be put within an HTML-version of the message
|
74
|
+
* `%{email_key}` -- a unique key identifying the %{email} field (example: `34d9ddf91edb4d0206837b125f4a2750`)
|
75
|
+
* `%{mail_campaign_id}` -- the ID of the `Smailer::Models::MailCampaign` record for this message
|
76
|
+
* `%{mailing_list_id}` -- the ID of the `Smailer::Models::MailingList` record this mail campaign is for
|
77
|
+
* `%{message_key}` -- a unique key, identifying the message to be sent out; this key can later be used for view statistics tracking and bounce email processing
|
78
|
+
|
79
|
+
Here is an example text you could include in the HTML version of your email to show a unsubscribe link (this also demonstrates how interpolation in the email's body works):
|
80
|
+
|
81
|
+
<p>If you wish to be removed from our mailinglist go here: <a href="http://yourcomain.com/unsubscribe/%{email_key}">http://yourcomain.com/unsubscribe/%{email_key}</a>.</p>
|
82
|
+
<p>You are subscribed to the list with the email address: %{escaped_email}</p>
|
83
|
+
|
84
|
+
You have to implement a route in your Rails app to handle '/unsubscribe/:email_key'. For example, it could go to `UnsubscribeController#unsubscribe`, which you could implement like so:
|
85
|
+
|
86
|
+
@email = Smailer::Models::MailKey.find_by_key(params[:email_key]).try(:email)
|
87
|
+
raise ActiveRecord::RecordNotFound unless @email
|
88
|
+
|
89
|
+
# here you have the @email address of the user who wishes to unsubscribe
|
90
|
+
# and can mark it in your system accordingly (or remove it from your lists altogether)
|
91
|
+
|
92
|
+
### Sending mails
|
93
|
+
|
94
|
+
The emails which have been placed in the queue previously, have to be sent out at some point. This can be done for example with a Rake task which is run periodically via a Cron daemon. Here's an example Rake task:
|
95
|
+
|
96
|
+
# lib/tasks/smailer.rake
|
97
|
+
namespace :smailer do
|
98
|
+
desc 'Send out a batch of queued emails.'
|
99
|
+
task :send_batch => :environment do
|
100
|
+
result = Smailer::Tasks::Send.execute
|
101
|
+
result.each do |queue_item, status|
|
102
|
+
puts "Sending #{queue_item.to}: #{status}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
This task can be executed via `RAILS_ENV=production bundle exec rake smailer:send_batch` (provided you are running it on your production servers).
|
18
108
|
|
19
109
|
## TODO
|
20
110
|
|
21
|
-
* Add a migration generator
|
22
111
|
* Tests, tests, tests
|
23
112
|
|
24
113
|
## Contribution
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Smailer
|
2
|
+
class MigrationGenerator < Rails::Generators::Base
|
3
|
+
desc "Create a migration file with definitions of the tables needed to run Smailer."
|
4
|
+
|
5
|
+
def manifest
|
6
|
+
file_name = 'create_smailer_tables'
|
7
|
+
@migration_name = file_name.camelize
|
8
|
+
template_path = File.expand_path('../../lib/generators/smailer/templates/migration.rb.erb', File.dirname(__FILE__))
|
9
|
+
|
10
|
+
record do |m|
|
11
|
+
m.migration_template template_path, File.join('db', 'migrate'), :migration_file_name => file_name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "rails/generators/active_record"
|
2
|
+
|
3
|
+
module Smailer
|
4
|
+
class MigrationGenerator < Rails::Generators::Base
|
5
|
+
include Rails::Generators::Migration
|
6
|
+
extend ActiveRecord::Generators::Migration
|
7
|
+
|
8
|
+
desc "Create a migration file with definitions of the tables needed to run Smailer."
|
9
|
+
source_root File.expand_path('../templates', __FILE__)
|
10
|
+
|
11
|
+
def generate_migration
|
12
|
+
file_name = 'create_smailer_tables'
|
13
|
+
@migration_name = file_name.camelize
|
14
|
+
|
15
|
+
migration_template 'migration.rb.erb', "db/migrate/#{file_name}.rb"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/smailer/version.rb
CHANGED
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path('../lib/smailer', File.dirname(__FILE__))
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 3
|
10
|
+
version: 0.2.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Dimitar Dimitrov
|
@@ -48,8 +48,9 @@ files:
|
|
48
48
|
- Gemfile
|
49
49
|
- README.md
|
50
50
|
- Rakefile
|
51
|
-
-
|
52
|
-
- lib/generators/
|
51
|
+
- generators/smailer/migration/migration_generator.rb
|
52
|
+
- lib/generators/smailer/migration_generator.rb
|
53
|
+
- lib/generators/smailer/templates/migration.rb.erb
|
53
54
|
- lib/smailer.rb
|
54
55
|
- lib/smailer/compatibility.rb
|
55
56
|
- lib/smailer/models.rb
|
@@ -62,6 +63,7 @@ files:
|
|
62
63
|
- lib/smailer/tasks.rb
|
63
64
|
- lib/smailer/tasks/send.rb
|
64
65
|
- lib/smailer/version.rb
|
66
|
+
- rails/init.rb
|
65
67
|
- smailer.gemspec
|
66
68
|
has_rdoc: true
|
67
69
|
homepage: http://github.com/mitio/smailer
|
@@ -1,19 +0,0 @@
|
|
1
|
-
class SmailerMigrationGenerator < Rails::Generators::Base
|
2
|
-
desc "This generator creates a migration file containing definitions of the tables needed to run Smailer."
|
3
|
-
|
4
|
-
def create_migration_file
|
5
|
-
root = File.dirname(__FILE__)
|
6
|
-
source = File.expand_path 'templates/migration.rb', root
|
7
|
-
destination = Rails.root.join("db/migrate/#{next_migration_number}_create_smailer_tables.rb")
|
8
|
-
|
9
|
-
FileUtils.cp source, destination
|
10
|
-
|
11
|
-
puts "Created #{destination}"
|
12
|
-
end
|
13
|
-
|
14
|
-
protected
|
15
|
-
|
16
|
-
def next_migration_number
|
17
|
-
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
18
|
-
end
|
19
|
-
end
|