t-mailer 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rspec +3 -0
- data/.travis.yml +15 -0
- data/Appraisals +11 -0
- data/Gemfile +6 -0
- data/LICENSE +22 -0
- data/README.md +139 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/gemfiles/mail_2.6.gemfile +7 -0
- data/gemfiles/mail_2.7.0.gemfile +7 -0
- data/gemfiles/mail_2.7.gemfile +7 -0
- data/lib/t/mailer.rb +79 -0
- data/lib/t/mailer/api/aws_ses.rb +102 -0
- data/lib/t/mailer/api/spark_post.rb +76 -0
- data/lib/t/mailer/delivery_method.rb +48 -0
- data/lib/t/mailer/delivery_system/aws_ses.rb +57 -0
- data/lib/t/mailer/delivery_system/spark_post.rb +72 -0
- data/lib/t/mailer/error.rb +14 -0
- data/lib/t/mailer/helper.rb +84 -0
- data/lib/t/mailer/railtie.rb +11 -0
- data/lib/t/mailer/version.rb +5 -0
- data/t-mailer.gemspec +31 -0
- metadata +167 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4b2fc41c057851b98263832287904972730bbc50c8fbbccc6e8c0b809a9b60a8
|
4
|
+
data.tar.gz: 89d5028cbbc58761d441967ee73bc5c3ca76f0554e94722e7be27ba90d767e04
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 608cfd88506f40969518e79dec35354a55e37872ff608bde1dd333543923a00ddc085f33472686765f1ba494144f45feb345161dccca0922084e30cb80a83d43
|
7
|
+
data.tar.gz: 81db1670342b34322de45e50f6b57739f54b12329e189e3b7fce1d65a4aabc53aa55d2fb7e190b421d903de5501a1e394593c35c18fb49df0530a65591bb3a30
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
sudo: false
|
2
|
+
language: ruby
|
3
|
+
rvm:
|
4
|
+
- 2.3
|
5
|
+
- 2.4
|
6
|
+
- 2.5
|
7
|
+
- 2.6
|
8
|
+
before_install:
|
9
|
+
- gem update --system
|
10
|
+
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
11
|
+
- gem install bundler -v '< 2'
|
12
|
+
gemfile:
|
13
|
+
- gemfiles/mail_2.7.gemfile
|
14
|
+
- gemfiles/mail_2.7.0.gemfile
|
15
|
+
- gemfiles/mail_2.6.gemfile
|
data/Appraisals
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Norbert Szivós
|
4
|
+
Copyright (c) 2019 100Starlings Ltd.
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
8
|
+
in the Software without restriction, including without limitation the rights
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
11
|
+
furnished to do so, subject to the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
14
|
+
all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# T-mailer
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.com/100Starlings/t-mailer.svg?branch=master)](https://travis-ci.com/100Starlings/t-mailer)
|
4
|
+
|
5
|
+
**T-mailer** helps you to use **ActionMailer** with different providers' **API**. It sends emails using **raw/rfc822** message type. Which means it converts the mail object to string and sends it completely. There is no any intermediate changes, so what you send is what you get. It supports more APIs (see below) and you can decide which one would like to use. It allows you to send different emails with different APIs. It can help to move between providers, load balacing or cost management.
|
6
|
+
|
7
|
+
## Supported APIs
|
8
|
+
|
9
|
+
- Amazon AWS SES
|
10
|
+
- SparkPost
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem "t-mailer"
|
18
|
+
```
|
19
|
+
|
20
|
+
And then execute:
|
21
|
+
|
22
|
+
$ bundle
|
23
|
+
|
24
|
+
Or install it yourself as:
|
25
|
+
|
26
|
+
$ gem install t-mailer
|
27
|
+
|
28
|
+
### Dependency Installation
|
29
|
+
|
30
|
+
The T-mailer gem is needed other gem(s) to install, depends on which API would like to use.
|
31
|
+
|
32
|
+
#### Amazon AWS SES
|
33
|
+
|
34
|
+
Gemfile:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
gem "aws-sdk-ses"
|
38
|
+
```
|
39
|
+
|
40
|
+
Or
|
41
|
+
|
42
|
+
$ gem install aws-sdk-ses
|
43
|
+
|
44
|
+
#### SparkPost
|
45
|
+
|
46
|
+
Gemfile:
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
gem "simple_spark"
|
50
|
+
```
|
51
|
+
|
52
|
+
Or
|
53
|
+
|
54
|
+
$ gem install simple_spark
|
55
|
+
|
56
|
+
## Rails Setup
|
57
|
+
|
58
|
+
First, add the required gems to your Gemfile and run the `bundle` command to install it.
|
59
|
+
|
60
|
+
After that, set the delivery method in `config/environments/production.rb`.
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
config.action_mailer.delivery_method = :t_mailer
|
64
|
+
```
|
65
|
+
|
66
|
+
By default, the gem will look for your API keys in your environment:
|
67
|
+
|
68
|
+
#### Amazon AWS SES
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
AWS_ACCESS_KEY_ID
|
72
|
+
AWS_DEFAULT_REGION
|
73
|
+
AWS_SECRET_ACCESS_KEY
|
74
|
+
```
|
75
|
+
|
76
|
+
#### SparkPost
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
SPARKPOST_API_KEY
|
80
|
+
```
|
81
|
+
|
82
|
+
If you have above keys you don't need to configure anything else. If above environment variables are not exist or if you would like to override these settings you can identifying a different key in the initializer `config/initializers/t-mailer.rb`:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
T::Mailer.configure do |config|
|
86
|
+
config.aws_access_key_id = "aws access key id"
|
87
|
+
config.aws_default_region = "aws default region"
|
88
|
+
config.aws_secret_access_key = "aws secret access key"
|
89
|
+
config.sparkpost_api_key = "sparkpost api key"
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
## Usage
|
94
|
+
|
95
|
+
When calling the `deliver!` method on the mail object T-mailer returns with a modified mail object with the message ID which returned from the API.
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
message = MyMailer.message(data).deliver!
|
99
|
+
message.message_id # => 123456789
|
100
|
+
```
|
101
|
+
|
102
|
+
### API Specific Features
|
103
|
+
|
104
|
+
`delivery_system` is a specific and required option for T-mailer that the delivery method knows which API should use.
|
105
|
+
|
106
|
+
#### Amazon AWS SES
|
107
|
+
|
108
|
+
To use AWS SES the `delivery_system` should be `ses`.
|
109
|
+
|
110
|
+
Also you can add more AWS SES specific options like `tag: "test"` (required) and `configuration_set_name: "testname"`.
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
mail(from: "from@example.com", to: "to@example.com", delivery_system: "ses", tag: "test", configuration_set_name: "testname")
|
114
|
+
```
|
115
|
+
|
116
|
+
#### SparkPost
|
117
|
+
|
118
|
+
To use SparkPost the `delivery_system` should be `sparkpost`.
|
119
|
+
|
120
|
+
Also you can add more SparkPost specific options like `tag: "test"`, `options: { open_tracking: true, click_tracking: false, transactional: true }` and `metadata: { website: "testwebsite" }`.
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
mail(from: "from@example.com", to: "to@example.com", delivery_system: "sparkpost", tag: "test", options: { open_tracking: true, click_tracking: false, transactional: true }, metadata: { website: "testwebsite" })
|
124
|
+
```
|
125
|
+
|
126
|
+
## Development
|
127
|
+
|
128
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
129
|
+
|
130
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
131
|
+
|
132
|
+
## Contributing
|
133
|
+
|
134
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/100Starlings/t-mailer.
|
135
|
+
Please use the [issue tracker](https://github.com/100Starlings/t-mailer/issues) if you found any issues. If you would like to contribute to this project, please fork this repository and create a new pull request.
|
136
|
+
|
137
|
+
## License
|
138
|
+
|
139
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "t/mailer"
|
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(__FILE__)
|
data/bin/setup
ADDED
data/lib/t/mailer.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
require "t/mailer/helper"
|
2
|
+
|
3
|
+
require "t/mailer/delivery_method"
|
4
|
+
require "t/mailer/error"
|
5
|
+
require "t/mailer/version"
|
6
|
+
|
7
|
+
# If we use outside of Rails then do not load this code.
|
8
|
+
require "t/mailer/railtie" if defined?(Rails)
|
9
|
+
|
10
|
+
# If the required gem is not installed then do not load that API.
|
11
|
+
require "t/mailer/api/aws_ses" if Gem.loaded_specs.has_key?("aws-sdk-ses")
|
12
|
+
require "t/mailer/api/spark_post" if Gem.loaded_specs.has_key?("simple_spark")
|
13
|
+
|
14
|
+
require "t/mailer/delivery_system/aws_ses"
|
15
|
+
require "t/mailer/delivery_system/spark_post"
|
16
|
+
|
17
|
+
module T
|
18
|
+
module Mailer
|
19
|
+
class << self
|
20
|
+
attr_accessor :configuration
|
21
|
+
|
22
|
+
# Returns back with configuration or initialze it with default values.
|
23
|
+
def configuration
|
24
|
+
@configuration ||= Configuration.new
|
25
|
+
end
|
26
|
+
|
27
|
+
# Configure T::Mailer and set up required credentials if environment
|
28
|
+
# variables does not exist.
|
29
|
+
#
|
30
|
+
# @example using Rails config/initializers/t-mailer.rb
|
31
|
+
#
|
32
|
+
# T::Mailer.configure do |config|
|
33
|
+
# config.aws_access_key_id = "aws_access_key_id"
|
34
|
+
# config.aws_default_region = "aws_default_region"
|
35
|
+
# config.aws_secret_access_key = "aws_secret_access_key"
|
36
|
+
# config.sparkpost_api_key = "sparkpost_api_key"
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
def configure
|
40
|
+
yield(configuration)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Configuration
|
45
|
+
# Amazon AWS SES
|
46
|
+
attr_accessor :aws_access_key_id
|
47
|
+
attr_accessor :aws_default_region
|
48
|
+
attr_accessor :aws_secret_access_key
|
49
|
+
# SparkPost
|
50
|
+
attr_accessor :sparkpost_api_key
|
51
|
+
|
52
|
+
def initialize
|
53
|
+
%w(
|
54
|
+
AWS_ACCESS_KEY_ID
|
55
|
+
AWS_DEFAULT_REGION
|
56
|
+
AWS_SECRET_ACCESS_KEY
|
57
|
+
SPARKPOST_API_KEY
|
58
|
+
).each do |variable_name|
|
59
|
+
set_credential(variable_name)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
# If environment variables exist then it can pick up and set up those
|
66
|
+
# credentials automatically (no need config/initializers/t-mailer.rb file).
|
67
|
+
# If environment variable does not exist then it will leave it blank.
|
68
|
+
#
|
69
|
+
# @param [String] credential/API key variable name
|
70
|
+
def set_credential(variable_name)
|
71
|
+
if ENV[variable_name].nil?
|
72
|
+
public_send("#{variable_name.downcase}=", "")
|
73
|
+
else
|
74
|
+
public_send("#{variable_name.downcase}=", ENV[variable_name])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "aws-sdk-ses"
|
2
|
+
|
3
|
+
module T
|
4
|
+
module Mailer
|
5
|
+
module Api
|
6
|
+
class AwsSes
|
7
|
+
include Helper
|
8
|
+
|
9
|
+
attr_reader :settings
|
10
|
+
|
11
|
+
# Set settings and check if the required credentials are exist. If the
|
12
|
+
# credentials are missing then it will raise error.
|
13
|
+
#
|
14
|
+
# @param [Hash] with the credentials
|
15
|
+
def initialize(options)
|
16
|
+
@settings = options
|
17
|
+
|
18
|
+
check_settings(:aws_access_key_id, :aws_default_region,
|
19
|
+
:aws_secret_access_key)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a client which will connect to server via API
|
23
|
+
def client
|
24
|
+
credentials = Aws::Credentials.new(settings[:aws_access_key_id],
|
25
|
+
settings[:aws_secret_access_key])
|
26
|
+
region = settings[:aws_default_region]
|
27
|
+
|
28
|
+
Aws::SES::Client.new(credentials: credentials, region: region)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Composes an email message and immediately queues it for sending. When
|
32
|
+
# calling this operation, you may specify the message headers as well as
|
33
|
+
# the content. The `SendRawEmail` operation is particularly useful for
|
34
|
+
# sending multipart MIME emails (such as those that contain both a
|
35
|
+
# plain-text and an HTML version).
|
36
|
+
#
|
37
|
+
# @example Example: SendRawEmail
|
38
|
+
#
|
39
|
+
# # The following example sends an email with an attachment:
|
40
|
+
#
|
41
|
+
# resp = client.send_raw_email({
|
42
|
+
# destinations: [
|
43
|
+
# ],
|
44
|
+
# from_arn: "",
|
45
|
+
# raw_message: {
|
46
|
+
# data: "From: sender@example.com\\nTo: recipient@example.com\\n
|
47
|
+
# Subject: Test email (contains an attachment)\\n
|
48
|
+
# MIME-Version: 1.0\\nContent-type: Multipart/Mixed;
|
49
|
+
# boundary=\"NextPart\"\\n\\n--NextPart\\n
|
50
|
+
# Content-Type: text/plain\\n\\nThis is the message body.\\n\\n
|
51
|
+
# --NextPart\\n
|
52
|
+
# Content-Type: text/plain;\\n
|
53
|
+
# Content-Disposition: attachment; filename=\"attachment.txt\"
|
54
|
+
# \\n\\nThis is the text in the attachment.\\n\\n--NextPart--",
|
55
|
+
# },
|
56
|
+
# return_path_arn: "",
|
57
|
+
# source: "",
|
58
|
+
# source_arn: "",
|
59
|
+
# })
|
60
|
+
#
|
61
|
+
# resp.to_h outputs the following:
|
62
|
+
# {
|
63
|
+
# message_id: "EXAMPLEf3f73d99b-c63fb06f-d263-41f8-a0fb-d0dc67d56c07-000",
|
64
|
+
# }
|
65
|
+
#
|
66
|
+
# @example Request syntax with placeholder values
|
67
|
+
#
|
68
|
+
# resp = client.send_raw_email({
|
69
|
+
# source: "Address",
|
70
|
+
# destinations: ["Address"],
|
71
|
+
# raw_message: { # required
|
72
|
+
# data: "data", # required
|
73
|
+
# },
|
74
|
+
# from_arn: "AmazonResourceName",
|
75
|
+
# source_arn: "AmazonResourceName",
|
76
|
+
# return_path_arn: "AmazonResourceName",
|
77
|
+
# tags: [
|
78
|
+
# {
|
79
|
+
# name: "MessageTagName", # required
|
80
|
+
# value: "MessageTagValue", # required
|
81
|
+
# },
|
82
|
+
# ],
|
83
|
+
# configuration_set_name: "ConfigurationSetName",
|
84
|
+
# })
|
85
|
+
#
|
86
|
+
# @example Response structure
|
87
|
+
#
|
88
|
+
# resp.message_id #=> String
|
89
|
+
#
|
90
|
+
# @overload send_raw_email(params = {})
|
91
|
+
#
|
92
|
+
# @param [Hash] with the details of the email
|
93
|
+
#
|
94
|
+
# @return [Object]
|
95
|
+
# #<struct Aws::SES::Types::SendRawEmailResponse message_id="an_id">
|
96
|
+
def send_raw_email(params = {})
|
97
|
+
client.send_raw_email(params)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require "simple_spark"
|
2
|
+
|
3
|
+
module T
|
4
|
+
module Mailer
|
5
|
+
module Api
|
6
|
+
module SparkPost
|
7
|
+
class Transmissions
|
8
|
+
include Helper
|
9
|
+
|
10
|
+
attr_reader :settings
|
11
|
+
|
12
|
+
# Set settings and check if the required credential exists. If the
|
13
|
+
# credential is missing then it will raise error.
|
14
|
+
#
|
15
|
+
# @param [Hash] with the credentials
|
16
|
+
def initialize(options)
|
17
|
+
@settings = options
|
18
|
+
|
19
|
+
check_settings(:sparkpost_api_key)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Creates a client which will connect to server via API
|
23
|
+
def client
|
24
|
+
SimpleSpark::Client.new(api_key: settings[:sparkpost_api_key])
|
25
|
+
end
|
26
|
+
|
27
|
+
# The following attribute should be set in the content object when sending
|
28
|
+
# RFC822 content as the transmission's content:
|
29
|
+
#
|
30
|
+
# Request
|
31
|
+
#
|
32
|
+
# POST /api/v1/transmissions/{?num_rcpt_errors}
|
33
|
+
# {
|
34
|
+
# "description": "Christmas Campaign Email",
|
35
|
+
# "recipients": [
|
36
|
+
# {
|
37
|
+
# "address": {
|
38
|
+
# "email": "wilma@flintstone.com",
|
39
|
+
# "name": "Wilma Flintstone"
|
40
|
+
# },
|
41
|
+
# "substitution_data": {
|
42
|
+
# "first_name": "Wilma",
|
43
|
+
# "customer_type": "Platinum",
|
44
|
+
# "year": "Freshman"
|
45
|
+
# }
|
46
|
+
# }
|
47
|
+
# ],
|
48
|
+
# "content": {
|
49
|
+
# "email_rfc822": "Content-Type: text/plain\r\nTo: \"{{address.name}}\"
|
50
|
+
# <{{address.email}}>\r\n\r\n Hi {{first_name}} \nSave
|
51
|
+
# big this Christmas in your area {{place}}! \nClick
|
52
|
+
# http://www.mysite.com and get huge discount\n Hurry,
|
53
|
+
# this offer is only to {{customer_type}}\n {{sender}}\r\n"
|
54
|
+
# }
|
55
|
+
# }
|
56
|
+
# Response
|
57
|
+
#
|
58
|
+
# {
|
59
|
+
# "results": {
|
60
|
+
# "total_rejected_recipients": 0,
|
61
|
+
# "total_accepted_recipients": 2,
|
62
|
+
# "id": "11668787484950529"
|
63
|
+
# }
|
64
|
+
# }
|
65
|
+
#
|
66
|
+
# @param [Hash] with the details of the email
|
67
|
+
#
|
68
|
+
# @return [Hash] with the server response
|
69
|
+
def create(attrs)
|
70
|
+
client.transmissions.create(attrs)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module T
|
2
|
+
module Mailer
|
3
|
+
class DeliveryMethod
|
4
|
+
include Helper
|
5
|
+
|
6
|
+
attr_reader :settings
|
7
|
+
|
8
|
+
# Set settings with the required credentials for the API, but allow to
|
9
|
+
# call the delivery method without it. In that case it will set that up
|
10
|
+
# with the default. If credentials has been added then it will override
|
11
|
+
# the default credentials.
|
12
|
+
#
|
13
|
+
# @param [Hash] with the credentials
|
14
|
+
def initialize(options = {})
|
15
|
+
@settings = {
|
16
|
+
aws_access_key_id: T::Mailer.configuration.aws_access_key_id,
|
17
|
+
aws_default_region: T::Mailer.configuration.aws_default_region,
|
18
|
+
aws_secret_access_key: T::Mailer.configuration.aws_secret_access_key,
|
19
|
+
sparkpost_api_key: T::Mailer.configuration.sparkpost_api_key,
|
20
|
+
}.merge!(options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Check that the delivery system is provided. If delivery system is
|
24
|
+
# missing it will raise error. If delivery system was provided then it
|
25
|
+
# will call the given delivery system with the message. If the provided
|
26
|
+
# delivery system does not exist the it will raise error.
|
27
|
+
#
|
28
|
+
# @param [Mail::Message] message what we would like to send
|
29
|
+
def deliver!(message)
|
30
|
+
delivery_system = get_value_from(message["delivery_system"])
|
31
|
+
|
32
|
+
if delivery_system.nil?
|
33
|
+
fail Error::WrongDeliverySystem, "Delivery system is missing."
|
34
|
+
end
|
35
|
+
|
36
|
+
case delivery_system
|
37
|
+
when "ses"
|
38
|
+
DeliverySystem::AwsSes.new(settings).deliver(message)
|
39
|
+
when "sparkpost"
|
40
|
+
DeliverySystem::SparkPost.new(settings).deliver(message)
|
41
|
+
else
|
42
|
+
fail Error::WrongDeliverySystem,
|
43
|
+
"The given delivery system is not supported."
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module T
|
2
|
+
module Mailer
|
3
|
+
module DeliverySystem
|
4
|
+
class AwsSes
|
5
|
+
include Helper
|
6
|
+
|
7
|
+
attr_reader :settings
|
8
|
+
|
9
|
+
# Set settings with the required credentials for the API, but allow to
|
10
|
+
# call this delivery system without it.
|
11
|
+
#
|
12
|
+
# @param [Hash] with the credentials
|
13
|
+
def initialize(options = {})
|
14
|
+
@settings = options
|
15
|
+
end
|
16
|
+
|
17
|
+
# Check that the API is loaded. If API is missing it will raise error.
|
18
|
+
# If API exists then it will call the API with the generated options
|
19
|
+
# from the given mail message.
|
20
|
+
#
|
21
|
+
# @param [Mail::Message] message what we would like to send
|
22
|
+
#
|
23
|
+
# @return [Mail::Message] message with the changed message_id
|
24
|
+
def deliver(message)
|
25
|
+
check_api_defined("Api::AwsSes")
|
26
|
+
|
27
|
+
options = generate_options(message)
|
28
|
+
|
29
|
+
response = Api::AwsSes.new(settings).send_raw_email(options)
|
30
|
+
message.message_id = response && response.message_id
|
31
|
+
|
32
|
+
message
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generate the required hash what it will send via API.
|
36
|
+
#
|
37
|
+
# @param [Mail::Message] message what we would like to send
|
38
|
+
#
|
39
|
+
# @return [Hash] options for the API
|
40
|
+
def generate_options(message)
|
41
|
+
{
|
42
|
+
raw_message: {
|
43
|
+
data: message.to_s,
|
44
|
+
},
|
45
|
+
tags: [
|
46
|
+
{
|
47
|
+
name: message.delivery_handler.to_s,
|
48
|
+
value: get_value_from(message["tag"]),
|
49
|
+
},
|
50
|
+
],
|
51
|
+
configuration_set_name: get_value_from(message["configuration_set_name"]),
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module T
|
2
|
+
module Mailer
|
3
|
+
module DeliverySystem
|
4
|
+
class SparkPost
|
5
|
+
include Helper
|
6
|
+
|
7
|
+
attr_reader :settings
|
8
|
+
|
9
|
+
# Set settings with the required credentials for the API, but allow to
|
10
|
+
# call this delivery system without it.
|
11
|
+
#
|
12
|
+
# @param [Hash] with the credentials
|
13
|
+
def initialize(options = {})
|
14
|
+
@settings = options
|
15
|
+
end
|
16
|
+
|
17
|
+
# Check that the API is loaded. If API is missing it will raise error.
|
18
|
+
# If API exists then it will call the API with the generated options
|
19
|
+
# from the given mail message.
|
20
|
+
#
|
21
|
+
# @param [Mail::Message] message what we would like to send
|
22
|
+
#
|
23
|
+
# @return [Mail::Message] message with the changed message_id
|
24
|
+
def deliver(message)
|
25
|
+
check_api_defined("Api::SparkPost::Transmissions")
|
26
|
+
|
27
|
+
options = generate_options(message)
|
28
|
+
|
29
|
+
response = Api::SparkPost::Transmissions.new(settings).create(options)
|
30
|
+
message.message_id = response && response.dig("id")
|
31
|
+
|
32
|
+
message
|
33
|
+
end
|
34
|
+
|
35
|
+
# Generate the required hash what it will send via API.
|
36
|
+
#
|
37
|
+
# @param [Mail::Message] message what we would like to send
|
38
|
+
#
|
39
|
+
# @return [Hash] options for the API
|
40
|
+
def generate_options(message)
|
41
|
+
{
|
42
|
+
options: get_value_from(message["options"]),
|
43
|
+
campaign_id: get_value_from(message["tag"]),
|
44
|
+
content: {
|
45
|
+
email_rfc822: message.to_s,
|
46
|
+
},
|
47
|
+
metadata: get_value_from(message["metadata"]),
|
48
|
+
recipients: generate_recipients(message),
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Generate recipients.
|
53
|
+
#
|
54
|
+
# @param [Mail::Message] message what we would like to send
|
55
|
+
#
|
56
|
+
# @return [Array] with the recipients and tags
|
57
|
+
def generate_recipients(message)
|
58
|
+
message.to.map do |to|
|
59
|
+
{
|
60
|
+
address: {
|
61
|
+
email: to,
|
62
|
+
},
|
63
|
+
tags: [
|
64
|
+
get_value_from(message["tag"]),
|
65
|
+
],
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module T
|
2
|
+
module Mailer
|
3
|
+
class Error < StandardError
|
4
|
+
# Specific error class for errors if the given delivery system is not in the list
|
5
|
+
class WrongDeliverySystem < Error; end
|
6
|
+
|
7
|
+
# Specific error class for errors if the delivery system's API gem is not installed
|
8
|
+
class DeliverySystemNotDefined < Error; end
|
9
|
+
|
10
|
+
# Specific error class when API is not getting required credentials
|
11
|
+
class MissingCredentials < Error; end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module T
|
2
|
+
module Mailer
|
3
|
+
module Helper
|
4
|
+
# Check gem is installed or not. If not it will raise error.
|
5
|
+
#
|
6
|
+
# @param [String] a API's class name
|
7
|
+
def check_api_defined(klass)
|
8
|
+
unless T::Mailer.const_defined?(klass)
|
9
|
+
fail Error::DeliverySystemNotDefined,
|
10
|
+
"Please install #{using_gem(klass)} gem."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Check API credentials were given.
|
15
|
+
# If one is missing or empty it will raise error.
|
16
|
+
#
|
17
|
+
# @param [List] comma separated values/symbols
|
18
|
+
def check_settings(*required_values)
|
19
|
+
has_all_settings =
|
20
|
+
settings.values_at(*required_values).all? do |setting|
|
21
|
+
setting && !setting.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
unless settings.is_a?(Hash) && has_all_settings
|
25
|
+
fail Error::MissingCredentials,
|
26
|
+
"Please provide all credential values. Required: #{required_values}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Check the version of a gem.
|
31
|
+
#
|
32
|
+
# @param [String] the name of the gem
|
33
|
+
# @param [String] the satisfied version of the gem
|
34
|
+
#
|
35
|
+
# @return [Boolean] true/false
|
36
|
+
def check_version_of(gem_name, version)
|
37
|
+
requirement = Gem::Requirement.new(version)
|
38
|
+
current_version = Gem.loaded_specs[gem_name].version
|
39
|
+
|
40
|
+
requirement.satisfied_by?(current_version)
|
41
|
+
end
|
42
|
+
|
43
|
+
# How to gets the uparsed value of the mail message fields.
|
44
|
+
#
|
45
|
+
# @return [String] version dependent method call
|
46
|
+
def field_value
|
47
|
+
if check_version_of("mail", "> 2.7.0")
|
48
|
+
%w(unparsed_value)
|
49
|
+
elsif check_version_of("mail", "= 2.7.0")
|
50
|
+
%w(instance_variable_get @unparsed_value)
|
51
|
+
elsif check_version_of("mail", "< 2.7.0")
|
52
|
+
%w(instance_variable_get @value)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Gets uparsed value of the mail message fields.
|
57
|
+
#
|
58
|
+
# @param [Mail::Field]
|
59
|
+
#
|
60
|
+
# @return [String/Hash] with the field unparsed value
|
61
|
+
def get_value_from(message_field)
|
62
|
+
return if message_field.nil?
|
63
|
+
|
64
|
+
message_field.public_send(*field_value)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Which gem using an API class.
|
68
|
+
#
|
69
|
+
# @param [String] class name
|
70
|
+
#
|
71
|
+
# @retrun [String] the gem name which should use
|
72
|
+
def using_gem(klass)
|
73
|
+
case klass
|
74
|
+
when "Api::AwsSes"
|
75
|
+
"aws-sdk-ses"
|
76
|
+
when "Api::SparkPost::Transmissions"
|
77
|
+
"simple_spark"
|
78
|
+
else
|
79
|
+
"unknown"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
data/t-mailer.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "t/mailer/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "t-mailer"
|
8
|
+
spec.version = T::Mailer::VERSION
|
9
|
+
spec.authors = ["Norbert Szivós"]
|
10
|
+
spec.email = ["sysqa@yahoo.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{T-mailer from the age of dinosaurs}
|
13
|
+
spec.description = %q{Delivery Method for Rails ActionMailer to send emails via API using raw/rfc822 message type}
|
14
|
+
spec.homepage = "https://github.com/100Starlings/t-mailer"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "appraisal"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
+
spec.add_development_dependency "webmock", "~> 3.0"
|
28
|
+
spec.add_development_dependency "mail", "~> 2.5"
|
29
|
+
spec.add_development_dependency "aws-sdk-ses", "~> 1.0"
|
30
|
+
spec.add_development_dependency "simple_spark", "~> 1.0"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: t-mailer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Norbert Szivós
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-07-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: appraisal
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
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: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mail
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.5'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.5'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: aws-sdk-ses
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simple_spark
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.0'
|
111
|
+
description: Delivery Method for Rails ActionMailer to send emails via API using raw/rfc822
|
112
|
+
message type
|
113
|
+
email:
|
114
|
+
- sysqa@yahoo.com
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- ".rspec"
|
121
|
+
- ".travis.yml"
|
122
|
+
- Appraisals
|
123
|
+
- Gemfile
|
124
|
+
- LICENSE
|
125
|
+
- README.md
|
126
|
+
- Rakefile
|
127
|
+
- bin/console
|
128
|
+
- bin/setup
|
129
|
+
- gemfiles/mail_2.6.gemfile
|
130
|
+
- gemfiles/mail_2.7.0.gemfile
|
131
|
+
- gemfiles/mail_2.7.gemfile
|
132
|
+
- lib/t/mailer.rb
|
133
|
+
- lib/t/mailer/api/aws_ses.rb
|
134
|
+
- lib/t/mailer/api/spark_post.rb
|
135
|
+
- lib/t/mailer/delivery_method.rb
|
136
|
+
- lib/t/mailer/delivery_system/aws_ses.rb
|
137
|
+
- lib/t/mailer/delivery_system/spark_post.rb
|
138
|
+
- lib/t/mailer/error.rb
|
139
|
+
- lib/t/mailer/helper.rb
|
140
|
+
- lib/t/mailer/railtie.rb
|
141
|
+
- lib/t/mailer/version.rb
|
142
|
+
- t-mailer.gemspec
|
143
|
+
homepage: https://github.com/100Starlings/t-mailer
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata: {}
|
147
|
+
post_install_message:
|
148
|
+
rdoc_options: []
|
149
|
+
require_paths:
|
150
|
+
- lib
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
requirements: []
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 2.7.6
|
164
|
+
signing_key:
|
165
|
+
specification_version: 4
|
166
|
+
summary: T-mailer from the age of dinosaurs
|
167
|
+
test_files: []
|