sendgrid-actionmailer 2.4.2 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -2
- data/Appraisals +0 -8
- data/CHANGELOG.md +49 -0
- data/README.md +57 -19
- data/lib/sendgrid_actionmailer.rb +106 -38
- data/lib/sendgrid_actionmailer/version.rb +1 -1
- data/sendgrid-actionmailer.gemspec +1 -1
- data/spec/lib/sendgrid_actionmailer_spec.rb +312 -51
- metadata +4 -6
- data/gemfiles/mail_2.5.gemfile +0 -7
- data/gemfiles/mail_2.6.gemfile +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 776fb071876f8748d9d6ab2ae7d304b18d60023afb9e6747aa9b2e5c11757dbb
|
4
|
+
data.tar.gz: 2ac9f378ca1372c581f10d24d1861a6b6b7fe3cbaddd9c5b6fc53f3d4f441ec8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb8c6ed35b214301a578d48b6d241c0a85366ff33767283da5e8d09c33210d960b62477c0de1df8397f144d0e70a95e83ea73c473502a7aa0ed8e949babe1ba7
|
7
|
+
data.tar.gz: 3830c481b115beffd21d53a4140d3a1d6de73ff4fe2952cbdafb63b3133b663a464d0075def2934b61112ab5a791d5c31796a86f1d2eeb25deb54ea3af3a1fdb
|
data/.travis.yml
CHANGED
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,54 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 3.0.2 - 2020-4-20
|
4
|
+
|
5
|
+
### Changes
|
6
|
+
|
7
|
+
- perform_send_request setting for testing perposes
|
8
|
+
|
9
|
+
## 3.0.1 - 2020-4-3
|
10
|
+
|
11
|
+
### Changes
|
12
|
+
|
13
|
+
- Validate error response body for empty string
|
14
|
+
|
15
|
+
## 3.0.0 - 2020-3-2
|
16
|
+
|
17
|
+
### Removed
|
18
|
+
|
19
|
+
- Compatibility with mail gems before version 2.7
|
20
|
+
|
21
|
+
## 2.6.0 - 2020-1-23
|
22
|
+
|
23
|
+
### Changes
|
24
|
+
|
25
|
+
- Dont send content types with dynamic templates (#69)
|
26
|
+
|
27
|
+
## 2.5.0 - 2020-1-21
|
28
|
+
|
29
|
+
### Changes
|
30
|
+
|
31
|
+
- Add personalizations field (#60)
|
32
|
+
|
33
|
+
### Fixes
|
34
|
+
|
35
|
+
- Revert "Lazy load ActionMailer::Base" (#64)
|
36
|
+
- Yank 2.4.1
|
37
|
+
|
38
|
+
## 2.4.2 - 2020-1-21
|
39
|
+
|
40
|
+
### Fixes
|
41
|
+
|
42
|
+
- Revert "Lazy load ActionMailer::Base" (#64)
|
43
|
+
- Yank 2.4.1
|
44
|
+
|
45
|
+
## 2.4.1 - 2020-1-20
|
46
|
+
|
47
|
+
### Changed
|
48
|
+
|
49
|
+
- Update Travis CI settings to test on latest Ruby and mail gem version (#55)
|
50
|
+
- Lazy load ActionMailer::Base (#57)
|
51
|
+
|
3
52
|
## 2.4.0 - 2019-07-9
|
4
53
|
|
5
54
|
### Changed
|
data/README.md
CHANGED
@@ -31,11 +31,12 @@ If you need to send mail for a number of Sendgrid accounts, you can set the API
|
|
31
31
|
|
32
32
|
```ruby
|
33
33
|
mail(to: 'example@email.com',
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
subject: 'email subject',
|
35
|
+
body: 'email body',
|
36
|
+
delivery_method_options: {
|
37
|
+
api_key: 'SENDGRID_API_KEY'
|
38
|
+
}
|
39
|
+
)
|
39
40
|
```
|
40
41
|
|
41
42
|
## SendGrid Mail Extensions
|
@@ -86,7 +87,7 @@ The unsubscribe group to associate with this email.
|
|
86
87
|
#### groups_to_display (array[integer])
|
87
88
|
An array containing the unsubscribe groups that you would like to be displayed on the unsubscribe preferences page.
|
88
89
|
|
89
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', asm: group_id: 99, groups_to_display: [4,5,6,7,8])```
|
90
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', asm: { group_id: 99, groups_to_display: [4,5,6,7,8] })```
|
90
91
|
|
91
92
|
### ip_pool_name (string)
|
92
93
|
The IP Pool that you would like to send this email from.
|
@@ -105,7 +106,7 @@ Indicates if this setting is enabled.
|
|
105
106
|
##### email (string)
|
106
107
|
The email address that you would like to receive the BCC.
|
107
108
|
|
108
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', mail_settings: {bcc: {enable: true, email: 'bcc@example.com}})```
|
109
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', mail_settings: { bcc: { enable: true, email: 'bcc@example.com }})```
|
109
110
|
|
110
111
|
#### bypass_list_management (object)
|
111
112
|
Allows you to bypass all unsubscribe groups and suppressions to ensure that the email is delivered to every single recipient. This should only be used in emergencies when it is absolutely necessary that every recipient receives your email.
|
@@ -113,7 +114,7 @@ Allows you to bypass all unsubscribe groups and suppressions to ensure that the
|
|
113
114
|
###### enable (boolean)
|
114
115
|
Indicates if this setting is enabled.
|
115
116
|
|
116
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
117
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', mail_settings: { bypass_list_management: { enable: true }})```
|
117
118
|
|
118
119
|
#### footer (object)
|
119
120
|
The default footer that you would like included on every email.
|
@@ -127,7 +128,7 @@ The plain text content of your footer.
|
|
127
128
|
##### html (string)
|
128
129
|
The HTML content of your footer.
|
129
130
|
|
130
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
131
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', mail_settings: { footer: { enable: true, text: 'FOOTER', html: '<h1>FOOTER</h1>' }})```
|
131
132
|
|
132
133
|
#### sandbox_mode (object)
|
133
134
|
This allows you to send a test email to ensure that your request body is valid and formatted correctly.
|
@@ -135,7 +136,7 @@ This allows you to send a test email to ensure that your request body is valid a
|
|
135
136
|
##### enable (boolean)
|
136
137
|
Indicates if this setting is enabled.
|
137
138
|
|
138
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
139
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', mail_settings: { sandbox_mode: { enable: true }})```
|
139
140
|
|
140
141
|
#### spam_check (object)
|
141
142
|
This allows you to test the content of your email for spam.
|
@@ -149,7 +150,8 @@ The threshold used to determine if your content qualifies as spam on a scale fro
|
|
149
150
|
##### post_to_url (string)
|
150
151
|
An Inbound Parse URL that you would like a copy of your email along with the spam report to be sent to.
|
151
152
|
|
152
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
153
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', mail_settings: { spam_check: { enable: true, threshold: 1, post_to_url: 'https://spamcatcher.sendgrid.com' }})```
|
154
|
+
|
153
155
|
### tracking_settings(json)
|
154
156
|
Settings to determine how you would like to track the metrics of how your recipients interact with your email.
|
155
157
|
|
@@ -159,10 +161,10 @@ Allows you to track whether a recipient clicked a link in your email.
|
|
159
161
|
##### enable (boolean)
|
160
162
|
Indicates if this setting is enabled.
|
161
163
|
|
162
|
-
#####
|
164
|
+
##### enable_text (boolean)
|
163
165
|
Indicates if this setting should be included in the text/plain portion of your email.
|
164
166
|
|
165
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
167
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', tracking_settings: { click_tracking: { enable: false, enable_text: false }})```
|
166
168
|
|
167
169
|
#### open_tracking (object)
|
168
170
|
Allows you to track whether the email was opened or not, but including a single pixel image in the body of the content. When the pixel is loaded, we can log that the email was opened.
|
@@ -173,7 +175,7 @@ Indicates if this setting is enabled.
|
|
173
175
|
##### substitution_tag (string)
|
174
176
|
Allows you to specify a substitution tag that you can insert in the body of your email at a location that you desire. This tag will be replaced by the open tracking pixel.
|
175
177
|
|
176
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
178
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', tracking_settings: { open_tracking: { enable: true, substitution_tag: 'Optional tag to replace with the open image in the body of the message' }})```
|
177
179
|
|
178
180
|
#### subscription_tracking (object)
|
179
181
|
Allows you to insert a subscription management link at the bottom of the text and html bodies of your email. If you would like to specify the location of the link within your email, you may use the substitution_tag.
|
@@ -190,7 +192,7 @@ HTML to be appended to the email, with the subscription tracking link. You may c
|
|
190
192
|
##### substitution_tag (string)
|
191
193
|
A tag that will be replaced with the unsubscribe URL. for example: [unsubscribe_url]. If this parameter is used, it will override both the text and html parameters. The URL of the link will be placed at the substitution tag’s location, with no additional formatting.
|
192
194
|
|
193
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
195
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', tracking_settings: { subscription_tracking: { enable: true, text: 'text to insert into the text/plain portion of the message', html: 'html to insert into the text/html portion of the message', substitution_tag: 'Optional tag to replace with the open image in the body of the message' }})```
|
194
196
|
|
195
197
|
#### ganalytics (object)
|
196
198
|
Allows you to enable tracking provided by Google Analytics.
|
@@ -213,20 +215,56 @@ Used to differentiate your campaign from advertisements.
|
|
213
215
|
##### utm_campaign (string)
|
214
216
|
The name of the campaign.
|
215
217
|
|
216
|
-
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body',
|
218
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', tracking_settings: { ganalytics: { enable: true, utm_source: 'some source', utm_medium: 'some medium', utm_term: 'some term', utm_content: 'some content', utm_campaign: 'some campaign' }})```
|
217
219
|
|
218
220
|
### dynamic_template_data (json)
|
219
221
|
|
220
|
-
Data to provide for feeding the new dynamic templates in Sendgrid with valueable data. This also disables the following Unsubscribe links because of deprecation of substitutions in the new template implementaiton.
|
222
|
+
Data to provide for feeding the new dynamic templates in Sendgrid with valueable data. This also disables the following Unsubscribe links because of deprecation of substitutions in the new template implementaiton. Variables are available within templates using [{{handlebar syntax}}](https://sendgrid.com/docs/for-developers/sending-email/using-handlebars).
|
223
|
+
|
224
|
+
```mail(to: 'example@email.com', subject: 'email subject', body: 'email body', dynamic_template_data: { variable_1: 'foo', variable_2: 'bar' })```
|
225
|
+
|
226
|
+
### personalizations (json)
|
227
|
+
|
228
|
+
Allows providing a customized [personalizations](https://sendgrid.com/docs/for-developers/sending-email/personalizations/) array for the v3 Mail Send endpoint. This allows customizing how an email is sent and also allows sending multiple different emails to different recipients with a single API call.
|
229
|
+
|
230
|
+
The personalizations object supports:
|
231
|
+
|
232
|
+
- "to", "cc", "bcc" - The recipients of your email.
|
233
|
+
- "subject" - The subject of your email.
|
234
|
+
- "headers" - Any headers you would like to include in your email.
|
235
|
+
- "substitutions" - Any substitutions you would like to be made for your email.
|
236
|
+
- "custom_args" - Any custom arguments you would like to include in your email.
|
237
|
+
- "send_at" - A specific time that you would like your email to be sent.
|
238
|
+
- "dynamic_template_data" - data for dynamic templates.
|
239
|
+
|
240
|
+
The following should be noted about these personalization attributes:
|
241
|
+
- to, cc, or bcc: if either to, cc, or bcc is also set when calling mail, those addresses provided to mail will be inserted as a separate personalization from the ones you provide. However, when using personalizations, you are not required to specify `to` when calling the mail function.
|
242
|
+
- dynamic_template_data specified in the mail function will be merged with any dynamic_template_data specified in the personalizations object (with the personalizations object keys having priority).
|
243
|
+
- Other fields set in the personalizations object will override any global parameters defined outside of personalizations.
|
244
|
+
|
245
|
+
Also note that substitutions will not work with dynamic templates.
|
221
246
|
|
222
|
-
|
247
|
+
Example usage:
|
248
|
+
|
249
|
+
```
|
250
|
+
mail(subject: 'default subject', 'email body', personalizations: [
|
251
|
+
{ to: [{ email: 'example@example.com' }]},
|
252
|
+
{ to: [{ email: 'example2@example.com' }]}
|
253
|
+
])
|
254
|
+
```
|
223
255
|
|
224
256
|
### Unsubscribe Links
|
225
257
|
|
226
|
-
Sendgrid unfortunately uses <% %> for their default substitution syntax, which makes it incompatible with Rails templates. Their proposed solution is to use Personalization Substitutions with the v3 Mail Send Endpoint.
|
258
|
+
Sendgrid unfortunately uses <% %> for their default substitution syntax, which makes it incompatible with Rails templates. Their proposed solution is to use Personalization Substitutions with the v3 Mail Send Endpoint. This gem makes that modification to make the following Rails friendly unsubscribe urls.
|
227
259
|
|
228
260
|
* `<a href="%asm_group_unsubscribe_raw_url%">Unsubscribe</a>`
|
229
261
|
* `<a href="%asm_global_unsubscribe_raw_url%">Unsubscribe from List</a>`
|
230
262
|
* `<a href="%asm_preferences_raw_url%">Manage Email Preferences</a>`
|
231
263
|
|
232
264
|
Note: This feature, and substitutions in general, do not work in combination with dynamic templates.
|
265
|
+
|
266
|
+
## Testing
|
267
|
+
|
268
|
+
The setting `perform_send_request` is available to disable sending for testing purposes. Setting perform_send_request false and return_response true enables the testing of the JSON API payload.
|
269
|
+
|
270
|
+
|
@@ -4,6 +4,7 @@ require 'sendgrid-ruby'
|
|
4
4
|
|
5
5
|
module SendGridActionMailer
|
6
6
|
class DeliveryMethod
|
7
|
+
|
7
8
|
# TODO: use custom class to customer excpetion payload
|
8
9
|
SendgridDeliveryError = Class.new(StandardError)
|
9
10
|
|
@@ -24,18 +25,20 @@ module SendGridActionMailer
|
|
24
25
|
m.from = to_email(mail.from)
|
25
26
|
m.reply_to = to_email(mail.reply_to)
|
26
27
|
m.subject = mail.subject || ""
|
27
|
-
# https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/personalizations.html
|
28
|
-
m.add_personalization(to_personalizations(mail))
|
29
28
|
end
|
30
29
|
|
30
|
+
add_personalizations(sendgrid_mail, mail)
|
31
31
|
add_api_key(sendgrid_mail, mail)
|
32
32
|
add_content(sendgrid_mail, mail)
|
33
33
|
add_send_options(sendgrid_mail, mail)
|
34
34
|
add_mail_settings(sendgrid_mail, mail)
|
35
35
|
add_tracking_settings(sendgrid_mail, mail)
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
if (settings[:perform_send_request] == false)
|
38
|
+
response = sendgrid_mail
|
39
|
+
else
|
40
|
+
response = perform_send_request(sendgrid_mail)
|
41
|
+
end
|
39
42
|
|
40
43
|
settings[:return_response] ? response : self
|
41
44
|
end
|
@@ -75,20 +78,51 @@ module SendGridActionMailer
|
|
75
78
|
end
|
76
79
|
end
|
77
80
|
|
78
|
-
def
|
79
|
-
Personalization.new
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
def setup_personalization(mail, personalization_hash)
|
82
|
+
personalization = Personalization.new
|
83
|
+
|
84
|
+
personalization_hash = self.class.transform_keys(personalization_hash, &:to_s)
|
85
|
+
|
86
|
+
(personalization_hash['to'] || []).each do |to|
|
87
|
+
personalization.add_to Email.new(email: to['email'], name: to['name'])
|
88
|
+
end
|
89
|
+
(personalization_hash['cc'] || []).each do |cc|
|
90
|
+
personalization.add_cc Email.new(email: cc['email'], name: cc['name'])
|
91
|
+
end
|
92
|
+
(personalization_hash['bcc'] || []).each do |bcc|
|
93
|
+
personalization.add_bcc Email.new(email: bcc['email'], name: bcc['name'])
|
94
|
+
end
|
95
|
+
(personalization_hash['headers'] || []).each do |header_key, header_value|
|
96
|
+
personalization.add_header Header.new(key: header_key, value: header_value)
|
97
|
+
end
|
98
|
+
(personalization_hash['substitutions'] || {}).each do |sub_key, sub_value|
|
99
|
+
personalization.add_substitution(Substitution.new(key: sub_key, value: sub_value))
|
100
|
+
end
|
101
|
+
(personalization_hash['custom_args'] || {}).each do |arg_key, arg_value|
|
102
|
+
personalization.add_custom_arg(CustomArg.new(key: arg_key, value: arg_value))
|
103
|
+
end
|
104
|
+
if personalization_hash['send_at']
|
105
|
+
personalization.send_at = personalization_hash['send_at']
|
106
|
+
end
|
107
|
+
if personalization_hash['subject']
|
108
|
+
personalization.subject = personalization_hash['subject']
|
109
|
+
end
|
83
110
|
|
111
|
+
if mail['dynamic_template_data'] || personalization_hash['dynamic_template_data']
|
84
112
|
if mail['dynamic_template_data']
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
p.add_substitution(Substitution.new(key: "%asm_preferences_raw_url%", value: "<%asm_preferences_raw_url%>"))
|
113
|
+
data = mail['dynamic_template_data'].unparsed_value
|
114
|
+
data.merge!(personalization_hash['dynamic_template_data'] || {})
|
115
|
+
else
|
116
|
+
data = personalization_hash['dynamic_template_data']
|
90
117
|
end
|
118
|
+
personalization.add_dynamic_template_data(data)
|
119
|
+
elsif mail['template_id'].nil?
|
120
|
+
personalization.add_substitution(Substitution.new(key: "%asm_group_unsubscribe_raw_url%", value: "<%asm_group_unsubscribe_raw_url%>"))
|
121
|
+
personalization.add_substitution(Substitution.new(key: "%asm_global_unsubscribe_raw_url%", value: "<%asm_global_unsubscribe_raw_url%>"))
|
122
|
+
personalization.add_substitution(Substitution.new(key: "%asm_preferences_raw_url%", value: "<%asm_preferences_raw_url%>"))
|
91
123
|
end
|
124
|
+
|
125
|
+
return personalization
|
92
126
|
end
|
93
127
|
|
94
128
|
def to_attachment(part)
|
@@ -115,28 +149,49 @@ module SendGridActionMailer
|
|
115
149
|
def add_api_key(sendgrid_mail, mail)
|
116
150
|
self.api_key = settings.fetch(:api_key)
|
117
151
|
if mail['delivery-method-options'] && mail['delivery-method-options'].value.include?('api_key')
|
118
|
-
self.api_key =
|
152
|
+
self.api_key = mail['delivery-method-options'].unparsed_value['api_key']
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def add_attachments(sendgrid_mail, mail)
|
157
|
+
mail.attachments.each do |part|
|
158
|
+
sendgrid_mail.add_attachment(to_attachment(part))
|
119
159
|
end
|
120
160
|
end
|
121
161
|
|
122
162
|
def add_content(sendgrid_mail, mail)
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
163
|
+
if mail['template_id']
|
164
|
+
# We are sending a template, so we don't need to add any content outside
|
165
|
+
# of attachments
|
166
|
+
add_attachments(sendgrid_mail, mail)
|
167
|
+
else
|
168
|
+
case mail.mime_type
|
169
|
+
when 'text/plain'
|
170
|
+
sendgrid_mail.add_content(to_content(:plain, mail.body.decoded))
|
171
|
+
when 'text/html'
|
172
|
+
sendgrid_mail.add_content(to_content(:html, mail.body.decoded))
|
173
|
+
when 'multipart/alternative', 'multipart/mixed', 'multipart/related'
|
174
|
+
sendgrid_mail.add_content(to_content(:plain, mail.text_part.decoded)) if mail.text_part
|
175
|
+
sendgrid_mail.add_content(to_content(:html, mail.html_part.decoded)) if mail.html_part
|
176
|
+
|
177
|
+
add_attachments(sendgrid_mail, mail)
|
134
178
|
end
|
135
179
|
end
|
136
180
|
end
|
137
181
|
|
138
|
-
def
|
139
|
-
|
182
|
+
def add_personalizations(sendgrid_mail, mail)
|
183
|
+
if mail['personalizations']
|
184
|
+
mail['personalizations'].unparsed_value.each do |p|
|
185
|
+
sendgrid_mail.add_personalization(setup_personalization(mail, p))
|
186
|
+
end
|
187
|
+
end
|
188
|
+
if (mail.to && mail.to.any?) || (mail.cc && mail.cc.any?) || (mail.bcc && mail.bcc.any?)
|
189
|
+
personalization = setup_personalization(mail, {})
|
190
|
+
to_emails(mail.to).each { |to| personalization.add_to(to) }
|
191
|
+
to_emails(mail.cc).each { |cc| personalization.add_cc(cc) }
|
192
|
+
to_emails(mail.bcc).each { |bcc| personalization.add_bcc(bcc) }
|
193
|
+
sendgrid_mail.add_personalization(personalization)
|
194
|
+
end
|
140
195
|
end
|
141
196
|
|
142
197
|
def add_send_options(sendgrid_mail, mail)
|
@@ -144,12 +199,12 @@ module SendGridActionMailer
|
|
144
199
|
sendgrid_mail.template_id = mail['template_id'].to_s
|
145
200
|
end
|
146
201
|
if mail['sections']
|
147
|
-
|
202
|
+
mail['sections'].unparsed_value.each do |key, value|
|
148
203
|
sendgrid_mail.add_section(Section.new(key: key, value: value))
|
149
204
|
end
|
150
205
|
end
|
151
206
|
if mail['headers']
|
152
|
-
|
207
|
+
mail['headers'].unparsed_value.each do |key, value|
|
153
208
|
sendgrid_mail.add_header(Header.new(key: key, value: value))
|
154
209
|
end
|
155
210
|
end
|
@@ -159,7 +214,7 @@ module SendGridActionMailer
|
|
159
214
|
end
|
160
215
|
end
|
161
216
|
if mail['custom_args']
|
162
|
-
|
217
|
+
mail['custom_args'].unparsed_value.each do |key, value|
|
163
218
|
sendgrid_mail.add_custom_arg(CustomArg.new(key: key, value: value))
|
164
219
|
end
|
165
220
|
end
|
@@ -170,10 +225,11 @@ module SendGridActionMailer
|
|
170
225
|
sendgrid_mail.batch_id = mail['batch_id'].to_s
|
171
226
|
end
|
172
227
|
if mail['asm']
|
173
|
-
asm =
|
174
|
-
asm = asm.delete_if { |key, value|
|
175
|
-
|
176
|
-
|
228
|
+
asm = mail['asm'].unparsed_value
|
229
|
+
asm = asm.delete_if { |key, value|
|
230
|
+
!key.to_s.match(/(group_id)|(groups_to_display)/) }
|
231
|
+
if asm.keys.map(&:to_s).include?('group_id')
|
232
|
+
sendgrid_mail.asm = ASM.new(self.class.transform_keys(asm, &:to_sym))
|
177
233
|
end
|
178
234
|
end
|
179
235
|
if mail['ip_pool_name']
|
@@ -183,7 +239,7 @@ module SendGridActionMailer
|
|
183
239
|
|
184
240
|
def add_mail_settings(sendgrid_mail, mail)
|
185
241
|
if mail['mail_settings']
|
186
|
-
settings =
|
242
|
+
settings = mail['mail_settings'].unparsed_value || {}
|
187
243
|
sendgrid_mail.mail_settings = MailSettings.new.tap do |m|
|
188
244
|
if settings[:bcc]
|
189
245
|
m.bcc = BccSettings.new(settings[:bcc])
|
@@ -206,7 +262,7 @@ module SendGridActionMailer
|
|
206
262
|
|
207
263
|
def add_tracking_settings(sendgrid_mail, mail)
|
208
264
|
if mail['tracking_settings']
|
209
|
-
settings =
|
265
|
+
settings = mail['tracking_settings'].unparsed_value
|
210
266
|
sendgrid_mail.tracking_settings = TrackingSettings.new.tap do |t|
|
211
267
|
if settings[:click_tracking]
|
212
268
|
t.click_tracking = ClickTracking.new(settings[:click_tracking])
|
@@ -228,7 +284,7 @@ module SendGridActionMailer
|
|
228
284
|
result = client.mail._('send').post(request_body: email.to_json) # ლ(ಠ益ಠლ) that API
|
229
285
|
|
230
286
|
if result.status_code && result.status_code.start_with?('4')
|
231
|
-
message =
|
287
|
+
message = !(result.body.empty?) ? JSON.parse(result.body).fetch('errors').pop.fetch('message') : 'Sendgrid API Error'
|
232
288
|
full_message = "Sendgrid delivery failed with #{result.status_code} #{message}"
|
233
289
|
|
234
290
|
settings[:raise_delivery_errors] ? raise(SendgridDeliveryError, full_message) : warn(full_message)
|
@@ -236,5 +292,17 @@ module SendGridActionMailer
|
|
236
292
|
|
237
293
|
result
|
238
294
|
end
|
295
|
+
|
296
|
+
# Recursive key transformation based on Rails deep_transform_values
|
297
|
+
def self.transform_keys(object, &block)
|
298
|
+
case object
|
299
|
+
when Hash
|
300
|
+
object.map { |key, value| [yield(key), transform_keys(value, &block)] }.to_h
|
301
|
+
when Array
|
302
|
+
object.map { |e| transform_keys(e, &block) }
|
303
|
+
else
|
304
|
+
object
|
305
|
+
end
|
306
|
+
end
|
239
307
|
end
|
240
308
|
end
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
20
|
spec.require_paths = ['lib']
|
21
21
|
|
22
|
-
spec.add_dependency 'mail', '~> 2.
|
22
|
+
spec.add_dependency 'mail', '~> 2.7'
|
23
23
|
spec.add_dependency 'sendgrid-ruby', '~> 6.0'
|
24
24
|
|
25
25
|
spec.add_development_dependency 'appraisal', '~> 2.1.0'
|
@@ -3,6 +3,10 @@ require 'webmock/rspec'
|
|
3
3
|
|
4
4
|
module SendGridActionMailer
|
5
5
|
describe DeliveryMethod do
|
6
|
+
def transform_keys(object, &block)
|
7
|
+
SendGridActionMailer::DeliveryMethod.transform_keys(object, &block)
|
8
|
+
end
|
9
|
+
|
6
10
|
subject(:mailer) do
|
7
11
|
DeliveryMethod.new(api_key: 'key')
|
8
12
|
end
|
@@ -55,6 +59,11 @@ module SendGridActionMailer
|
|
55
59
|
m = DeliveryMethod.new(return_response: true)
|
56
60
|
expect(m.settings[:return_response]).to eq(true)
|
57
61
|
end
|
62
|
+
|
63
|
+
it 'sets perform_deliveries' do
|
64
|
+
m = DeliveryMethod.new(perform_send_request: false)
|
65
|
+
expect(m.settings[:perform_send_request]).to eq(false)
|
66
|
+
end
|
58
67
|
end
|
59
68
|
|
60
69
|
describe '#deliver!' do
|
@@ -242,13 +251,51 @@ module SendGridActionMailer
|
|
242
251
|
])
|
243
252
|
end
|
244
253
|
|
245
|
-
context '
|
246
|
-
|
254
|
+
context 'template_id' do
|
255
|
+
before do
|
247
256
|
mail['template_id'] = '1'
|
257
|
+
end
|
258
|
+
|
259
|
+
it 'sets a template_id' do
|
248
260
|
mailer.deliver!(mail)
|
249
261
|
expect(client.sent_mail['template_id']).to eq('1')
|
250
262
|
end
|
251
263
|
|
264
|
+
it 'does not set unsubscribe substitutions' do
|
265
|
+
mailer.deliver!(mail)
|
266
|
+
expect(client.sent_mail['personalizations'].first).to_not have_key('substitutions')
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'does not set send a content type' do
|
270
|
+
mailer.deliver!(mail)
|
271
|
+
expect(client.sent_mail['content']).to eq(nil)
|
272
|
+
end
|
273
|
+
|
274
|
+
it 'does not set send a content type even if body is given' do
|
275
|
+
# This matches the default behavior of ActionMail. body must be
|
276
|
+
# specified and content_type defaults to text/plain.
|
277
|
+
mail.body = 'I heard you like pineapple.'
|
278
|
+
mail.content_type = 'text/plain'
|
279
|
+
mailer.deliver!(mail)
|
280
|
+
expect(client.sent_mail['content']).to eq(nil)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
context 'without dynamic template data or a template id' do
|
285
|
+
it 'sets unsubscribe substitutions' do
|
286
|
+
mailer.deliver!(mail)
|
287
|
+
expect(client.sent_mail['personalizations'].first).to have_key('substitutions')
|
288
|
+
substitutions = client.sent_mail['personalizations'].first['substitutions']
|
289
|
+
expect(substitutions).to eq({
|
290
|
+
'%asm_group_unsubscribe_raw_url%' => '<%asm_group_unsubscribe_raw_url%>',
|
291
|
+
'%asm_global_unsubscribe_raw_url%' => '<%asm_global_unsubscribe_raw_url%>',
|
292
|
+
'%asm_preferences_raw_url%' => '<%asm_preferences_raw_url%>'
|
293
|
+
})
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
context 'send options' do
|
298
|
+
|
252
299
|
it 'sets sections' do
|
253
300
|
mail['sections'] = {'%foo%' => 'bar'}
|
254
301
|
mailer.deliver!(mail)
|
@@ -283,10 +330,10 @@ module SendGridActionMailer
|
|
283
330
|
end
|
284
331
|
|
285
332
|
it 'sets asm' do
|
286
|
-
asm = {
|
333
|
+
asm = {group_id: 99, groups_to_display: [4,5,6,7,8]}
|
287
334
|
mail['asm'] = asm
|
288
335
|
mailer.deliver!(mail)
|
289
|
-
expect(client.sent_mail['asm']).to eq(asm)
|
336
|
+
expect(client.sent_mail['asm']).to eq(transform_keys(asm, &:to_s))
|
290
337
|
end
|
291
338
|
|
292
339
|
it 'sets ip_pool_name' do
|
@@ -295,109 +342,109 @@ module SendGridActionMailer
|
|
295
342
|
expect(client.sent_mail['ip_pool_name']).to eq('marketing')
|
296
343
|
end
|
297
344
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
expect(client.sent_mail['asm']).to eq({"group_id" => 99, "groups_to_display" => [4,5,6,7,8]})
|
304
|
-
end
|
305
|
-
|
306
|
-
it "should parse 1.9 hash" do
|
307
|
-
asm = { group_id: 99, groups_to_display: [4,5,6,7,8]}
|
308
|
-
mail['asm'] = asm
|
309
|
-
mailer.deliver!(mail)
|
310
|
-
expect(client.sent_mail['asm']).to eq({"group_id" => 99, "groups_to_display" => [4,5,6,7,8]})
|
311
|
-
end
|
312
|
-
|
313
|
-
it "should parse json" do
|
314
|
-
asm = {'group_id' => 99, 'groups_to_display' => [4,5,6,7,8]}
|
315
|
-
mail['asm'] = asm.to_json
|
316
|
-
mailer.deliver!(mail)
|
317
|
-
expect(client.sent_mail['asm']).to eq({"group_id" => 99, "groups_to_display" => [4,5,6,7,8]})
|
318
|
-
end
|
345
|
+
it 'should not change values inside custom args' do
|
346
|
+
custom_args = { 'text' => 'line with a => in it' }
|
347
|
+
mail['custom_args'] = custom_args
|
348
|
+
mailer.deliver!(mail)
|
349
|
+
expect(client.sent_mail['custom_args']).to eq('text' => 'line with a => in it')
|
319
350
|
end
|
320
351
|
|
321
352
|
context 'mail_settings' do
|
322
353
|
it 'sets bcc' do
|
323
|
-
bcc = {
|
354
|
+
bcc = { bcc: { enable: true, email: 'test@example.com' }}
|
324
355
|
mail['mail_settings'] = bcc
|
325
356
|
mailer.deliver!(mail)
|
326
|
-
expect(client.sent_mail['mail_settings']).to eq(bcc)
|
357
|
+
expect(client.sent_mail['mail_settings']).to eq(transform_keys(bcc, &:to_s))
|
327
358
|
end
|
328
359
|
|
329
360
|
it 'sets bypass_list_management' do
|
330
|
-
bypass = {
|
361
|
+
bypass = { bypass_list_management: { enable: true }}
|
331
362
|
mail['mail_settings'] = bypass
|
332
363
|
mailer.deliver!(mail)
|
333
|
-
expect(client.sent_mail['mail_settings']).to eq(bypass)
|
364
|
+
expect(client.sent_mail['mail_settings']).to eq(transform_keys(bypass, &:to_s))
|
334
365
|
end
|
335
366
|
|
336
367
|
it 'sets footer' do
|
337
|
-
footer = {
|
368
|
+
footer = {footer: { enable: true, text: 'Footer Text', html: '<html><body>Footer Text</body></html>'}}
|
338
369
|
mail['mail_settings'] = footer
|
339
370
|
mailer.deliver!(mail)
|
340
|
-
expect(client.sent_mail['mail_settings']).to eq(footer)
|
371
|
+
expect(client.sent_mail['mail_settings']).to eq(transform_keys(footer, &:to_s))
|
341
372
|
end
|
342
373
|
|
343
374
|
it 'sets sandbox_mode' do
|
344
|
-
sandbox = {
|
375
|
+
sandbox = {sandbox_mode: { enable: true }}
|
345
376
|
mail['mail_settings'] = sandbox
|
346
377
|
mailer.deliver!(mail)
|
347
|
-
expect(client.sent_mail['mail_settings']).to eq(sandbox)
|
378
|
+
expect(client.sent_mail['mail_settings']).to eq(transform_keys(sandbox, &:to_s))
|
348
379
|
end
|
349
380
|
|
350
381
|
it 'sets spam_check' do
|
351
|
-
spam_check = {
|
382
|
+
spam_check = {spam_check: { enable: true, threshold: 1, post_to_url: 'https://spamcatcher.sendgrid.com'}}
|
352
383
|
mail['mail_settings'] = spam_check
|
353
384
|
mailer.deliver!(mail)
|
354
|
-
expect(client.sent_mail['mail_settings']).to eq(spam_check)
|
385
|
+
expect(client.sent_mail['mail_settings']).to eq(transform_keys(spam_check, &:to_s))
|
355
386
|
end
|
356
387
|
end
|
357
388
|
|
358
389
|
context 'tracking_settings' do
|
359
390
|
it 'sets click_tracking' do
|
360
|
-
tracking = {
|
361
|
-
mail['tracking_settings'] = tracking
|
391
|
+
tracking = { click_tracking: { enable: false, enable_text: false }}
|
392
|
+
mail['tracking_settings'] = tracking.dup
|
362
393
|
mailer.deliver!(mail)
|
363
|
-
expect(client.sent_mail['tracking_settings']).to eq(tracking)
|
394
|
+
expect(client.sent_mail['tracking_settings']).to eq(transform_keys(tracking, &:to_s))
|
364
395
|
end
|
365
396
|
|
366
397
|
it 'sets open_tracking' do
|
367
|
-
tracking = {
|
398
|
+
tracking = { open_tracking: { enable: true, substitution_tag: 'Optional tag to replace with the open image in the body of the message' }}
|
368
399
|
mail['tracking_settings'] = tracking
|
369
400
|
mailer.deliver!(mail)
|
370
|
-
expect(client.sent_mail['tracking_settings']).to eq(tracking)
|
401
|
+
expect(client.sent_mail['tracking_settings']).to eq(transform_keys(tracking, &:to_s))
|
371
402
|
end
|
372
403
|
|
373
404
|
it 'sets subscription_tracking' do
|
374
|
-
tracking = {
|
405
|
+
tracking = { subscription_tracking: { enable: true, text: 'text to insert into the text/plain portion of the message', html: 'html to insert into the text/html portion of the message', substitution_tag: 'Optional tag to replace with the open image in the body of the def message' }}
|
375
406
|
mail['tracking_settings'] = tracking
|
376
407
|
mailer.deliver!(mail)
|
377
|
-
expect(client.sent_mail['tracking_settings']).to eq(tracking)
|
408
|
+
expect(client.sent_mail['tracking_settings']).to eq(transform_keys(tracking, &:to_s))
|
378
409
|
end
|
379
410
|
|
380
411
|
it 'sets ganalytics' do
|
381
|
-
tracking = {
|
412
|
+
tracking = { ganalytics: { enable: true, utm_source: 'some source', utm_medium: 'some medium', utm_term: 'some term', utm_content: 'some content', utm_campaign: 'some campaign' }}
|
382
413
|
mail['tracking_settings'] = tracking
|
383
414
|
mailer.deliver!(mail)
|
384
|
-
expect(client.sent_mail['tracking_settings']).to eq(tracking)
|
415
|
+
expect(client.sent_mail['tracking_settings']).to eq(transform_keys(tracking, &:to_s))
|
385
416
|
end
|
386
417
|
end
|
387
418
|
|
388
419
|
context 'dynamic template data' do
|
420
|
+
let(:template_data) do
|
421
|
+
{ variable_1: '1', variable_2: '2' }
|
422
|
+
end
|
423
|
+
|
424
|
+
before { mail['dynamic_template_data'] = template_data }
|
425
|
+
|
389
426
|
it 'sets dynamic_template_data' do
|
390
|
-
template_data = { variable_1: '1', variable_2: '2' }
|
391
|
-
mail['dynamic_template_data'] = template_data
|
392
427
|
mailer.deliver!(mail)
|
393
428
|
expect(client.sent_mail['personalizations'].first['dynamic_template_data']).to eq(template_data)
|
394
429
|
end
|
395
|
-
end
|
396
430
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
431
|
+
it 'does not set unsubscribe substitutions' do
|
432
|
+
mailer.deliver!(mail)
|
433
|
+
expect(client.sent_mail['personalizations'].first).to_not have_key('substitutions')
|
434
|
+
end
|
435
|
+
|
436
|
+
context 'containing what looks like hash syntax' do
|
437
|
+
let(:template_data) do
|
438
|
+
{ hint: 'Just use => instead of :' }
|
439
|
+
end
|
440
|
+
|
441
|
+
it 'does not change values inside dynamic template data' do
|
442
|
+
mailer.deliver!(mail)
|
443
|
+
expect(
|
444
|
+
client.sent_mail['personalizations'].first['dynamic_template_data']
|
445
|
+
).to eq(template_data)
|
446
|
+
end
|
447
|
+
end
|
401
448
|
end
|
402
449
|
|
403
450
|
it 'sets dynamic template data and sandbox_mode' do
|
@@ -509,6 +556,220 @@ module SendGridActionMailer
|
|
509
556
|
expect(content['content_id'].class).to eq(String)
|
510
557
|
end
|
511
558
|
end
|
559
|
+
|
560
|
+
context 'with personalizations' do
|
561
|
+
let(:personalizations) do
|
562
|
+
[
|
563
|
+
{
|
564
|
+
'to' => [
|
565
|
+
{'email' => 'john1@example.com', 'name' => 'John 1'},
|
566
|
+
{'email' => 'john2@example.com', 'name' => 'John 2'},
|
567
|
+
]
|
568
|
+
},
|
569
|
+
{
|
570
|
+
'to' => [
|
571
|
+
{'email' => 'john3@example.com', 'name' => 'John 3'},
|
572
|
+
{'email' => 'john4@example.com'}
|
573
|
+
],
|
574
|
+
'cc' => [
|
575
|
+
{'email' => 'cc@example.com'}
|
576
|
+
],
|
577
|
+
'bcc' => [
|
578
|
+
{'email' => 'bcc@example.com'}
|
579
|
+
],
|
580
|
+
'substitutions' => {
|
581
|
+
'%fname%' => 'Bob'
|
582
|
+
},
|
583
|
+
'subject' => 'personalized subject',
|
584
|
+
'send_at' => 1443636843,
|
585
|
+
'custom_args' => {
|
586
|
+
'user_id' => '343'
|
587
|
+
},
|
588
|
+
'headers' => {
|
589
|
+
'X-Test' => true
|
590
|
+
}
|
591
|
+
}
|
592
|
+
]
|
593
|
+
end
|
594
|
+
|
595
|
+
before do
|
596
|
+
mail.to = nil
|
597
|
+
mail.cc = nil
|
598
|
+
mail.bcc = nil
|
599
|
+
mail['personalizations'] = personalizations
|
600
|
+
end
|
601
|
+
|
602
|
+
it 'sets the provided to address personalizations' do
|
603
|
+
mailer.deliver!(mail)
|
604
|
+
expect(client.sent_mail['personalizations'].length).to eq(2)
|
605
|
+
expect(client.sent_mail['personalizations'][0]['to']).to eq(personalizations[0]['to'])
|
606
|
+
expect(client.sent_mail['personalizations'][1]['to']).to eq(personalizations[1]['to'])
|
607
|
+
end
|
608
|
+
|
609
|
+
it 'sets the provided cc address personalizations' do
|
610
|
+
mailer.deliver!(mail)
|
611
|
+
expect(client.sent_mail['personalizations'][0]).to_not have_key('cc')
|
612
|
+
expect(client.sent_mail['personalizations'][1]['cc']).to eq(personalizations[1]['cc'])
|
613
|
+
end
|
614
|
+
|
615
|
+
it 'sets the provided bcc address personalizations' do
|
616
|
+
mailer.deliver!(mail)
|
617
|
+
expect(client.sent_mail['personalizations'][0]).to_not have_key('bcc')
|
618
|
+
expect(client.sent_mail['personalizations'][1]['bcc']).to eq(personalizations[1]['bcc'])
|
619
|
+
end
|
620
|
+
|
621
|
+
it 'sets the provided subject personalizations' do
|
622
|
+
mailer.deliver!(mail)
|
623
|
+
expect(client.sent_mail['personalizations'][0]).to_not have_key('subject')
|
624
|
+
expect(client.sent_mail['personalizations'][1]['subject']).to eq(personalizations[1]['subject'])
|
625
|
+
end
|
626
|
+
|
627
|
+
it 'sets the provided headers personalizations' do
|
628
|
+
mailer.deliver!(mail)
|
629
|
+
expect(client.sent_mail['personalizations'][0]).to_not have_key('headers')
|
630
|
+
expect(client.sent_mail['personalizations'][1]['headers']).to eq(personalizations[1]['headers'])
|
631
|
+
end
|
632
|
+
|
633
|
+
it 'sets the provided custom_arg personalizations' do
|
634
|
+
mailer.deliver!(mail)
|
635
|
+
expect(client.sent_mail['personalizations'][0]).to_not have_key('custom_args')
|
636
|
+
expect(client.sent_mail['personalizations'][1]['custom_args']).to eq(personalizations[1]['custom_args'])
|
637
|
+
end
|
638
|
+
|
639
|
+
it 'sets the provided send_at personalizations' do
|
640
|
+
mailer.deliver!(mail)
|
641
|
+
expect(client.sent_mail['personalizations'][0]).to_not have_key('send_at')
|
642
|
+
expect(client.sent_mail['personalizations'][1]['send_at']).to eq(personalizations[1]['send_at'])
|
643
|
+
end
|
644
|
+
|
645
|
+
it 'sets the provided substitution personalizations' do
|
646
|
+
mailer.deliver!(mail)
|
647
|
+
expect(client.sent_mail['personalizations'][1]['substitutions']).to include(personalizations[1]['substitutions'])
|
648
|
+
end
|
649
|
+
|
650
|
+
it 'adds to the unsubscribe link substitutions' do
|
651
|
+
mailer.deliver!(mail)
|
652
|
+
expect(client.sent_mail['personalizations'][0]['substitutions']).to eq({
|
653
|
+
'%asm_group_unsubscribe_raw_url%' => '<%asm_group_unsubscribe_raw_url%>',
|
654
|
+
'%asm_global_unsubscribe_raw_url%' => '<%asm_global_unsubscribe_raw_url%>',
|
655
|
+
'%asm_preferences_raw_url%' => '<%asm_preferences_raw_url%>'
|
656
|
+
})
|
657
|
+
expect(client.sent_mail['personalizations'][1]['substitutions']).to include({
|
658
|
+
'%asm_group_unsubscribe_raw_url%' => '<%asm_group_unsubscribe_raw_url%>',
|
659
|
+
'%asm_global_unsubscribe_raw_url%' => '<%asm_global_unsubscribe_raw_url%>',
|
660
|
+
'%asm_preferences_raw_url%' => '<%asm_preferences_raw_url%>'
|
661
|
+
})
|
662
|
+
end
|
663
|
+
|
664
|
+
context 'with symbols used as keys' do
|
665
|
+
let(:personalizations) do
|
666
|
+
[
|
667
|
+
{
|
668
|
+
to: [
|
669
|
+
{email: 'sally1@example.com', name: 'Sally 1'},
|
670
|
+
{email: 'sally2@example.com', name: 'Sally 2'},
|
671
|
+
]
|
672
|
+
}
|
673
|
+
]
|
674
|
+
end
|
675
|
+
|
676
|
+
it 'still works' do
|
677
|
+
mailer.deliver!(mail)
|
678
|
+
expect(client.sent_mail['personalizations'].length).to eq(1)
|
679
|
+
expected_to = personalizations[0][:to].map { |t| transform_keys(t, &:to_s) }
|
680
|
+
expect(client.sent_mail['personalizations'][0]['to']).to eq(expected_to)
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
684
|
+
context 'dynamic template data passed into a personalizaiton' do
|
685
|
+
let(:personalization_data) do
|
686
|
+
{
|
687
|
+
'variable_1' => '1', 'variable_2' => '2'
|
688
|
+
}
|
689
|
+
end
|
690
|
+
|
691
|
+
let(:personalizations_with_dynamic_data) do
|
692
|
+
personalizations.tap do |p|
|
693
|
+
p[1]['dynamic_template_data'] = personalization_data
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
before do
|
698
|
+
mail['personalizations'] = nil
|
699
|
+
mail['personalizations'] = personalizations_with_dynamic_data
|
700
|
+
end
|
701
|
+
|
702
|
+
it 'sets the provided dynamic template data personalizations' do
|
703
|
+
mailer.deliver!(mail)
|
704
|
+
expect(client.sent_mail['personalizations'][0]).to_not have_key('dynamic_template_data')
|
705
|
+
expect(client.sent_mail['personalizations'][1]['dynamic_template_data']).to eq(personalization_data)
|
706
|
+
end
|
707
|
+
|
708
|
+
context 'dynamic template data is also set on the mail object' do
|
709
|
+
let(:mail_template_data) do
|
710
|
+
{ 'variable_3' => '1', 'variable_4' => '2' }
|
711
|
+
end
|
712
|
+
|
713
|
+
before { mail['dynamic_template_data'] = mail_template_data.dup }
|
714
|
+
|
715
|
+
it 'sets dynamic_template_data where not also provided as a personalization' do
|
716
|
+
mailer.deliver!(mail)
|
717
|
+
expect(client.sent_mail['personalizations'][0]['dynamic_template_data']).to eq(mail_template_data)
|
718
|
+
end
|
719
|
+
|
720
|
+
it 'merges the template data with a personalizations dynamic data' do
|
721
|
+
mailer.deliver!(mail)
|
722
|
+
expect(client.sent_mail['personalizations'][1]['dynamic_template_data']).to eq(
|
723
|
+
mail_template_data.merge(personalization_data)
|
724
|
+
)
|
725
|
+
end
|
726
|
+
end
|
727
|
+
end
|
728
|
+
|
729
|
+
context 'when to is set on mail object' do
|
730
|
+
before { mail.to = 'test@sendgrid.com' }
|
731
|
+
|
732
|
+
it 'adds that to address as a separate personalization' do
|
733
|
+
mailer.deliver!(mail)
|
734
|
+
expect(client.sent_mail['personalizations'].length).to eq(3)
|
735
|
+
expect(client.sent_mail['personalizations'][0]['to']).to eq(personalizations[0]['to'])
|
736
|
+
expect(client.sent_mail['personalizations'][1]['to']).to eq(personalizations[1]['to'])
|
737
|
+
expect(client.sent_mail['personalizations'][2]['to']).to eq([{"email"=>"test@sendgrid.com"}])
|
738
|
+
end
|
739
|
+
end
|
740
|
+
|
741
|
+
context 'when cc is set on mail object' do
|
742
|
+
before { mail.cc = 'test@sendgrid.com' }
|
743
|
+
|
744
|
+
it 'adds that cc address as a separate personalization' do
|
745
|
+
mailer.deliver!(mail)
|
746
|
+
expect(client.sent_mail['personalizations'].length).to eq(3)
|
747
|
+
expect(client.sent_mail['personalizations'][0]['cc']).to eq(personalizations[0]['cc'])
|
748
|
+
expect(client.sent_mail['personalizations'][1]['cc']).to eq(personalizations[1]['cc'])
|
749
|
+
expect(client.sent_mail['personalizations'][2]['cc']).to eq([{"email"=>"test@sendgrid.com"}])
|
750
|
+
end
|
751
|
+
end
|
752
|
+
|
753
|
+
context 'when bcc is set on mail object' do
|
754
|
+
before { mail.bcc = 'test@sendgrid.com' }
|
755
|
+
|
756
|
+
it 'adds that bcc address as a separate personalization' do
|
757
|
+
mailer.deliver!(mail)
|
758
|
+
expect(client.sent_mail['personalizations'].length).to eq(3)
|
759
|
+
expect(client.sent_mail['personalizations'][0]['bcc']).to eq(personalizations[0]['bcc'])
|
760
|
+
expect(client.sent_mail['personalizations'][1]['bcc']).to eq(personalizations[1]['bcc'])
|
761
|
+
expect(client.sent_mail['personalizations'][2]['bcc']).to eq([{"email"=>"test@sendgrid.com"}])
|
762
|
+
end
|
763
|
+
end
|
764
|
+
|
765
|
+
context 'when perform_send_request false' do
|
766
|
+
it 'should not send and email and return json body' do
|
767
|
+
m = DeliveryMethod.new(perform_send_request: false, return_response: true, api_key: 'key')
|
768
|
+
response = m.deliver!(mail)
|
769
|
+
expect(response).to respond_to(:to_json)
|
770
|
+
end
|
771
|
+
end
|
772
|
+
end
|
512
773
|
end
|
513
774
|
end
|
514
775
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sendgrid-actionmailer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eddie Zaneski
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-04-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mail
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '2.
|
21
|
+
version: '2.7'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: '2.
|
28
|
+
version: '2.7'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: sendgrid-ruby
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -128,8 +128,6 @@ files:
|
|
128
128
|
- LICENSE.txt
|
129
129
|
- README.md
|
130
130
|
- Rakefile
|
131
|
-
- gemfiles/mail_2.5.gemfile
|
132
|
-
- gemfiles/mail_2.6.gemfile
|
133
131
|
- gemfiles/mail_2.7.gemfile
|
134
132
|
- lib/sendgrid-actionmailer.rb
|
135
133
|
- lib/sendgrid_actionmailer.rb
|
data/gemfiles/mail_2.5.gemfile
DELETED