t-mailer 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,15 @@
1
+ .bundle
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ # installed gem versions
14
+ Gemfile.lock
15
+ gemfiles/*.gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -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
@@ -0,0 +1,11 @@
1
+ appraise "mail-2.7" do
2
+ gem "mail", "~> 2.7.0"
3
+ end
4
+
5
+ appraise "mail-2.7.0" do
6
+ gem "mail", "2.7.0"
7
+ end
8
+
9
+ appraise "mail-2.6" do
10
+ gem "mail", "~> 2.6.0"
11
+ end
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in t-mailer.gemspec
6
+ gemspec
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.
@@ -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).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -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__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mail", "~> 2.6.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mail", "2.7.0"
6
+
7
+ gemspec path: "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "mail", "~> 2.7.0"
6
+
7
+ gemspec path: "../"
@@ -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
@@ -0,0 +1,11 @@
1
+ module T
2
+ module Mailer
3
+ class Railtie < Rails::Railtie
4
+ initializer "t-mailer.add_delivery_method" do
5
+ ActiveSupport.on_load :action_mailer do
6
+ ActionMailer::Base.add_delivery_method :t_mailer, T::Mailer::DeliveryMethod
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ module T
2
+ module Mailer
3
+ VERSION = "0.1.1".freeze
4
+ end
5
+ end
@@ -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: []