send_grid_mailer 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +102 -0
  3. data/.circleci/setup-rubygems.sh +3 -0
  4. data/.rubocop.yml +19 -579
  5. data/.ruby-version +1 -1
  6. data/CHANGELOG.md +10 -0
  7. data/README.md +33 -1
  8. data/lib/send_grid_mailer/definition.rb +32 -14
  9. data/lib/send_grid_mailer/dev_deliverer.rb +11 -2
  10. data/lib/send_grid_mailer/logger.rb +6 -1
  11. data/lib/send_grid_mailer/mailer_base_ext.rb +2 -0
  12. data/lib/send_grid_mailer/version.rb +1 -1
  13. data/send_grid_mailer.gemspec +12 -7
  14. data/spec/dummy/Rakefile +1 -1
  15. data/spec/dummy/app/assets/config/manifest.js +3 -0
  16. data/spec/dummy/app/assets/stylesheets/application.css +3 -3
  17. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  18. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  19. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  20. data/spec/dummy/app/{assets/javascripts → javascript/packs}/application.js +3 -1
  21. data/spec/dummy/app/jobs/application_job.rb +7 -0
  22. data/spec/dummy/app/mailers/application_mailer.rb +1 -1
  23. data/spec/dummy/app/mailers/test_mailer.rb +6 -0
  24. data/spec/dummy/app/models/application_record.rb +3 -0
  25. data/spec/dummy/app/views/layouts/application.html.erb +10 -9
  26. data/spec/dummy/bin/rails +3 -3
  27. data/spec/dummy/bin/rake +2 -2
  28. data/spec/dummy/bin/setup +18 -14
  29. data/spec/dummy/config.ru +3 -1
  30. data/spec/dummy/config/application.rb +12 -22
  31. data/spec/dummy/config/boot.rb +3 -3
  32. data/spec/dummy/config/cable.yml +10 -0
  33. data/spec/dummy/config/database.yml +2 -2
  34. data/spec/dummy/config/environment.rb +1 -1
  35. data/spec/dummy/config/environments/development.rb +48 -18
  36. data/spec/dummy/config/environments/production.rb +63 -22
  37. data/spec/dummy/config/environments/test.rb +29 -12
  38. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  39. data/spec/dummy/config/initializers/assets.rb +4 -3
  40. data/spec/dummy/config/initializers/backtrace_silencers.rb +4 -3
  41. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  42. data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
  43. data/spec/dummy/config/initializers/filter_parameter_logging.rb +3 -1
  44. data/spec/dummy/config/initializers/permissions_policy.rb +11 -0
  45. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -2
  46. data/spec/dummy/config/locales/en.yml +11 -1
  47. data/spec/dummy/config/puma.rb +43 -0
  48. data/spec/dummy/config/routes.rb +1 -54
  49. data/spec/dummy/config/storage.yml +34 -0
  50. data/spec/dummy/public/404.html +6 -6
  51. data/spec/dummy/public/422.html +6 -6
  52. data/spec/dummy/public/500.html +6 -6
  53. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  54. data/spec/dummy/public/apple-touch-icon.png +0 -0
  55. data/spec/dummy/spec/lib/send_grid_mailer/definition_spec.rb +52 -23
  56. data/spec/dummy/spec/mailers/test_mailer_spec.rb +84 -46
  57. data/spec/rails_helper.rb +3 -5
  58. metadata +142 -71
  59. data/.hound.yml +0 -4
  60. data/.travis.yml +0 -15
  61. data/spec/dummy/bin/bundle +0 -3
  62. data/spec/dummy/config/initializers/session_store.rb +0 -3
  63. data/spec/dummy/config/secrets.yml +0 -22
  64. data/spec/dummy/db/schema.rb +0 -16
  65. data/spec/dummy/spec/support/test_helpers.rb +0 -5
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.3
1
+ 2.7
data/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
  This project adheres to [Semantic Versioning](http://semver.org/).
4
4
 
5
+ ### v2.0.0
6
+
7
+ ##### Changed
8
+
9
+ * Replace travis with circleci.
10
+
11
+ ##### Removed
12
+
13
+ * Support for Ruby 2.5
14
+
5
15
  ### v1.2.1
6
16
 
7
17
  ##### Fixed
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SendGrid Mailer
2
2
  [![Gem Version](https://badge.fury.io/rb/send_grid_mailer.svg)](https://badge.fury.io/rb/send_grid_mailer)
3
- [![Build Status](https://travis-ci.org/platanus/send_grid_mailer.svg?branch=master)](https://travis-ci.org/platanus/send_grid_mailer)
3
+ [![CircleCI](https://circleci.com/gh/platanus/send_grid_mailer.svg?style=shield)](https://app.circleci.com/pipelines/github/platanus/send_grid_mailer)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/platanus/send_grid_mailer/badge.svg)](https://coveralls.io/github/platanus/send_grid_mailer)
5
5
 
6
6
  Is an Action Mailer adapter for using SendGrid in a Rails application and
@@ -169,6 +169,28 @@ class TestMailer < ApplicationMailer
169
169
  end
170
170
  ```
171
171
 
172
+ #### Set Dynamic Template Data
173
+
174
+ ```ruby
175
+ class TestMailer < ApplicationMailer
176
+ def my_email
177
+ dynamic_template_data({ key1: "value1", key2: "value2" })
178
+ mail
179
+ end
180
+ end
181
+ ```
182
+
183
+ #### Add Category
184
+
185
+ ```ruby
186
+ class TestMailer < ApplicationMailer
187
+ def my_email
188
+ add_category("value")
189
+ mail
190
+ end
191
+ end
192
+ ```
193
+
172
194
  > Remember: you need to specify al least: `body`, `template_id` or a Rails template.
173
195
 
174
196
  ## Recipient Interceptor
@@ -205,6 +227,16 @@ bundle exec guard
205
227
 
206
228
  You need to put **all your tests** in the `/send_grid_mailer/spec/dummy/spec/` directory.
207
229
 
230
+ ## Publishing
231
+
232
+ On master/main branch...
233
+
234
+ 1. Change `VERSION` in `lib/send_grid_mailer/version.rb`.
235
+ 2. Change `Unreleased` title to current version in `CHANGELOG.md`.
236
+ 3. Commit new release. For example: `Releasing v0.1.0`.
237
+ 4. Create tag. For example: `git tag v0.1.0`.
238
+ 5. Push tag. For example: `git push origin v0.1.0`.
239
+
208
240
  ## Contributing
209
241
 
210
242
  1. Fork it
@@ -2,28 +2,36 @@ module SendGridMailer
2
2
  class Definition
3
3
  METHODS = [
4
4
  :substitute,
5
+ :dynamic_template_data,
5
6
  :set_template_id,
6
7
  :set_sender,
7
8
  :set_recipients,
8
9
  :set_subject,
9
10
  :set_content,
10
11
  :add_attachment,
11
- :add_header
12
+ :add_header,
13
+ :add_category
12
14
  ]
13
15
 
14
16
  def substitute(key, value, default = "")
15
- personalization.substitutions = SendGrid::Substitution.new(
16
- key: key, value: value.to_s || default
17
+ personalization.add_substitution(
18
+ SendGrid::Substitution.new(key: key, value: value.to_s || default)
17
19
  )
18
20
  end
19
21
 
22
+ def dynamic_template_data(object)
23
+ personalization.add_dynamic_template_data(object)
24
+ end
25
+
20
26
  def set_template_id(value)
21
27
  return unless value
28
+
22
29
  mail.template_id = value
23
30
  end
24
31
 
25
32
  def set_sender(email)
26
33
  return unless email
34
+
27
35
  matched_format = email.match(/<(.+)>/)
28
36
  if matched_format
29
37
  address = matched_format[1]
@@ -37,19 +45,22 @@ module SendGridMailer
37
45
  def set_recipients(mode, *emails)
38
46
  emails.flatten.each do |email|
39
47
  next unless email
40
- personalization.send("#{mode}=", SendGrid::Email.new(email: email))
48
+
49
+ personalization.send("add_#{mode}", SendGrid::Email.new(email: email))
41
50
  end
42
51
  end
43
52
 
44
53
  def set_subject(value)
45
54
  return unless value
55
+
46
56
  personalization.subject = value
47
57
  end
48
58
 
49
59
  def set_content(value, type = nil)
50
60
  return unless value
51
- type = "text/plain" unless type
52
- mail.contents = SendGrid::Content.new(type: type, value: value)
61
+
62
+ type ||= "text/plain"
63
+ mail.add_content(SendGrid::Content.new(type: type, value: value))
53
64
  end
54
65
 
55
66
  def add_attachment(file, name, type, disposition = "inline", content_id = nil)
@@ -59,16 +70,23 @@ module SendGridMailer
59
70
  attachment.filename = name
60
71
  attachment.disposition = disposition
61
72
  attachment.content_id = content_id
62
- mail.attachments = attachment
73
+ mail.add_attachment(attachment)
63
74
  end
64
75
 
65
76
  def add_header(key, value)
66
77
  return if !key || !value
67
- personalization.headers = SendGrid::Header.new(key: key, value: value)
78
+
79
+ personalization.add_header(SendGrid::Header.new(key: key, value: value))
80
+ end
81
+
82
+ def add_category(value)
83
+ return unless value
84
+
85
+ mail.add_category(SendGrid::Category.new(name: value))
68
86
  end
69
87
 
70
88
  def to_json
71
- mail.personalizations = personalization if personalization?
89
+ mail.add_personalization(personalization) if personalization?
72
90
  mail.to_json
73
91
  end
74
92
 
@@ -77,7 +95,7 @@ module SendGridMailer
77
95
  end
78
96
 
79
97
  def clean_recipients(mode)
80
- personalization.instance_variable_set("@#{mode}s", nil)
98
+ personalization.instance_variable_set("@#{mode}s", [])
81
99
  end
82
100
 
83
101
  def personalization
@@ -86,12 +104,12 @@ module SendGridMailer
86
104
 
87
105
  def personalization?; !personalization.to_json.empty? end
88
106
 
89
- def content?; !mail.contents.blank? end
107
+ def content?; mail.contents.present? end
90
108
 
91
- def sender?; !mail.from.blank? end
109
+ def sender?; mail.from.present? end
92
110
 
93
- def subject?; !personalization.subject.blank? end
111
+ def subject?; personalization.subject.present? end
94
112
 
95
- def template_id?; !mail.template_id.blank? end
113
+ def template_id?; mail.template_id.present? end
96
114
  end
97
115
  end
@@ -3,6 +3,7 @@ module SendGridMailer
3
3
  include InterceptorsHandler
4
4
  include Logger
5
5
  require "letter_opener"
6
+ require "handlebars"
6
7
 
7
8
  def deliver!(sg_definition)
8
9
  @sg_definition = sg_definition
@@ -24,17 +25,25 @@ module SendGridMailer
24
25
  end
25
26
 
26
27
  def letter_opener_delivery_method
27
- @letter_opener_delivery_method ||= LetterOpener::DeliveryMethod.new(location: '/tmp/mails')
28
+ @letter_opener_delivery_method ||= LetterOpener::DeliveryMethod.new(location: dev_emails_location)
29
+ end
30
+
31
+ def dev_emails_location
32
+ Rails.application.config.action_mailer.sendgrid_dev_settings[:emails_location] || "/tmp/mails"
33
+ rescue
34
+ "/tmp/mails"
28
35
  end
29
36
 
30
37
  def parsed_template
31
38
  template_response = sg_api.get_template(@sg_definition)
32
39
  template_versions = JSON.parse(template_response.body)["versions"]
33
- return unless template_versions.present?
40
+ return if template_versions.blank?
34
41
 
35
42
  template_active_version = template_versions.find { |version| version["active"] == 1 }
36
43
  template_content = template_active_version["html_content"]
37
44
  @sg_definition.personalization.substitutions.each { |k, v| template_content.gsub!(k, v) }
45
+ template = Handlebars::Context.new.compile(template_content)
46
+ template_content = template.call(@sg_definition.personalization.dynamic_template_data)
38
47
  template_content
39
48
  end
40
49
 
@@ -40,18 +40,20 @@ module SendGridMailer
40
40
  def build_definition_message(data)
41
41
  data = data.keys.map do |k|
42
42
  d = data[k].to_s
43
- "#{k}: #{(d.blank? ? '-' : d)}"
43
+ "#{k}: #{d.presence || '-'}"
44
44
  end.join("\n")
45
45
  end
46
46
 
47
47
  def log_email(email)
48
48
  return if email.blank?
49
+
49
50
  email["email"]
50
51
  end
51
52
 
52
53
  def log_emails(personalization, origin)
53
54
  emails = personalization.send(origin)
54
55
  return if emails.blank?
56
+
55
57
  emails.map do |email|
56
58
  log_email(email)
57
59
  end.join(", ")
@@ -59,6 +61,7 @@ module SendGridMailer
59
61
 
60
62
  def log_attachments(mail)
61
63
  return if mail.attachments.blank?
64
+
62
65
  mail.attachments.map do |f|
63
66
  "\n\t#{f['filename']}"
64
67
  end.join("")
@@ -66,6 +69,7 @@ module SendGridMailer
66
69
 
67
70
  def log_contents(mail)
68
71
  return if mail.contents.blank?
72
+
69
73
  mail.contents.map do |content|
70
74
  "\n\ttype: #{content['type']}\n\tvalue: #{content['value']}"
71
75
  end.join("")
@@ -73,6 +77,7 @@ module SendGridMailer
73
77
 
74
78
  def log_pairs(hash)
75
79
  return if hash.blank?
80
+
76
81
  hash.keys.map do |k|
77
82
  "\n\t#{k} => #{hash[k]}"
78
83
  end.join("")
@@ -59,8 +59,10 @@ module ActionMailer
59
59
  def set_body(params)
60
60
  set_template_id(params[:template_id])
61
61
  return if sg_definition.template_id?
62
+
62
63
  set_content(params[:body], params[:content_type])
63
64
  return if sg_definition.content?
65
+
64
66
  set_body_from_tpl(params)
65
67
  end
66
68
 
@@ -1,3 +1,3 @@
1
1
  module SendGridMailer
2
- VERSION = "1.2.1"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -19,14 +19,19 @@ Gem::Specification.new do |s|
19
19
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  s.test_files = Dir["spec/**/*"]
21
21
 
22
- s.add_dependency "rails", ">= 4.2.0"
23
- s.add_dependency "sendgrid-ruby", "~> 4.0", ">= 4.0.4"
22
+ s.add_dependency "handlebars", "~> 0.8.0"
24
23
  s.add_dependency "letter_opener", "~> 1.7.0"
24
+ s.add_dependency "rails", ">= 4.2.0"
25
+ s.add_dependency "sendgrid-ruby", "~> 5", ">= 5.3.0"
26
+
27
+ s.add_development_dependency "coveralls"
28
+ s.add_development_dependency "factory_bot_rails"
29
+ s.add_development_dependency "guard-rspec", "~> 4.7"
25
30
  s.add_development_dependency "pry"
26
31
  s.add_development_dependency "pry-rails"
27
- s.add_development_dependency "sqlite3", "~> 1.3.13"
28
- s.add_development_dependency "rspec-rails", "~> 3.4.0"
29
- s.add_development_dependency "guard-rspec", "~> 4.7"
30
- s.add_development_dependency "factory_bot_rails"
31
- s.add_development_dependency "coveralls"
32
+ s.add_development_dependency "rspec-rails", "~> 3.5.0"
33
+ s.add_development_dependency "rspec_junit_formatter"
34
+ s.add_development_dependency "rubocop", "0.65.0"
35
+ s.add_development_dependency "rubocop-rspec"
36
+ s.add_development_dependency "sqlite3", "~> 1.4"
32
37
  end
data/spec/dummy/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  # Add your own tasks in files placed in lib/tasks ending in .rake,
2
2
  # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
3
 
4
- require File.expand_path('../config/application', __FILE__)
4
+ require_relative "config/application"
5
5
 
6
6
  Rails.application.load_tasks
@@ -0,0 +1,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../stylesheets .css
3
+ //= link send_grid_mailer_manifest.js
@@ -6,9 +6,9 @@
6
6
  * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
7
  *
8
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.
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
12
  *
13
13
  *= require_tree .
14
14
  *= require_self
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -1,5 +1,2 @@
1
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
2
  end
@@ -5,9 +5,11 @@
5
5
  // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
6
  //
7
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.
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
9
  //
10
10
  // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
+ //= require rails-ujs
14
+ //= require activestorage
13
15
  //= require_tree .
@@ -0,0 +1,7 @@
1
+ class ApplicationJob < ActiveJob::Base
2
+ # Automatically retry jobs that encountered a deadlock
3
+ # retry_on ActiveRecord::Deadlocked
4
+
5
+ # Most jobs are safe to ignore if the underlying records are no longer available
6
+ # discard_on ActiveJob::DeserializationError
7
+ end
@@ -1,4 +1,4 @@
1
1
  class ApplicationMailer < ActionMailer::Base
2
- default from: "from@example.com"
2
+ default from: 'from@example.com'
3
3
  layout 'mailer'
4
4
  end
@@ -84,4 +84,10 @@ class TestMailer < ApplicationMailer
84
84
  substitute "%key%", value
85
85
  mail(to: "r1@platan.us", body: "X")
86
86
  end
87
+
88
+ def dynamic_template_email(value)
89
+ set_template_id("XXX")
90
+ dynamic_template_data(key: value)
91
+ mail(to: "r1@platan.us")
92
+ end
87
93
  end
@@ -0,0 +1,3 @@
1
+ class ApplicationRecord < ActiveRecord::Base
2
+ self.abstract_class = true
3
+ end
@@ -1,14 +1,15 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
- <head>
4
- <title>Dummy</title>
5
- <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
6
- <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
7
- <%= csrf_meta_tags %>
8
- </head>
9
- <body>
3
+ <head>
4
+ <title>Dummy</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%= csrf_meta_tags %>
7
+ <%= csp_meta_tag %>
10
8
 
11
- <%= yield %>
9
+ <%= stylesheet_link_tag 'application', media: 'all' %>
10
+ </head>
12
11
 
13
- </body>
12
+ <body>
13
+ <%= yield %>
14
+ </body>
14
15
  </html>
data/spec/dummy/bin/rails CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path('../../config/application', __FILE__)
3
- require_relative '../config/boot'
4
- require 'rails/commands'
2
+ APP_PATH = File.expand_path('../config/application', __dir__)
3
+ require_relative "../config/boot"
4
+ require "rails/commands"