ses_api-rails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +133 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/ses_api/rails/api.rb +115 -0
- data/lib/ses_api/rails/configuration.rb +26 -0
- data/lib/ses_api/rails/railtie.rb +10 -0
- data/lib/ses_api/rails/version.rb +5 -0
- data/lib/ses_api/rails.rb +17 -0
- data/ses_api-rails.gemspec +26 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 412077631ec736027d7d9b14e46fcfca42e2d193
|
4
|
+
data.tar.gz: 01081ff399c203622a4514cddf6089cca15c4c58
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fddfc7096b9b62780bded4527d1c57f291921a3e1ee63a5559a3e65c08bac04aa0beb00ea8acdf2ee4185001bf421c1abd15218f95194fac3086cb339d0d3409
|
7
|
+
data.tar.gz: a0c64ff863393372b9a736fd72682a6664ffec491806c56b0b30e9d95c807d207e6b9ae263a63c9f0d9f2836ef0ae88662ec58cc7550200c070194f36bcac043
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Chris Ickes
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
# SES API for Rails
|
2
|
+
Basic SES API integration with Rails specifically for transaction based emails - contact emails, user emails, etc.
|
3
|
+
|
4
|
+
## Install the SES API Rails gem
|
5
|
+
```
|
6
|
+
# Gemfile
|
7
|
+
gem 'ses_api-rails', git: 'https://github.com/cickes/ses_api-rails.git'
|
8
|
+
```
|
9
|
+
`bundle install`
|
10
|
+
|
11
|
+
## High Level Integration Details
|
12
|
+
1. Create an initializer file defining your AWS credentials as constants
|
13
|
+
```
|
14
|
+
# config/initializers/ses_api-rails.rb
|
15
|
+
SesApi::Rails.configure do |config|
|
16
|
+
config.secret_access_key = ENV['SECRET_ACCESS_KEY']
|
17
|
+
config.access_key_id = Figaro.env.access_key_id
|
18
|
+
config.aws_region = "us-east-1"
|
19
|
+
config.ses_endpoint = "email.us-east-1.amazonaws.com"
|
20
|
+
end
|
21
|
+
```
|
22
|
+
There are many ways to accomplish this. The above shows 3 different methods. Personally I recommend the [Figaro Gem](https://github.com/laserlemon/figaro).
|
23
|
+
|
24
|
+
2. Subclass the SesApi::Rails::Mailer class in your CustomMailer or in your ApplicationMailer
|
25
|
+
```
|
26
|
+
# app/mailers/custom_mailer.rb
|
27
|
+
class CustomMailer < SesApi::Rails::Mailer
|
28
|
+
...
|
29
|
+
def contact
|
30
|
+
mail to: "you@example.com", subject: "Via Ses"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
3. Instantiate the mailer where appropriate.
|
36
|
+
```
|
37
|
+
# app/controllers/contacts_controller.rb
|
38
|
+
def create
|
39
|
+
@contact = Contact.new(contact_params)
|
40
|
+
if @contact.valid?
|
41
|
+
CustomMailer.contact(@contact).deliver_now!
|
42
|
+
redirect_to contact_success_path, notice: "Thank you for your contact request."
|
43
|
+
else
|
44
|
+
render :new
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
## A Step By Step Example
|
50
|
+
1. (OPTIONAL) After the ses_api-rails gem is installed, add your Amazon AWS / SES credentials to environment variables.
|
51
|
+
NOTE: There are many ways to set environment variables. This example uses the Figaro gem.
|
52
|
+
```
|
53
|
+
# Gemfile
|
54
|
+
gem 'figaro'
|
55
|
+
```
|
56
|
+
```
|
57
|
+
`bundle install`
|
58
|
+
`figaro install`
|
59
|
+
```
|
60
|
+
```
|
61
|
+
# config/application.yml
|
62
|
+
SECRET_ACCESS_KEY: "secret_access_key"
|
63
|
+
AWS_ACCESS_KEY_ID: "aws_access_key_id"
|
64
|
+
AWS_REGION: "us-east-1"
|
65
|
+
SES_ENDPOINT: "email.us-east-1.amazonaws.com"
|
66
|
+
```
|
67
|
+
|
68
|
+
2. Create an initializer that assigns your AWS credentials to constants. There are multiple ways to accomplish this including simply hardcoding a string value. The example below uses Figaro environment variables.
|
69
|
+
```
|
70
|
+
# config/initializers/ses_api-rails.rb
|
71
|
+
SesApi::Rails.configure do |config|
|
72
|
+
config.secret_access_key = Figaro.env.secret_access_key
|
73
|
+
config.access_key_id = Figaro.env.access_key_id
|
74
|
+
config.aws_region = Figaro.env.aws_region
|
75
|
+
config.ses_endpoint = Figaro.env.ses_endpoint
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
3. Create a Mailer that subclasses the SesApi::Rails::Mailer
|
80
|
+
`rails g mailer ContactMailer`
|
81
|
+
If you are only sending email from the Amazon Ses Api, you can subclass the ApplicationMailer. Otherwise subclass the Mailer that will use the Ses delivery method.
|
82
|
+
* Using the Amazon Ses API as the only delivery method application-wide
|
83
|
+
```
|
84
|
+
# app/mailers/application_mailer.rb
|
85
|
+
class ApplicationMailer < SesApi::Rails::Mailer
|
86
|
+
default from: "from@example.com"
|
87
|
+
layout 'mailer'
|
88
|
+
end
|
89
|
+
```
|
90
|
+
```
|
91
|
+
# app/mailers/contact_mailer.rb
|
92
|
+
class ContactMailer < ApplicationMailer
|
93
|
+
...
|
94
|
+
def contact
|
95
|
+
mail to: "you@example.com", subject: "Via Ses"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
```
|
99
|
+
Create a mailer view(s)
|
100
|
+
```
|
101
|
+
# app/views/contact_mailer/contact.html.erb
|
102
|
+
<h1>Hello new contact</h1>
|
103
|
+
<p>Include instance variables as you like using @contact.attribute</p>
|
104
|
+
```
|
105
|
+
```
|
106
|
+
# app/views/contact_mailer/contact.text.erb
|
107
|
+
This is a text version
|
108
|
+
Hello new contact
|
109
|
+
```
|
110
|
+
|
111
|
+
4. Instantiate the mailer where appropriate.
|
112
|
+
NOTE: This assumes that you have a form, model, etc. & is not covered in the installation guide of this gem.
|
113
|
+
```
|
114
|
+
# app/controllers/contacts_controller.rb
|
115
|
+
...
|
116
|
+
def create
|
117
|
+
@contact = Contact.new(contact_params)
|
118
|
+
if @contact.valid?
|
119
|
+
ContactMailer.contact(@contact).deliver_now!
|
120
|
+
redirect_to contact_success_path, notice: "Thank you for your contact request."
|
121
|
+
else
|
122
|
+
render :new
|
123
|
+
end
|
124
|
+
end
|
125
|
+
...
|
126
|
+
```
|
127
|
+
|
128
|
+
## Troubleshooting
|
129
|
+
Is the library included? One way to do so is to autoload all library sub-directories:
|
130
|
+
`config.autoload_paths += Dir["#{config.root}/lib/**/"]`
|
131
|
+
|
132
|
+
Is the time correct? Recommended to use ntp or another time snychronization method
|
133
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "ses_api/rails"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
module SesApi
|
2
|
+
module Rails
|
3
|
+
|
4
|
+
# defines Mail::delivery_method
|
5
|
+
class Api < Mail::SMTP
|
6
|
+
# constants
|
7
|
+
ALGO = "AWS4-HMAC-SHA256"
|
8
|
+
SERVICE = "ses"
|
9
|
+
TERM_STR = "aws4_request"
|
10
|
+
|
11
|
+
class_attribute :conn, :mail
|
12
|
+
|
13
|
+
def initialize(values)
|
14
|
+
self.settings = {
|
15
|
+
}.merge!(values)
|
16
|
+
|
17
|
+
self.conn = Faraday.new(:url => "https://#{SesApi::Rails.configuration.ses_endpoint}") do |faraday|
|
18
|
+
faraday.request :url_encoded # form-encode POST params
|
19
|
+
faraday.response :logger # log requests to STDOUT
|
20
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def settings
|
25
|
+
{}
|
26
|
+
end
|
27
|
+
|
28
|
+
def deliver!(mail)
|
29
|
+
self.mail = mail
|
30
|
+
dt = create_datetime
|
31
|
+
credential_scope = create_credential_scope(dt)
|
32
|
+
|
33
|
+
response = conn.post do |req|
|
34
|
+
req.body = create_payload
|
35
|
+
hashed_payload = Digest::SHA256.hexdigest(req.body) #.downcase
|
36
|
+
headers = { :'X-Amz-Date' => dt, Host: "#{SesApi::Rails.configuration.ses_endpoint}", :'X-Amz-Content-Sha256' => hashed_payload }
|
37
|
+
headers.each do |addtl_header, value|
|
38
|
+
req.headers[addtl_header.to_s.camelize] = value
|
39
|
+
end
|
40
|
+
req.headers['Authorization'] = create_auth_header(dt, credential_scope, hashed_payload, headers)
|
41
|
+
end
|
42
|
+
|
43
|
+
raise SesApi::Rails::SesError if response.status != 200
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_datetime
|
47
|
+
# returns ISO8601 Basic format YYYYMMDD'T'HHMMSS'Z'
|
48
|
+
timestamp = Time.now.getutc
|
49
|
+
timestamp.strftime('%Y%m%dT%H%M%SZ')
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_credential_scope(request_datetime)
|
53
|
+
"#{request_datetime[0,8]}/#{SesApi::Rails.configuration.aws_region}/#{SERVICE}/#{TERM_STR}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_payload
|
57
|
+
to = mail.to.each_with_index.map { |email, i| "&Destination.ToAddresses.member.#{i+1}=#{CGI::escape(email)}"}.join
|
58
|
+
cc = mail.cc.each_with_index.map { |email, i| "&Destination.CCAddresses.member.#{i+1}=#{CGI::escape(email)}"}.join if mail.cc.present?
|
59
|
+
bcc = mail.bcc.each_with_index.map { |email, i| "&Destination.BCCAddresses.member.#{i+1}=#{CGI::escape(email)}"}.join if mail.bcc.present?
|
60
|
+
from = "&Source=#{CGI::escape(mail.from[0])}"
|
61
|
+
subject = "&Message.Subject.Data=#{CGI::escape(mail.subject)}"
|
62
|
+
|
63
|
+
if mail.body.raw_source.present?
|
64
|
+
body = "&Message.Body.Html.Data=#{CGI::escape(mail.body.raw_source)}&Message.Body.Html.Charset=UTF-8"
|
65
|
+
body << "&Message.Body.Text.Data=#{CGI::escape(mail.body.raw_source)}&Message.Body.Text.Charset=UTF-8"
|
66
|
+
else
|
67
|
+
body = "&Message.Body.Html.Data=#{CGI::escape(mail.html_part.body.raw_source)}&Message.Body.Html.Charset=UTF-8"
|
68
|
+
body << "&Message.Body.Text.Data=#{CGI::escape(mail.text_part.body.raw_source)}&Message.Body.Text.Charset=UTF-8"
|
69
|
+
end
|
70
|
+
|
71
|
+
payload = "AWSAccessKeyId=#{SesApi::Rails.configuration.access_key_id}&Action=SendEmail#{to}#{cc}#{bcc}#{body}#{subject}#{from}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_canonical_request(headers, hashed_payload, signed_headers)
|
75
|
+
http_request_method = "POST"
|
76
|
+
canonical_uri = "/"
|
77
|
+
canonical_query_str = ""
|
78
|
+
canonical_headers = headers.sort.map { |k,v| "#{k.downcase}:#{v.strip}\n"}.join
|
79
|
+
canonical_request = [http_request_method, canonical_uri, canonical_query_str, canonical_headers, signed_headers, hashed_payload].join("\n")
|
80
|
+
end
|
81
|
+
|
82
|
+
def create_auth_header(request_datetime, credential_scope, hashed_payload, headers)
|
83
|
+
signing_key = create_signing_key(request_datetime)
|
84
|
+
signed_headers = headers.sort.map { |k,v| "#{k.downcase}" }.join(";")
|
85
|
+
string_to_sign = create_str_to_sign(request_datetime, credential_scope, headers, hashed_payload, signed_headers)
|
86
|
+
signing_signature = create_signature(signing_key, string_to_sign)
|
87
|
+
return "#{ALGO} Credential=#{SesApi::Rails.configuration.access_key_id}/#{credential_scope}, SignedHeaders=#{signed_headers}, Signature=#{signing_signature}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_signing_key(request_datetime)
|
91
|
+
key_date = hmac("AWS4" + SesApi::Rails.configuration.secret_access_key, request_datetime[0,8])
|
92
|
+
key_region = hmac(key_date, SesApi::Rails.configuration.aws_region)
|
93
|
+
key_service = hmac(key_region, SERVICE)
|
94
|
+
key_credentials = hmac(key_service, TERM_STR)
|
95
|
+
end
|
96
|
+
|
97
|
+
def create_str_to_sign(request_datetime, credential_scope, headers, hashed_payload, signed_headers)
|
98
|
+
canonical_request = create_canonical_request(headers, hashed_payload, signed_headers)
|
99
|
+
return "#{ALGO}\n#{request_datetime}\n#{credential_scope}\n#{Digest::SHA256.hexdigest(canonical_request)}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def create_signature(signing_key, string_to_sign)
|
103
|
+
hexhmac(signing_key, string_to_sign)
|
104
|
+
end
|
105
|
+
|
106
|
+
def hmac(key, value)
|
107
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value)
|
108
|
+
end
|
109
|
+
|
110
|
+
def hexhmac(key, value)
|
111
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module SesApi
|
2
|
+
module Rails
|
3
|
+
class << self
|
4
|
+
attr_accessor :configuration
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.configure
|
8
|
+
self.configuration ||= Configuration.new
|
9
|
+
yield configuration
|
10
|
+
end
|
11
|
+
|
12
|
+
class Configuration
|
13
|
+
attr_accessor :aws_region
|
14
|
+
attr_accessor :ses_endpoint
|
15
|
+
attr_accessor :access_key_id
|
16
|
+
attr_accessor :secret_access_key
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@aws_region = "us-east-1"
|
20
|
+
@ses_endpoint = "email.us-east-1.amazonaws.com"
|
21
|
+
@access_key_id = nil
|
22
|
+
@secret_access_key = nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'mail'
|
2
|
+
require 'faraday'
|
3
|
+
require 'ses_api/rails/version'
|
4
|
+
require 'ses_api/rails/configuration'
|
5
|
+
require 'ses_api/rails/railtie'
|
6
|
+
|
7
|
+
module SesApi
|
8
|
+
module Rails
|
9
|
+
|
10
|
+
class Mailer < ActionMailer::Base
|
11
|
+
self.delivery_method = :ses
|
12
|
+
end
|
13
|
+
|
14
|
+
class SesError < StandardError; end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'ses_api/rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ses_api-rails"
|
8
|
+
spec.version = SesApi::Rails::VERSION
|
9
|
+
spec.authors = ["Chris Ickes"]
|
10
|
+
spec.email = ["chris@ickessoftware.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Basic Rails / Amazon SES API Integration.}
|
13
|
+
spec.description = %q{Rails / Amazon SES API integration for basic transactional email sending.}
|
14
|
+
spec.homepage = "https://github.com/cickes/ses_api-rails.git"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_dependency 'mail'
|
25
|
+
spec.add_dependency 'faraday'
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ses_api-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris Ickes
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-10-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mail
|
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: faraday
|
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
|
+
description: Rails / Amazon SES API integration for basic transactional email sending.
|
70
|
+
email:
|
71
|
+
- chris@ickessoftware.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/console
|
83
|
+
- bin/setup
|
84
|
+
- lib/ses_api/rails.rb
|
85
|
+
- lib/ses_api/rails/api.rb
|
86
|
+
- lib/ses_api/rails/configuration.rb
|
87
|
+
- lib/ses_api/rails/railtie.rb
|
88
|
+
- lib/ses_api/rails/version.rb
|
89
|
+
- ses_api-rails.gemspec
|
90
|
+
homepage: https://github.com/cickes/ses_api-rails.git
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubyforge_project:
|
110
|
+
rubygems_version: 2.4.5
|
111
|
+
signing_key:
|
112
|
+
specification_version: 4
|
113
|
+
summary: Basic Rails / Amazon SES API Integration.
|
114
|
+
test_files: []
|