aws_ses_newsletters 0.0.1
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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +118 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/aws_ses_newsletters/application.js +13 -0
- data/app/assets/stylesheets/aws_ses_newsletters/application.css +15 -0
- data/app/controllers/aws_ses_newsletters/application_controller.rb +5 -0
- data/app/controllers/aws_ses_newsletters/email_responses_controller.rb +71 -0
- data/app/helpers/aws_ses_newsletters/application_helper.rb +4 -0
- data/app/models/aws_ses_newsletters/email_response.rb +7 -0
- data/app/models/aws_ses_newsletters/newsletter.rb +4 -0
- data/app/views/layouts/aws_ses_newsletters/application.html.erb +14 -0
- data/app/workers/aws_ses_newsletters/newsletters_sender.rb +107 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20160410174449_create_aws_ses_newsletters_newsletters.rb +12 -0
- data/db/migrate/20160411205706_create_aws_ses_newsletters_email_responses.rb +11 -0
- data/lib/aws_ses_newsletters.rb +5 -0
- data/lib/aws_ses_newsletters/engine.rb +10 -0
- data/lib/aws_ses_newsletters/html_builder.rb +29 -0
- data/lib/aws_ses_newsletters/mail_builder.rb +40 -0
- data/lib/aws_ses_newsletters/version.rb +3 -0
- data/lib/tasks/aws_ses_newsletters_tasks.rake +4 -0
- metadata +177 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f8cf510cd0e29876670ef28739b0222642ab5e6c
|
4
|
+
data.tar.gz: 07b6efac74634925389d304a05bd2cb5302976c3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1e44ff3b4a92e6b934c45a3ac8780a83cca6f7d50d5e613ae097383878f7d46a16511ed3b1f0dc15a576a06b344c691b9a0c2679adb205ce90a7c348d2bf0b6a
|
7
|
+
data.tar.gz: 0a0167cb316ebdd28e19832cd077cdec0a3b63cc60efd8f96a505f4a2365cfafe6401ac3ca9fc44781a8bcd17b6d370c58bb591d1047b42dd8e6ad58e88c7847
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2016 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
= AwsSesNewsletters
|
2
|
+
|
3
|
+
This project rocks and uses MIT-LICENSE.
|
4
|
+
|
5
|
+
{<img src="https://codeship.com/projects/1ddc9a90-e61d-0133-54a1-0e12c0a498c1/status?branch=master" alt="Status?branch=master" />}[https://codeship.com/projects/146708]
|
6
|
+
|
7
|
+
== What is AwsSesNewsletters
|
8
|
+
|
9
|
+
AwsSesNewsletters is a Rails plugin or, using the new nomenclature a gemified plugin, that allows you to
|
10
|
+
very easily construct newsletters that are going to be sent with Amazon SES. In other words, it is a wrapper
|
11
|
+
over aws-ses that provides some basic functionality to construct the emails and a common workflow to send
|
12
|
+
the emails.
|
13
|
+
|
14
|
+
== Dependencies
|
15
|
+
|
16
|
+
1. https://github.com/drewblas/aws-ses
|
17
|
+
2. https://github.com/premailer/premailer
|
18
|
+
3. https://github.com/mperham/sidekiq
|
19
|
+
|
20
|
+
== How to install
|
21
|
+
|
22
|
+
=== Install the gem, either as
|
23
|
+
<tt>gem install aws_ses_newsletters</tt>
|
24
|
+
|
25
|
+
or adding
|
26
|
+
|
27
|
+
<tt>gem 'aws_ses_newsletters'</tt> to your Gemfile and running <tt>bundle install</tt>
|
28
|
+
|
29
|
+
=== Install the needed migrations, to generate the table for Newsletters & Emails Responses
|
30
|
+
<tt>rake aws_ses_newsletters:install:migrations</tt>
|
31
|
+
|
32
|
+
This will add 2 migration, that you need to run:
|
33
|
+
|
34
|
+
<tt>rake db:migrate</tt>
|
35
|
+
|
36
|
+
=== Mount the engine in the path of your preference. In <b>routes.rb</b>
|
37
|
+
<tt>mount AwsSesNewsletters::Engine, at: "/newsletters"</tt>
|
38
|
+
|
39
|
+
This will add 2 new routes to your application:
|
40
|
+
a. POST newsletters/email_responses/bounce
|
41
|
+
b. POST newsletters/email_responses/complaint
|
42
|
+
|
43
|
+
These are the routes you need to configure in *SNS* to receive notifications for bounces and complaints respectively.
|
44
|
+
|
45
|
+
=== Add your amazon keys
|
46
|
+
a. SES_ACCESS_KEY_ID
|
47
|
+
b. SES_SECRET_ACCESS_KEY
|
48
|
+
|
49
|
+
In heroku, you need to set them as:
|
50
|
+
|
51
|
+
heroku config:set SES_ACCESS_KEY_ID=<you_access_keid>
|
52
|
+
heroku config:set SES_SECRET_ACCESS_KEY=<you_secret_access_key>
|
53
|
+
|
54
|
+
== Usage
|
55
|
+
|
56
|
+
To create a Newsletter, you need to inherit from AwsSesNewsletters::NewslettersSender and implement 2 methods:
|
57
|
+
1. create_newsletter: which should create & return a AwsSesNewsletters::Newsletter
|
58
|
+
2. get_recipients: which should iterate over your recipients and yield with them. For example:
|
59
|
+
|
60
|
+
# def get_recipients
|
61
|
+
# recipient = Recipient.new('fzuppa@10pines.com', 'Federico', 'Zuppa')
|
62
|
+
# yield recipient
|
63
|
+
# end
|
64
|
+
|
65
|
+
After creating this class, you will usually execute it asynchronously using sidekiq:
|
66
|
+
|
67
|
+
<tt>YourClass.perform_async</tt>
|
68
|
+
|
69
|
+
To test it in the rails console, of course that you can do *YourClass.new.perform*
|
70
|
+
|
71
|
+
== A few important use cases
|
72
|
+
|
73
|
+
There is a demo project that shows the most important use cases I had inmind when building this plugin: https://github.com/10Pines/aws_ses_newsletters_demo
|
74
|
+
|
75
|
+
Here's a quick explanation of them:
|
76
|
+
|
77
|
+
=== Create the html using ERB
|
78
|
+
|
79
|
+
There is a helper class to do this called AwsSesNewsletters::HtmlBuilder. It takes 2 parameters
|
80
|
+
|
81
|
+
a. The template erb that will be used to construct the html
|
82
|
+
b. A hash with variables needed to construct the html
|
83
|
+
|
84
|
+
For example, take a look at NewslettersWithVariableReplacementsSender in the demo:
|
85
|
+
|
86
|
+
html_body: AwsSesNewsletters::HtmlBuilder.new(
|
87
|
+
"#{::Rails.root}/app/views/newsletter_with_instance_variables.html.erb",
|
88
|
+
{promotions: [OpenStruct.new(name: '10% off this week')]}
|
89
|
+
).build
|
90
|
+
|
91
|
+
=== Replace strings after the html is built
|
92
|
+
You need to do this to put the recipient's email for each mail or an unsubscription token (those were the 2 things I needed)
|
93
|
+
|
94
|
+
If you want to perform such replacement, just override <tt>do_custom_replacements_for(email, recipient)</tt>
|
95
|
+
|
96
|
+
For example:
|
97
|
+
def do_custom_replacements_for(mail, recipient)
|
98
|
+
mail.html_part.body = mail.html_part.body.raw_source.gsub('recipient_email', recipient.email)
|
99
|
+
end
|
100
|
+
|
101
|
+
=== Send inline attachments
|
102
|
+
This is discouraged. I found out after building the gem and that is why I left it (in case you need it)
|
103
|
+
|
104
|
+
To do such thing, simply override <tt>get_images</tt> returning a hash of images.
|
105
|
+
def get_images
|
106
|
+
images = {}
|
107
|
+
images["logo10pines"] = File.read(Rails.root.join('public/mailresources/logo-fullcolor_150px.png'))
|
108
|
+
images
|
109
|
+
end
|
110
|
+
|
111
|
+
In the html, simply put the id that you used in the hash.
|
112
|
+
|
113
|
+
<img src="logo10pines" %>
|
114
|
+
|
115
|
+
Please look at the demo example that it will be much easier to understand!
|
116
|
+
|
117
|
+
==== Author: Federico Zuppa
|
118
|
+
mailto:fzuppa@10pines.com
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'AwsSesNewsletters'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/test_app/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require_dependency "aws_ses_newsletters/application_controller"
|
2
|
+
|
3
|
+
module AwsSesNewsletters
|
4
|
+
class EmailResponsesController < ApplicationController
|
5
|
+
skip_before_action :verify_authenticity_token
|
6
|
+
before_action :log_incoming_message
|
7
|
+
|
8
|
+
def bounce
|
9
|
+
# TODO: get a certificate and make this secure
|
10
|
+
# return render json: {} unless aws_message.authentic?
|
11
|
+
|
12
|
+
if type != 'Bounce'
|
13
|
+
puts "Not a bounce - exiting"
|
14
|
+
return render json: {}
|
15
|
+
end
|
16
|
+
|
17
|
+
bounce = message['bounce']
|
18
|
+
bouncerecps = bounce['bouncedRecipients']
|
19
|
+
bouncerecps.each do |recp|
|
20
|
+
email = recp['emailAddress']
|
21
|
+
extra_info = "status: #{recp['status']}, action: #{recp['action']}, diagnosticCode: #{recp['diagnosticCode']}"
|
22
|
+
|
23
|
+
EmailResponse.create ({ email: email, response_type: 'bounce', extra_info: extra_info})
|
24
|
+
end
|
25
|
+
|
26
|
+
render json: {}
|
27
|
+
end
|
28
|
+
|
29
|
+
def complaint
|
30
|
+
#return render json: {} unless aws_message.authentic?
|
31
|
+
|
32
|
+
if type != 'Complaint'
|
33
|
+
Rails.logger.info "Not a complaint - exiting"
|
34
|
+
return render json: {}
|
35
|
+
end
|
36
|
+
|
37
|
+
complaint = message['complaint']
|
38
|
+
recipients = complaint['complainedRecipients']
|
39
|
+
recipients.each do |recp|
|
40
|
+
email = recp['emailAddress']
|
41
|
+
extra_info = "complaintFeedbackType: #{complaint['complaintFeedbackType']}"
|
42
|
+
EmailResponse.create ( { email: email, response_type: 'complaint', extra_info: extra_info } )
|
43
|
+
end
|
44
|
+
|
45
|
+
render json: {}
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# def aws_message
|
51
|
+
# @aws_message ||= AWS::SNS::Message.new request.raw_post
|
52
|
+
# end
|
53
|
+
|
54
|
+
def email_response_params
|
55
|
+
params.require(:email_response).permit(:email, :extra_info, :response_type)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Weirdly, AWS double encodes the JSON.
|
59
|
+
def message
|
60
|
+
@message ||= JSON.parse JSON.parse(request.raw_post)['Message']
|
61
|
+
end
|
62
|
+
|
63
|
+
def type
|
64
|
+
message['notificationType']
|
65
|
+
end
|
66
|
+
|
67
|
+
def log_incoming_message
|
68
|
+
Rails.logger.info request.raw_post
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>AwsSesNewsletters</title>
|
5
|
+
<%= stylesheet_link_tag "aws_ses_newsletters/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "aws_ses_newsletters/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'aws_ses_newsletters/mail_builder'
|
2
|
+
|
3
|
+
module AwsSesNewsletters
|
4
|
+
# Inherit from this class to create a Newsletter and override *create_newsletter* & *get_recipients*
|
5
|
+
# It is a Sidekiq::Worker, so the method that will be executed is *perform*, which creates a AwsSesNewsletters::Newsletter
|
6
|
+
# and sends the newsletter to all defined recipients.
|
7
|
+
class NewslettersSender
|
8
|
+
include ::Sidekiq::Worker
|
9
|
+
attr_accessor :newsletter
|
10
|
+
|
11
|
+
SES = AWS::SES::Base.new(access_key_id: ENV['SES_ACCESS_KEY_ID'],
|
12
|
+
secret_access_key: ENV['SES_SECRET_ACCESS_KEY'])
|
13
|
+
|
14
|
+
# this method is the one that is executed when starting a sidekiq process
|
15
|
+
def perform
|
16
|
+
@newsletter = create_newsletter
|
17
|
+
send_emails
|
18
|
+
end
|
19
|
+
|
20
|
+
# Send a preview email
|
21
|
+
def preview_to(recipient)
|
22
|
+
@newsletter = build_newsletter
|
23
|
+
mail = build_mail
|
24
|
+
mail.to = recipient.email
|
25
|
+
replace_and_send_mail_safely(mail, recipient)
|
26
|
+
end
|
27
|
+
protected
|
28
|
+
|
29
|
+
# Iterate over recipients and sends emails
|
30
|
+
def send_emails
|
31
|
+
mail = build_mail
|
32
|
+
get_recipients do |recipient|
|
33
|
+
next if EmailResponse.exists?(email: recipient.email) # bounces & complaints
|
34
|
+
mail.to = recipient.email
|
35
|
+
replace_and_send_mail_safely(mail, recipient)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Override this method to create a AwsSesNewsletters::Newsletter
|
40
|
+
# ==== Example
|
41
|
+
# AwsSesNewsletter::Newsletter.create(from: 'you@example.com', subject: 'newsletter subject', html_body: '<p>Newsletter here</p>')
|
42
|
+
def create_newsletter
|
43
|
+
fail NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
# Override this method to build a AwsSesNewsletters::Newsletter to preview
|
47
|
+
# ==== Example
|
48
|
+
# AwsSesNewsletter::Newsletter.new(from: 'you@example.com', subject: 'newsletter subject', html_body: '<p>Newsletter here</p>')
|
49
|
+
def build_newsletter
|
50
|
+
fail NotImplementedError
|
51
|
+
end
|
52
|
+
|
53
|
+
# Override this method to get the recipients, yielding for every recipient you want to send an email to
|
54
|
+
# It is recommended to batch if there are many recipients
|
55
|
+
# ==== Example
|
56
|
+
# User.where(wants_newsletter: true).find_in_batches(batch_size: 100) do |group|
|
57
|
+
# group.each do |recipient|
|
58
|
+
# yield recipient
|
59
|
+
# end
|
60
|
+
# end
|
61
|
+
def get_recipients
|
62
|
+
fail NotImplementedError
|
63
|
+
end
|
64
|
+
|
65
|
+
# override this method if you want to inline images
|
66
|
+
# return a Hash where the key is the key used in the template and the value is the file
|
67
|
+
def get_images
|
68
|
+
{}
|
69
|
+
end
|
70
|
+
|
71
|
+
# Perform custom replacements and send the email without throwing any exception
|
72
|
+
def replace_and_send_mail_safely(mail, recipient)
|
73
|
+
html_body = mail.html_part.body.raw_source
|
74
|
+
do_custom_replacements_for(mail, recipient)
|
75
|
+
send_raw_email_safely(mail)
|
76
|
+
mail.html_part.body = html_body
|
77
|
+
end
|
78
|
+
|
79
|
+
# calls aws-ses *send_raw_email* with a +mail+
|
80
|
+
def send_raw_email_safely(mail)
|
81
|
+
begin
|
82
|
+
SES.send_raw_email(mail)
|
83
|
+
rescue StandardError => e
|
84
|
+
Rails.logger.info e.message
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Override this method to perform a replacement for a particular email
|
89
|
+
# Usually you will want to override the body
|
90
|
+
# ==== Example
|
91
|
+
# mail.html_part.body = mail.html_part.body.raw_source.gsub('recipient_email', recipient.email)
|
92
|
+
def do_custom_replacements_for(mail, recipient)
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
# Builds a Mail
|
98
|
+
def build_mail
|
99
|
+
AwsSesNewsletters::MailBuilder.new(
|
100
|
+
from: newsletter.from,
|
101
|
+
subject: newsletter.subject,
|
102
|
+
html_body: newsletter.html_body,
|
103
|
+
images: get_images,
|
104
|
+
).build
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'premailer'
|
2
|
+
|
3
|
+
module AwsSesNewsletters
|
4
|
+
# Helper that allows you to build html from erb templates, inlines css as needed in emails
|
5
|
+
class HtmlBuilder
|
6
|
+
include Rails.application.routes.url_helpers
|
7
|
+
include ActionView::Helpers
|
8
|
+
include ActionView::Rendering
|
9
|
+
|
10
|
+
attr_accessor :template_name
|
11
|
+
|
12
|
+
def initialize(template_name, instance_variables_hash = nil)
|
13
|
+
@template_name = template_name
|
14
|
+
instance_variables_hash.each { |name, value| instance_variable_set("@#{name}", value) } if instance_variables_hash.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
def build
|
18
|
+
template = File.read(template_name)
|
19
|
+
renderer = ERB.new(template)
|
20
|
+
html_string = renderer.result(get_binding)
|
21
|
+
inline_html_string = ::Premailer.new(html_string, warn_level: Premailer::Warnings::SAFE, with_html_string: true).to_inline_css
|
22
|
+
return inline_html_string.gsub(/\n/, "")
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_binding
|
26
|
+
binding()
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AwsSesNewsletters
|
2
|
+
# Helper to build a Mail
|
3
|
+
class MailBuilder
|
4
|
+
attr_accessor :from, :to, :subject, :html_body, :images
|
5
|
+
|
6
|
+
def initialize(from:, subject:, html_body:, images: [])
|
7
|
+
@from = from
|
8
|
+
@subject = subject
|
9
|
+
@html_body = html_body
|
10
|
+
@images = images
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
from = self.from
|
15
|
+
subject = self.subject
|
16
|
+
html_body = self.html_body
|
17
|
+
images = self.images
|
18
|
+
|
19
|
+
mail = Mail.new do
|
20
|
+
from from
|
21
|
+
subject subject
|
22
|
+
html = html_body
|
23
|
+
|
24
|
+
# attachments
|
25
|
+
images.each do |key, value|
|
26
|
+
attachments[key] = value
|
27
|
+
end
|
28
|
+
attachments.each do |attachment|
|
29
|
+
(html = html.sub(attachment.filename, "cid:#{attachment.cid}")) if (html =~ /#{attachment.filename}/)
|
30
|
+
end
|
31
|
+
|
32
|
+
html_part do
|
33
|
+
body html; content_type 'text/html; charset=UTF-8'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
mail.raise_delivery_errors = true
|
37
|
+
mail
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aws_ses_newsletters
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Federico Zuppa
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-04-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aws-ses
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sidekiq
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: premailer
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: factory_girl_rails
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: Framework that uses aws-ses to send newsletters
|
126
|
+
email:
|
127
|
+
- fzuppa@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- MIT-LICENSE
|
133
|
+
- README.rdoc
|
134
|
+
- Rakefile
|
135
|
+
- app/assets/javascripts/aws_ses_newsletters/application.js
|
136
|
+
- app/assets/stylesheets/aws_ses_newsletters/application.css
|
137
|
+
- app/controllers/aws_ses_newsletters/application_controller.rb
|
138
|
+
- app/controllers/aws_ses_newsletters/email_responses_controller.rb
|
139
|
+
- app/helpers/aws_ses_newsletters/application_helper.rb
|
140
|
+
- app/models/aws_ses_newsletters/email_response.rb
|
141
|
+
- app/models/aws_ses_newsletters/newsletter.rb
|
142
|
+
- app/views/layouts/aws_ses_newsletters/application.html.erb
|
143
|
+
- app/workers/aws_ses_newsletters/newsletters_sender.rb
|
144
|
+
- config/routes.rb
|
145
|
+
- db/migrate/20160410174449_create_aws_ses_newsletters_newsletters.rb
|
146
|
+
- db/migrate/20160411205706_create_aws_ses_newsletters_email_responses.rb
|
147
|
+
- lib/aws_ses_newsletters.rb
|
148
|
+
- lib/aws_ses_newsletters/engine.rb
|
149
|
+
- lib/aws_ses_newsletters/html_builder.rb
|
150
|
+
- lib/aws_ses_newsletters/mail_builder.rb
|
151
|
+
- lib/aws_ses_newsletters/version.rb
|
152
|
+
- lib/tasks/aws_ses_newsletters_tasks.rake
|
153
|
+
homepage: https://github.com/10pines/aws_ses_newsletters
|
154
|
+
licenses:
|
155
|
+
- MIT
|
156
|
+
metadata: {}
|
157
|
+
post_install_message:
|
158
|
+
rdoc_options: []
|
159
|
+
require_paths:
|
160
|
+
- lib
|
161
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
167
|
+
requirements:
|
168
|
+
- - ">="
|
169
|
+
- !ruby/object:Gem::Version
|
170
|
+
version: '0'
|
171
|
+
requirements: []
|
172
|
+
rubyforge_project:
|
173
|
+
rubygems_version: 2.4.6
|
174
|
+
signing_key:
|
175
|
+
specification_version: 4
|
176
|
+
summary: Easy newsletters with Amazon SES
|
177
|
+
test_files: []
|