action_mailer_kafka 0.1.0

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.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +158 -0
  3. data/.gitignore +18 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +64 -0
  6. data/Appraisals +21 -0
  7. data/CHANGELOG.md +6 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.md +23 -0
  10. data/README.md +138 -0
  11. data/Rakefile +6 -0
  12. data/action_mailer_kafka.gemspec +52 -0
  13. data/bin/console +14 -0
  14. data/bin/setup +8 -0
  15. data/example/.gitignore +21 -0
  16. data/example/Gemfile +39 -0
  17. data/example/README.rdoc +10 -0
  18. data/example/Rakefile +6 -0
  19. data/example/app/assets/images/.keep +0 -0
  20. data/example/app/assets/javascripts/application.js +16 -0
  21. data/example/app/assets/javascripts/users.js.coffee +3 -0
  22. data/example/app/assets/stylesheets/application.css +15 -0
  23. data/example/app/assets/stylesheets/scaffolds.css.scss +69 -0
  24. data/example/app/assets/stylesheets/users.css.scss +3 -0
  25. data/example/app/controllers/application_controller.rb +5 -0
  26. data/example/app/controllers/concerns/.keep +0 -0
  27. data/example/app/controllers/users_controller.rb +82 -0
  28. data/example/app/helpers/application_helper.rb +2 -0
  29. data/example/app/helpers/users_helper.rb +2 -0
  30. data/example/app/jobs/send_email_job.rb +8 -0
  31. data/example/app/mailers/.keep +0 -0
  32. data/example/app/mailers/example_mailer.rb +6 -0
  33. data/example/app/models/.keep +0 -0
  34. data/example/app/models/concerns/.keep +0 -0
  35. data/example/app/models/user.rb +2 -0
  36. data/example/app/views/example_mailer/sample_email.html.erb +398 -0
  37. data/example/app/views/example_mailer/sample_email.text.erb +2 -0
  38. data/example/app/views/layouts/application.html.erb +14 -0
  39. data/example/app/views/users/_form.html.erb +25 -0
  40. data/example/app/views/users/edit.html.erb +6 -0
  41. data/example/app/views/users/index.html.erb +27 -0
  42. data/example/app/views/users/index.json.jbuilder +4 -0
  43. data/example/app/views/users/new.html.erb +5 -0
  44. data/example/app/views/users/show.html.erb +14 -0
  45. data/example/app/views/users/show.json.jbuilder +1 -0
  46. data/example/config/application.rb +23 -0
  47. data/example/config/boot.rb +4 -0
  48. data/example/config/database.yml +11 -0
  49. data/example/config/environment.rb +5 -0
  50. data/example/config/environments/development.rb +43 -0
  51. data/example/config/environments/production.rb +105 -0
  52. data/example/config/environments/test.rb +39 -0
  53. data/example/config/initializers/backtrace_silencers.rb +7 -0
  54. data/example/config/initializers/cookies_serializer.rb +3 -0
  55. data/example/config/initializers/filter_parameter_logging.rb +4 -0
  56. data/example/config/initializers/inflections.rb +16 -0
  57. data/example/config/initializers/mime_types.rb +4 -0
  58. data/example/config/initializers/session_store.rb +3 -0
  59. data/example/config/initializers/wrap_parameters.rb +14 -0
  60. data/example/config/locales/en.yml +23 -0
  61. data/example/config/routes.rb +4 -0
  62. data/example/config/secrets.yml +22 -0
  63. data/example/config.ru +4 -0
  64. data/example/db/migrate/20141111080045_create_users.rb +10 -0
  65. data/example/db/migrate/20141115060216_create_delayed_jobs.rb +22 -0
  66. data/example/db/schema.rb +40 -0
  67. data/example/db/seeds.rb +7 -0
  68. data/example/public/404.html +67 -0
  69. data/example/public/422.html +67 -0
  70. data/example/public/500.html +66 -0
  71. data/example/public/favicon.ico +0 -0
  72. data/example/public/robots.txt +5 -0
  73. data/example/vendor/assets/javascripts/.keep +0 -0
  74. data/example/vendor/assets/stylesheets/.keep +0 -0
  75. data/gemfiles/.bundle/config +2 -0
  76. data/gemfiles/mail_2_5.gemfile +7 -0
  77. data/gemfiles/mail_2_6.gemfile +7 -0
  78. data/gemfiles/mail_2_7.gemfile +7 -0
  79. data/gemfiles/rails_4.gemfile +7 -0
  80. data/gemfiles/rails_5.gemfile +7 -0
  81. data/lib/action_mailer_kafka/delivery_method.rb +139 -0
  82. data/lib/action_mailer_kafka/error.rb +22 -0
  83. data/lib/action_mailer_kafka/railtie.rb +7 -0
  84. data/lib/action_mailer_kafka/version.rb +3 -0
  85. data/lib/action_mailer_kafka.rb +10 -0
  86. data/logo.png +0 -0
  87. metadata +328 -0
data/Rakefile ADDED
@@ -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,52 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'action_mailer_kafka/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'action_mailer_kafka'
7
+ spec.version = ActionMailerKafka::VERSION
8
+ spec.authors = ['Luong Vo']
9
+ spec.email = ['vo.tran.thanh.luong@gmail.com']
10
+ spec.license = 'MIT'
11
+ spec.summary = 'Custom action mailer to send mails to Kafka message queue.'
12
+ spec.description = 'This gem defines a way for Rails service or other backends to \
13
+ define a mailer that sends email to our employemt hero mail service.'
14
+ spec.homepage = 'https://github.com/luong-komorebi/action-mailer-kafka/'
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ if spec.respond_to?(:metadata)
19
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
20
+
21
+ spec.metadata['homepage_uri'] = spec.homepage
22
+ # spec.metadata['source_code_uri'] = "TODO: Put your gem's public repo URL here."
23
+ # spec.metadata['changelog_uri'] = "TODO: Put your gem's CHANGELOG.md URL here."
24
+ else
25
+ raise 'RubyGems 2.0 or newer is required to protect against ' \
26
+ 'public gem pushes.'
27
+ end
28
+
29
+ # Specify which files should be added to the gem when it is released.
30
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
31
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
32
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
33
+ end
34
+ spec.bindir = 'exe'
35
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ['lib']
37
+
38
+ spec.add_dependency 'mail'
39
+ spec.add_dependency 'ruby-kafka', '~> 0.7.6'
40
+ spec.add_development_dependency 'appraisal'
41
+ spec.add_development_dependency 'bundler'
42
+ spec.add_development_dependency 'byebug'
43
+ spec.add_development_dependency 'faraday'
44
+ spec.add_development_dependency 'rails'
45
+ spec.add_development_dependency 'rake'
46
+ spec.add_development_dependency 'rspec'
47
+ spec.add_development_dependency 'rspec-json_expectations'
48
+ spec.add_development_dependency 'rubocop'
49
+ spec.add_development_dependency 'rubocop-rspec'
50
+ spec.add_development_dependency 'rubycritic'
51
+ spec.add_development_dependency 'simplecov'
52
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "action_mailer_kafka"
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
@@ -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,21 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+ /db/*.sqlite3-journal
13
+
14
+ # Ignore all logfiles and tempfiles.
15
+ /log/*.log
16
+ /tmp
17
+
18
+ # Ignore application configuration
19
+ /config/application.yml
20
+
21
+ /Gemfile.lock
data/example/Gemfile ADDED
@@ -0,0 +1,39 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'byebug'
4
+ # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
5
+ gem 'rails'
6
+ gem 'pg'
7
+ # Use SCSS for stylesheets
8
+ # gem 'sass-rails', '~> 4.0.3'
9
+ # Use Uglifier as compressor for JavaScript assets
10
+ gem 'uglifier'
11
+ # Use CoffeeScript for .js.coffee assets and view
12
+ gem 'coffee-rails'
13
+ # See https://github.com/sstephenson/execjs#readme for more supported runtimes
14
+ # gem 'therubyracer', platforms: :ruby
15
+
16
+ # Use jquery as the JavaScript library
17
+ gem 'jquery-rails'
18
+ # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
19
+ gem 'turbolinks'
20
+ # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
21
+ gem 'jbuilder'
22
+
23
+ # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
24
+ gem 'spring', group: :development
25
+
26
+ # Use ActiveModel has_secure_password
27
+ # gem 'bcrypt', '~> 3.1.7'
28
+
29
+ # Use unicorn as the app server
30
+ # gem 'unicorn'
31
+
32
+ # Use Capistrano for deployment
33
+ # gem 'capistrano-rails', group: :development
34
+
35
+ # Use debugger
36
+ # gem 'debugger', group: [:development, :test]
37
+ gem "figaro"
38
+ gem 'delayed_job_active_record'
39
+ gem 'action_mailer_kafka', path: '../'
@@ -0,0 +1,10 @@
1
+ == README
2
+
3
+ Simple application for sending mails from rails application.
4
+
5
+ ```sh
6
+ bundle exec rake db:create
7
+ bundle exec rake db:migrate
8
+ bundle exec rackup
9
+ ```
10
+
data/example/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
File without changes
@@ -0,0 +1,16 @@
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/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require turbolinks
16
+ //= require_tree .
@@ -0,0 +1,3 @@
1
+ # Place all the behaviors and hooks related to the matching controller here.
2
+ # All this logic will automatically be available in application.js.
3
+ # You can use CoffeeScript in this file: http://coffeescript.org/
@@ -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,69 @@
1
+ body {
2
+ background-color: #fff;
3
+ color: #333;
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ p, ol, ul, td {
10
+ font-family: verdana, arial, helvetica, sans-serif;
11
+ font-size: 13px;
12
+ line-height: 18px;
13
+ }
14
+
15
+ pre {
16
+ background-color: #eee;
17
+ padding: 10px;
18
+ font-size: 11px;
19
+ }
20
+
21
+ a {
22
+ color: #000;
23
+ &:visited {
24
+ color: #666;
25
+ }
26
+ &:hover {
27
+ color: #fff;
28
+ background-color: #000;
29
+ }
30
+ }
31
+
32
+ div {
33
+ &.field, &.actions {
34
+ margin-bottom: 10px;
35
+ }
36
+ }
37
+
38
+ #notice {
39
+ color: green;
40
+ }
41
+
42
+ .field_with_errors {
43
+ padding: 2px;
44
+ background-color: red;
45
+ display: table;
46
+ }
47
+
48
+ #error_explanation {
49
+ width: 450px;
50
+ border: 2px solid red;
51
+ padding: 7px;
52
+ padding-bottom: 0;
53
+ margin-bottom: 20px;
54
+ background-color: #f0f0f0;
55
+ h2 {
56
+ text-align: left;
57
+ font-weight: bold;
58
+ padding: 5px 5px 5px 15px;
59
+ font-size: 12px;
60
+ margin: -7px;
61
+ margin-bottom: 0px;
62
+ background-color: #c00;
63
+ color: #fff;
64
+ }
65
+ ul li {
66
+ font-size: 12px;
67
+ list-style: square;
68
+ }
69
+ }
@@ -0,0 +1,3 @@
1
+ // Place all the styles related to the users controller here.
2
+ // They will automatically be included in application.css.
3
+ // You can use Sass (SCSS) here: http://sass-lang.com/
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
File without changes
@@ -0,0 +1,82 @@
1
+ class UsersController < ApplicationController
2
+ before_action :set_user, only: [:show, :edit, :update, :destroy]
3
+
4
+ # GET /users
5
+ # GET /users.json
6
+ def index
7
+ @users = User.all
8
+ end
9
+
10
+ # GET /users/1
11
+ # GET /users/1.json
12
+ def show
13
+ end
14
+
15
+ # GET /users/new
16
+ def new
17
+ @user = User.new
18
+ end
19
+
20
+ # GET /users/1/edit
21
+ def edit
22
+ end
23
+
24
+ # POST /users
25
+ # POST /users.json
26
+ def create
27
+ @user = User.new(user_params)
28
+
29
+ respond_to do |format|
30
+ if @user.save
31
+
32
+ # Sends email to user when user is created.
33
+ # To send emails without Action Job
34
+ ExampleMailer.sample_email(@user).deliver_now
35
+
36
+ # To send emails using Action Jobs
37
+ # SendEmailJob.set(wait: 10.seconds).perform_later(@user)
38
+
39
+ format.html { redirect_to @user, notice: 'User was successfully created.' }
40
+ format.json { render :show, status: :created, location: @user }
41
+ else
42
+ format.html { render :new }
43
+ format.json { render json: @user.errors, status: :unprocessable_entity }
44
+ end
45
+ end
46
+ end
47
+
48
+ # PATCH/PUT /users/1
49
+ # PATCH/PUT /users/1.json
50
+ def update
51
+ respond_to do |format|
52
+ if @user.update(user_params)
53
+ format.html { redirect_to @user, notice: 'User was successfully updated.' }
54
+ format.json { render :show, status: :ok, location: @user }
55
+ else
56
+ format.html { render :edit }
57
+ format.json { render json: @user.errors, status: :unprocessable_entity }
58
+ end
59
+ end
60
+ end
61
+
62
+ # DELETE /users/1
63
+ # DELETE /users/1.json
64
+ def destroy
65
+ @user.destroy
66
+ respond_to do |format|
67
+ format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
68
+ format.json { head :no_content }
69
+ end
70
+ end
71
+
72
+ private
73
+ # Use callbacks to share common setup or constraints between actions.
74
+ def set_user
75
+ @user = User.find(params[:id])
76
+ end
77
+
78
+ # Never trust parameters from the scary internet, only allow the white list through.
79
+ def user_params
80
+ params.require(:user).permit(:name, :email)
81
+ end
82
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module UsersHelper
2
+ end
@@ -0,0 +1,8 @@
1
+ class SendEmailJob < ActiveJob::Base
2
+ queue_as :default
3
+
4
+ def perform(user)
5
+ @user = user
6
+ ExampleMailer.sample_email(@user).deliver_now
7
+ end
8
+ end
File without changes
@@ -0,0 +1,6 @@
1
+ class ExampleMailer < ActionMailer::Base
2
+ def sample_email(user)
3
+ @user = user
4
+ mail(to: @user.email, subject: 'Sample Email', user: @user)
5
+ end
6
+ end
File without changes
File without changes
@@ -0,0 +1,2 @@
1
+ class User < ActiveRecord::Base
2
+ end
@@ -0,0 +1,398 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width" />
5
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
6
+ <title>Simple Transactional Email</title>
7
+ <style>
8
+ /* -------------------------------------
9
+ GLOBAL RESETS
10
+ ------------------------------------- */
11
+
12
+ /*All the styling goes here*/
13
+
14
+ img {
15
+ border: none;
16
+ -ms-interpolation-mode: bicubic;
17
+ max-width: 100%;
18
+ }
19
+
20
+ body {
21
+ background-color: #f6f6f6;
22
+ font-family: sans-serif;
23
+ -webkit-font-smoothing: antialiased;
24
+ font-size: 14px;
25
+ line-height: 1.4;
26
+ margin: 0;
27
+ padding: 0;
28
+ -ms-text-size-adjust: 100%;
29
+ -webkit-text-size-adjust: 100%;
30
+ }
31
+
32
+ table {
33
+ border-collapse: separate;
34
+ mso-table-lspace: 0pt;
35
+ mso-table-rspace: 0pt;
36
+ width: 100%; }
37
+ table td {
38
+ font-family: sans-serif;
39
+ font-size: 14px;
40
+ vertical-align: top;
41
+ }
42
+
43
+ /* -------------------------------------
44
+ BODY & CONTAINER
45
+ ------------------------------------- */
46
+
47
+ .body {
48
+ background-color: #f6f6f6;
49
+ width: 100%;
50
+ }
51
+
52
+ /* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
53
+ .container {
54
+ display: block;
55
+ margin: 0 auto !important;
56
+ /* makes it centered */
57
+ max-width: 580px;
58
+ padding: 10px;
59
+ width: 580px;
60
+ }
61
+
62
+ /* This should also be a block element, so that it will fill 100% of the .container */
63
+ .content {
64
+ box-sizing: border-box;
65
+ display: block;
66
+ margin: 0 auto;
67
+ max-width: 580px;
68
+ padding: 10px;
69
+ }
70
+
71
+ /* -------------------------------------
72
+ HEADER, FOOTER, MAIN
73
+ ------------------------------------- */
74
+ .main {
75
+ background: #ffffff;
76
+ border-radius: 3px;
77
+ width: 100%;
78
+ }
79
+
80
+ .wrapper {
81
+ box-sizing: border-box;
82
+ padding: 20px;
83
+ }
84
+
85
+ .content-block {
86
+ padding-bottom: 10px;
87
+ padding-top: 10px;
88
+ }
89
+
90
+ .footer {
91
+ clear: both;
92
+ margin-top: 10px;
93
+ text-align: center;
94
+ width: 100%;
95
+ }
96
+ .footer td,
97
+ .footer p,
98
+ .footer span,
99
+ .footer a {
100
+ color: #999999;
101
+ font-size: 12px;
102
+ text-align: center;
103
+ }
104
+
105
+ /* -------------------------------------
106
+ TYPOGRAPHY
107
+ ------------------------------------- */
108
+ h1,
109
+ h2,
110
+ h3,
111
+ h4 {
112
+ color: #000000;
113
+ font-family: sans-serif;
114
+ font-weight: 400;
115
+ line-height: 1.4;
116
+ margin: 0;
117
+ margin-bottom: 30px;
118
+ }
119
+
120
+ h1 {
121
+ font-size: 35px;
122
+ font-weight: 300;
123
+ text-align: center;
124
+ text-transform: capitalize;
125
+ }
126
+
127
+ p,
128
+ ul,
129
+ ol {
130
+ font-family: sans-serif;
131
+ font-size: 14px;
132
+ font-weight: normal;
133
+ margin: 0;
134
+ margin-bottom: 15px;
135
+ }
136
+ p li,
137
+ ul li,
138
+ ol li {
139
+ list-style-position: inside;
140
+ margin-left: 5px;
141
+ }
142
+
143
+ a {
144
+ color: #3498db;
145
+ text-decoration: underline;
146
+ }
147
+
148
+ /* -------------------------------------
149
+ BUTTONS
150
+ ------------------------------------- */
151
+ .btn {
152
+ box-sizing: border-box;
153
+ width: 100%; }
154
+ .btn > tbody > tr > td {
155
+ padding-bottom: 15px; }
156
+ .btn table {
157
+ width: auto;
158
+ }
159
+ .btn table td {
160
+ background-color: #ffffff;
161
+ border-radius: 5px;
162
+ text-align: center;
163
+ }
164
+ .btn a {
165
+ background-color: #ffffff;
166
+ border: solid 1px #3498db;
167
+ border-radius: 5px;
168
+ box-sizing: border-box;
169
+ color: #3498db;
170
+ cursor: pointer;
171
+ display: inline-block;
172
+ font-size: 14px;
173
+ font-weight: bold;
174
+ margin: 0;
175
+ padding: 12px 25px;
176
+ text-decoration: none;
177
+ text-transform: capitalize;
178
+ }
179
+
180
+ .btn-primary table td {
181
+ background-color: #3498db;
182
+ }
183
+
184
+ .btn-primary a {
185
+ background-color: #3498db;
186
+ border-color: #3498db;
187
+ color: #ffffff;
188
+ }
189
+
190
+ /* -------------------------------------
191
+ OTHER STYLES THAT MIGHT BE USEFUL
192
+ ------------------------------------- */
193
+ .last {
194
+ margin-bottom: 0;
195
+ }
196
+
197
+ .first {
198
+ margin-top: 0;
199
+ }
200
+
201
+ .align-center {
202
+ text-align: center;
203
+ }
204
+
205
+ .align-right {
206
+ text-align: right;
207
+ }
208
+
209
+ .align-left {
210
+ text-align: left;
211
+ }
212
+
213
+ .clear {
214
+ clear: both;
215
+ }
216
+
217
+ .mt0 {
218
+ margin-top: 0;
219
+ }
220
+
221
+ .mb0 {
222
+ margin-bottom: 0;
223
+ }
224
+
225
+ .preheader {
226
+ color: transparent;
227
+ display: none;
228
+ height: 0;
229
+ max-height: 0;
230
+ max-width: 0;
231
+ opacity: 0;
232
+ overflow: hidden;
233
+ mso-hide: all;
234
+ visibility: hidden;
235
+ width: 0;
236
+ }
237
+
238
+ .powered-by a {
239
+ text-decoration: none;
240
+ }
241
+
242
+ hr {
243
+ border: 0;
244
+ border-bottom: 1px solid #f6f6f6;
245
+ margin: 20px 0;
246
+ }
247
+
248
+ /* -------------------------------------
249
+ RESPONSIVE AND MOBILE FRIENDLY STYLES
250
+ ------------------------------------- */
251
+ @media only screen and (max-width: 620px) {
252
+ table[class=body] h1 {
253
+ font-size: 28px !important;
254
+ margin-bottom: 10px !important;
255
+ }
256
+ table[class=body] p,
257
+ table[class=body] ul,
258
+ table[class=body] ol,
259
+ table[class=body] td,
260
+ table[class=body] span,
261
+ table[class=body] a {
262
+ font-size: 16px !important;
263
+ }
264
+ table[class=body] .wrapper,
265
+ table[class=body] .article {
266
+ padding: 10px !important;
267
+ }
268
+ table[class=body] .content {
269
+ padding: 0 !important;
270
+ }
271
+ table[class=body] .container {
272
+ padding: 0 !important;
273
+ width: 100% !important;
274
+ }
275
+ table[class=body] .main {
276
+ border-left-width: 0 !important;
277
+ border-radius: 0 !important;
278
+ border-right-width: 0 !important;
279
+ }
280
+ table[class=body] .btn table {
281
+ width: 100% !important;
282
+ }
283
+ table[class=body] .btn a {
284
+ width: 100% !important;
285
+ }
286
+ table[class=body] .img-responsive {
287
+ height: auto !important;
288
+ max-width: 100% !important;
289
+ width: auto !important;
290
+ }
291
+ }
292
+
293
+ /* -------------------------------------
294
+ PRESERVE THESE STYLES IN THE HEAD
295
+ ------------------------------------- */
296
+ @media all {
297
+ .ExternalClass {
298
+ width: 100%;
299
+ }
300
+ .ExternalClass,
301
+ .ExternalClass p,
302
+ .ExternalClass span,
303
+ .ExternalClass font,
304
+ .ExternalClass td,
305
+ .ExternalClass div {
306
+ line-height: 100%;
307
+ }
308
+ .apple-link a {
309
+ color: inherit !important;
310
+ font-family: inherit !important;
311
+ font-size: inherit !important;
312
+ font-weight: inherit !important;
313
+ line-height: inherit !important;
314
+ text-decoration: none !important;
315
+ }
316
+ .btn-primary table td:hover {
317
+ background-color: #34495e !important;
318
+ }
319
+ .btn-primary a:hover {
320
+ background-color: #34495e !important;
321
+ border-color: #34495e !important;
322
+ }
323
+ }
324
+
325
+ </style>
326
+ </head>
327
+ <body class="">
328
+ <span class="preheader">This is preheader text. Some clients will show this text as a preview.</span>
329
+ <table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
330
+ <tr>
331
+ <td>&nbsp;</td>
332
+ <td class="container">
333
+ <div class="content">
334
+
335
+ <!-- START CENTERED WHITE CONTAINER -->
336
+ <table role="presentation" class="main">
337
+
338
+ <!-- START MAIN CONTENT AREA -->
339
+ <tr>
340
+ <td class="wrapper">
341
+ <table role="presentation" border="0" cellpadding="0" cellspacing="0">
342
+ <tr>
343
+ <td>
344
+ <p>Hi there,</p>
345
+ <p>Sometimes you just want to send a simple HTML email with a simple design and clear call to action. This is it.</p>
346
+ <table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
347
+ <tbody>
348
+ <tr>
349
+ <td align="left">
350
+ <table role="presentation" border="0" cellpadding="0" cellspacing="0">
351
+ <tbody>
352
+ <tr>
353
+ <td> <a href="http://htmlemail.io" target="_blank">Call To Action</a> </td>
354
+ </tr>
355
+ </tbody>
356
+ </table>
357
+ </td>
358
+ </tr>
359
+ </tbody>
360
+ </table>
361
+ <p>This is a really simple email template. Its sole purpose is to get the recipient to click the button with no distractions.</p>
362
+ <p>Good luck! Hope it works.</p>
363
+ </td>
364
+ </tr>
365
+ </table>
366
+ </td>
367
+ </tr>
368
+
369
+ <!-- END MAIN CONTENT AREA -->
370
+ </table>
371
+ <!-- END CENTERED WHITE CONTAINER -->
372
+
373
+ <!-- START FOOTER -->
374
+ <div class="footer">
375
+ <table role="presentation" border="0" cellpadding="0" cellspacing="0">
376
+ <tr>
377
+ <td class="content-block">
378
+ <span class="apple-link">Company Inc, 3 Abbey Road, San Francisco CA 94102</span>
379
+ <br> Don't like these emails? <a href="http://i.imgur.com/CScmqnj.gif">Unsubscribe</a>.
380
+ </td>
381
+ </tr>
382
+ <tr>
383
+ <td class="content-block powered-by">
384
+ Powered by <a href="http://htmlemail.io">HTMLemail</a>.
385
+ </td>
386
+ </tr>
387
+ </table>
388
+ </div>
389
+ <!-- END FOOTER -->
390
+
391
+ </div>
392
+ </td>
393
+ <td>&nbsp;</td>
394
+ </tr>
395
+ </table>
396
+ </body>
397
+ </html>
398
+