sendgrid-ruby 5.1.0 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,9 +2,11 @@ This documentation provides examples for specific use cases. Please [open an iss
2
2
 
3
3
  # Table of Contents
4
4
 
5
- * [Transactional Templates](#transactional_templates)
5
+ * [Transactional Templates](#transactional-templates)
6
+ * [How to Setup a Domain Whitelabel](#domain-whitelabel)
7
+ * [How to View Email Statistics](#email-statistics)
6
8
 
7
- <a name="transactional_templates"></a>
9
+ <a name="transactional-templates"></a>
8
10
  # Transactional Templates
9
11
 
10
12
  For this example, we assume you have created a [transactional template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/index.html). Following is the template content we used for testing.
@@ -110,4 +112,32 @@ end
110
112
  puts response.status_code
111
113
  puts response.body
112
114
  puts response.headers
113
- ```
115
+ ```
116
+
117
+ ## Adding Attachments
118
+
119
+ ```ruby
120
+ attachment = Attachment.new
121
+ attachment.content = Base64.strict_encode64(File.open(fpath, 'rb').read)
122
+ attachment.type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
123
+ attachment.filename = fname
124
+ attachment.disposition = 'attachment'
125
+ attachment.content_id = 'Reports Sheet'
126
+ mail.add_attachment(attachment)
127
+
128
+ ```
129
+ Attachments must be base64 encoded, using Base64's strict_encode64 where no line feeds are added.
130
+
131
+ <a name="domain-whitelabel"></a>
132
+ # How to Setup a Domain Whitelabel
133
+
134
+ You can find documentation for how to setup a domain whitelabel via the UI [here](https://sendgrid.com/docs/Classroom/Basics/Whitelabel/setup_domain_whitelabel.html) and via API [here](https://github.com/sendgrid/sendgrid-ruby/blob/master/USAGE.md#whitelabel).
135
+
136
+ Find more information about all of SendGrid's whitelabeling related documentation [here](https://sendgrid.com/docs/Classroom/Basics/Whitelabel/index.html).
137
+
138
+ <a name="email-statistics"></a>
139
+ # How to View Email Statistics
140
+
141
+ You can find documentation for how to view your email statistics via the UI [here](https://app.sendgrid.com/statistics) and via API [here](https://github.com/sendgrid/sendgrid-ruby/blob/master/USAGE.md#stats).
142
+
143
+ Alternatively, we can post events to a URL of your choice via our [Event Webhook](https://sendgrid.com/docs/API_Reference/Webhooks/event.html) about events that occur as SendGrid processes your email.
@@ -0,0 +1,42 @@
1
+ require 'sendgrid-ruby'
2
+ require 'date'
3
+
4
+ include SendGrid
5
+
6
+ sg_client = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY']).client
7
+ stats = SendGrid::EmailStats.new(sendgrid_client: sg_client)
8
+
9
+ # Fetch stats by day, between 2 dates
10
+ from = Date.new(2017, 10, 01)
11
+ to = Date.new(2017, 10, 12)
12
+
13
+ email_stats = stats.by_day(from, to)
14
+
15
+ email_stats.metrics
16
+
17
+ if !email_stats.error?
18
+ email_stats.metrics.each do |metric|
19
+ puts "Date - #{metric.date}"
20
+ puts "Number of Requests - #{metric.requests}"
21
+ puts "Bounces - #{metric.bounces}"
22
+ puts "Opens - #{metric.opens}"
23
+ puts "Clicks - #{metric.clicks}"
24
+ end
25
+ end
26
+
27
+ # Fetch stats by week, between 2 dates for a category
28
+ from = Date.new(2017, 10, 01)
29
+ to = Date.new(2017, 10, 12)
30
+ category = 'abcd'
31
+
32
+ email_stats = stats.by_week(from, to, category)
33
+
34
+ if !email_stats.error?
35
+ email_stats.metrics.each do |metric|
36
+ puts "Date - #{metric.date}"
37
+ puts "Number of Requests - #{metric.requests}"
38
+ puts "Bounces - #{metric.bounces}"
39
+ puts "Opens - #{metric.opens}"
40
+ puts "Clicks - #{metric.clicks}"
41
+ end
42
+ end
@@ -22,3 +22,6 @@ require_relative 'sendgrid/helpers/mail/subscription_tracking'
22
22
  require_relative 'sendgrid/helpers/mail/substitution'
23
23
  require_relative 'sendgrid/helpers/mail/tracking_settings'
24
24
  require_relative 'sendgrid/helpers/settings/settings'
25
+ require_relative 'sendgrid/helpers/stats/email_stats'
26
+ require_relative 'sendgrid/helpers/stats/stats_response'
27
+ require_relative 'sendgrid/helpers/stats/metrics'
@@ -3,8 +3,12 @@ require 'json'
3
3
  module SendGrid
4
4
  class Email
5
5
  def initialize(email: nil, name: nil)
6
- @email = email
7
- @name = name
6
+ if name
7
+ @email = email
8
+ @name = name
9
+ else
10
+ @email, @name = split_email(email)
11
+ end
8
12
  end
9
13
 
10
14
  def email=(email)
@@ -23,6 +27,11 @@ module SendGrid
23
27
  @name
24
28
  end
25
29
 
30
+ def split_email(email)
31
+ split = /(?:(?<address>.+)\s)?<?(?<email>.+@[^>]+)>?/.match(email)
32
+ return split[:email], split[:address]
33
+ end
34
+
26
35
  def to_json(*)
27
36
  {
28
37
  'email' => self.email,
@@ -1,4 +1,4 @@
1
- **This module allows you to quickly and easily build a Settings object for retreiving or updating you SendGrid Settings.**
1
+ **This module allows you to quickly and easily build a Settings object for retrieving or updating you SendGrid Settings.**
2
2
 
3
3
  # Quick Start
4
4
 
@@ -11,4 +11,4 @@ ruby examples/helpers/settings/example.rb
11
11
  ## Usage
12
12
 
13
13
  - See the [example](https://github.com/sendgrid/sendgrid-ruby/tree/master/examples/helpers/settings) for a complete working example.
14
- - [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Settings/index.html)
14
+ - [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Settings/index.html)
@@ -0,0 +1,46 @@
1
+ require 'json'
2
+
3
+ module SendGrid
4
+ class EmailStats
5
+ def initialize(args)
6
+ @sendgrid_client = args[:sendgrid_client]
7
+ end
8
+
9
+ def by_day(start_date, end_date, categories = nil, subusers = nil)
10
+ get('day', start_date, end_date, categories, subusers)
11
+ end
12
+
13
+ def by_week(start_date, end_date, categories = nil, subusers = nil)
14
+ get('week', start_date, end_date, categories, subusers)
15
+ end
16
+
17
+ def by_month(start_date, end_date, categories = nil, subusers = nil)
18
+ get('month', start_date, end_date, categories, subusers)
19
+ end
20
+
21
+ def get(aggregated_by, start_date, end_date, categories = nil, subusers = nil)
22
+ params = query_params(aggregated_by, start_date, end_date, categories, subusers)
23
+
24
+ response_body = @sendgrid_client.stats.get(query_params: params).body
25
+ build_response(response_body)
26
+ end
27
+
28
+ private
29
+
30
+ def query_params(aggregated_by, start_date, end_date, categories, subusers)
31
+ params = {
32
+ aggregated_by: aggregated_by,
33
+ start_date: start_date,
34
+ end_date: end_date
35
+ }
36
+ params.merge(categories: categories) if categories
37
+ params.merge(subusers: subusers) if subusers
38
+ params
39
+ end
40
+
41
+ def build_response(response_body)
42
+ response_json = JSON.parse(response_body)
43
+ StatsResponse.new(response_json)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,35 @@
1
+ require 'json'
2
+
3
+ module SendGrid
4
+ class Metrics
5
+ attr_reader :blocks, :bounce_drops,
6
+ :bounces, :clicks, :deferred, :delivered,
7
+ :invalid_emails, :opens, :processed, :requests,
8
+ :spam_report_drops, :spam_reports, :unique_clicks,
9
+ :unique_opens, :unsubscribe_drops, :unsubscribes
10
+
11
+ def initialize(args={})
12
+ @date = args['date']
13
+ @blocks = args['blocks']
14
+ @bounce_drops = args['bounce_drops']
15
+ @bounces = args['bounces']
16
+ @clicks = args['clicks']
17
+ @deferred = args['deferred']
18
+ @delivered = args['delivered']
19
+ @invalid_emails = args['invalid_emails']
20
+ @opens = args['opens']
21
+ @processed = args['processed']
22
+ @requests = args['requests']
23
+ @spam_report_drops = args['spam_report_drops']
24
+ @spam_reports = args['spam_reports']
25
+ @unique_clicks = args['unique_clicks']
26
+ @unique_opens = args['unique_opens']
27
+ @unsubscribe_drops = args['unsubscribe_drops']
28
+ @unsubscribes = args['unsubscribes']
29
+ end
30
+
31
+ def date
32
+ Date.parse(@date)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,31 @@
1
+ require 'json'
2
+
3
+ module SendGrid
4
+ class StatsResponse
5
+ def initialize(args)
6
+ @errors = args['errors'] if args.is_a? Hash
7
+ @stats = args if args.is_a? Array
8
+ end
9
+
10
+ def errors
11
+ @errors.map do |error|
12
+ error['message']
13
+ end
14
+ end
15
+
16
+ def error?
17
+ !@errors.nil?
18
+ end
19
+
20
+ def metrics
21
+ @stats.flat_map do |stat|
22
+ starting_date = stat['date']
23
+ all_stats_for_date = stat['stats']
24
+
25
+ metrics = all_stats_for_date.map do |metric|
26
+ Metrics.new(metric['metrics'].merge('date' => starting_date))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module SendGrid
2
- VERSION = '5.1.0'
2
+ VERSION = '5.2.0'
3
3
  end
@@ -16,9 +16,14 @@ to = SendGrid::Email.new('test@example.com', 'Example User')
16
16
  subject = 'Sending with SendGrid is Fun'
17
17
  plain_text_content = 'and easy to do anywhere, even with Ruby'
18
18
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
19
- msg = SendGrid::Mail.create_single_email(from, to, subject, plain_text_content, html_content)
19
+ msg = SendGrid::Mail.create(from: from,
20
+ tos: to,
21
+ subject: subject,
22
+ plain_text_content: plain_text_content,
23
+ html_content: html_content,
24
+ substitutions: {})
20
25
 
21
- client = SendGrid::ClientFactory.new(api_key: ENV['SENDGRID_API_KEY'])
26
+ client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
22
27
 
23
28
  begin
24
29
  response = client.send_email(msg)
@@ -38,7 +43,7 @@ The following code assumes you are storing the API key in an [environment variab
38
43
  require 'sendgrid-ruby'
39
44
 
40
45
  from = SendGrid::Email.new('test@example.com', 'Example User')
41
- tos = [
46
+ tos = [
42
47
  SendGrid::Email.new('test1@example.com', 'Example User1'),
43
48
  SendGrid::Email.new('test2@example.com', 'Example User2'),
44
49
  SendGrid::Email.new('test3@example.com', 'Example User3')
@@ -46,13 +51,14 @@ tos = [
46
51
  subject = 'Sending with SendGrid is Fun'
47
52
  plain_text_content = 'and easy to do anywhere, even with Ruby'
48
53
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
49
- msg = SendGrid::Mail.create_single_email_to_multiple_recipients(from,
50
- tos,
51
- subject,
52
- plain_text_content,
53
- html_content)
54
+ msg = SendGrid::Mail.create(from: from,
55
+ tos: tos,
56
+ subject: subject,
57
+ plain_text_content: plain_text_content,
58
+ html_content: html_content,
59
+ substitutions: {})
54
60
 
55
- client = SendGrid::ClientFactory.new(api_key: ENV['SENDGRID_API_KEY'])
61
+ client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
56
62
 
57
63
  begin
58
64
  response = client.send_email(msg)
@@ -72,7 +78,7 @@ The following code assumes you are storing the API key in an [environment variab
72
78
  require 'sendgrid-ruby'
73
79
 
74
80
  from = SendGrid::Email.new('test@example.com', 'Example User')
75
- tos = [
81
+ tos = [
76
82
  SendGrid::Email.new('test1@example.com', 'Example User1'),
77
83
  SendGrid::Email.new('test2@example.com', 'Example User2'),
78
84
  SendGrid::Email.new('test3@example.com', 'Example User3')
@@ -92,14 +98,14 @@ values = [
92
98
  substitutions = {
93
99
  '-name1-' => values
94
100
  }
95
- msg = SendGrid::Mail.create_multiple_emails_to_multiple_recipients(from,
96
- tos,
97
- subjects,
98
- plain_text_content,
99
- html_content,
100
- substitutions)
101
+ msg = SendGrid::Mail.create(from: from,
102
+ tos: tos,
103
+ subject: subjects,
104
+ plain_text_content: plain_text_content,
105
+ html_content: html_content,
106
+ substitutions: substitutions)
101
107
 
102
- client = SendGrid::ClientFactory.new(api_key: ENV['SENDGRID_API_KEY'])
108
+ client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
103
109
 
104
110
  begin
105
111
  response = client.send_email(msg)
@@ -116,33 +122,33 @@ puts response.headers
116
122
  The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
117
123
 
118
124
  ```ruby
119
- client = SendGrid::ClientFactory.new(api_key: ENV['SENDGRID_API_KEY'])
125
+ client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
120
126
 
121
127
  from = SendGrid::Email.new('test@example.com', 'Example User')
122
128
  to = SendGrid::Email.new('test@example.com', 'Example User')
123
129
  subject = 'Sending with SendGrid is Fun'
124
130
  plain_text_content = 'and easy to do anywhere, even with Ruby'
125
131
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
126
- msg = SendGrid::SendGridMessage.new(from, to, subject, plain_text_content, html_content)
132
+ msg = SendGrid::Message.new(from, to, subject, plain_text_content, html_content)
127
133
 
128
134
  # For a detailed description of each of these settings, please see the [documentation](https://sendgrid.com/docs/API_Reference/api_v3.html).
129
135
 
130
136
  msg.add_to(SendGrid::Email.new('test1@example.com', 'Example User1'))
131
- to_emails = [
137
+ to_emails = [
132
138
  SendGrid::Email.new('test2@example.com', 'Example User2'),
133
139
  SendGrid::Email.new('test3@example.com', 'Example User3')
134
140
  ];
135
141
  msg.add_tos(to_emails)
136
142
 
137
143
  msg.add_cc(SendGrid::Email.new('test4@example.com', 'Example User4'))
138
- cc_emails = [
144
+ cc_emails = [
139
145
  SendGrid::Email.new('test5@example.com', 'Example User5'),
140
146
  SendGrid::Email.new('test6@example.com', 'Example User6')
141
147
  ];
142
148
  msg.add_ccs(cc_emails)
143
149
 
144
150
  msg.add_bcc(SendGrid::Email.new('test7@example.com', 'Example User7'))
145
- bcc_emails = [
151
+ bcc_emails = [
146
152
  SendGrid::Email.new('test8@example.com', 'Example User8'),
147
153
  SendGrid::Email.new('test9@example.com', 'Example User9')
148
154
  ];
@@ -179,21 +185,21 @@ msg.set_subject('this subject overrides the Global Subject on the default Person
179
185
  # If you need to add more [Personalizations](https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/personalizations.html), here is an example of adding another Personalization by passing in a personalization index.
180
186
 
181
187
  msg.add_to(SendGrid::Email.new('test10@example.com', 'Example User10'), 1)
182
- to_emails = [
188
+ to_emails = [
183
189
  SendGrid::Email.new('test11@example.com', 'Example User11'),
184
190
  SendGrid::Email.new('test12@example.com', 'Example User12')
185
191
  ];
186
192
  msg.add_tos(to_emails, 1)
187
193
 
188
194
  msg.add_cc(SendGrid::Email.new('test13@example.com', 'Example User13'), 1)
189
- cc_emails = [
195
+ cc_emails = [
190
196
  SendGrid::Email.new('test14@example.com', 'Example User14'),
191
197
  SendGrid::Email.new('test15@example.com', 'Example User15')
192
198
  ];
193
199
  msg.add_ccs(cc_emails, 1)
194
200
 
195
201
  msg.add_bcc(SendGrid::Email.new('test16@example.com', 'Example User16'), 1)
196
- bcc_emails = [
202
+ bcc_emails = [
197
203
  SendGrid::Email.new('test17@example.com', 'Example User17'),
198
204
  SendGrid::Email.new('test18@example.com', 'Example User18')
199
205
  ];
@@ -292,16 +298,18 @@ puts response.headers
292
298
  The following code assumes you are storing the API key in an [environment variable (recommended)](https://github.com/sendgrid/sendgrid-ruby/blob/master/TROUBLESHOOTING.md#environment-variables-and-your-sendgrid-api-key). If you don't have your key stored in an environment variable, you can assign it directly to `api_key` for testing purposes.
293
299
 
294
300
  ```ruby
295
- client = SendGrid::ClientFactory.new(api_key: ENV['SENDGRID_API_KEY'])
301
+ client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
296
302
 
297
303
  from = SendGrid::Email.new('test@example.com', 'Example User')
298
304
  to = SendGrid::Email.new('test@example.com', 'Example User')
299
305
  subject = 'Sending with SendGrid is Fun'
300
306
  plain_text_content = 'and easy to do anywhere, even with Ruby'
301
307
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
302
- msg = SendGrid::SendGridMessage.new(from, to, subject, plain_text_content, html_content)
308
+ msg = SendGrid::Message.new(from, to, subject, plain_text_content, html_content)
309
+ bytes = File.read('/path/to/the/attachment.pdf')
310
+ encoded = Base64.encode64(bytes)
303
311
  msg.add_attachment('balance_001.pdf',
304
- 'base64 encoded content',
312
+ encoded,
305
313
  'application/pdf',
306
314
  'attachment',
307
315
  'Balance Sheet')
@@ -355,14 +363,14 @@ I hope you are having a great day in -city- :)
355
363
  ```
356
364
 
357
365
  ```ruby
358
- client = SendGrid::ClientFactory.new(api_key: ENV['SENDGRID_API_KEY'])
366
+ client = SendGrid::Client.new(api_key: ENV['SENDGRID_API_KEY'])
359
367
 
360
368
  from = SendGrid::Email.new('test@example.com', 'Example User')
361
369
  to = SendGrid::Email.new('test@example.com', 'Example User')
362
370
  subject = 'Sending with SendGrid is Fun'
363
371
  plain_text_content = 'and easy to do anywhere, even with Ruby'
364
372
  html_content = '<strong>and easy to do anywhere, even with Ruby</strong>'
365
- msg = SendGrid::SendGridMessage.new(from, to, subject, plain_text_content, html_content)
373
+ msg = SendGrid::Message.new(from, to, subject, plain_text_content, html_content)
366
374
 
367
375
  substitutions = [
368
376
  '-name-' => 'Example User',
@@ -0,0 +1,112 @@
1
+ require 'spec_helper'
2
+
3
+ describe SendGrid::EmailStats do
4
+ let(:sg_client) { SendGrid::API.new(api_key: 'abcd').client }
5
+ let(:stats) { SendGrid::EmailStats.new(sendgrid_client: sg_client) }
6
+ let(:sg_response) { double('SendGrid::Response') }
7
+
8
+ let(:sample_response) do
9
+ [{
10
+ "date" => "2017-10-01",
11
+ "stats" => [
12
+ {"metrics" =>
13
+ {
14
+ "blocks" => 101,
15
+ "bounce_drops" => 102,
16
+ "bounces" => 103,
17
+ "clicks" => 104,
18
+ "deferred" => 105,
19
+ "delivered" => 106,
20
+ "invalid_emails" => 107,
21
+ "opens" => 108,
22
+ "processed" => 109,
23
+ "requests" => 110,
24
+ "spam_report_drops" => 111,
25
+ "spam_reports" => 112,
26
+ "unique_clicks" => 113,
27
+ "unique_opens" => 114,
28
+ "unsubscribe_drops" => 115,
29
+ "unsubscribes" => 116
30
+ }
31
+ }
32
+ ]
33
+ }]
34
+ end
35
+
36
+ let(:error_response) do
37
+ {
38
+ "errors" => [
39
+ {
40
+ "message" => "end_date should be a YYYY-MM-DD formatted date"
41
+ }
42
+ ]
43
+ }
44
+ end
45
+
46
+ describe '.new' do
47
+ it 'initializes with SendGrid::Client' do
48
+ expect(stats).to be_a SendGrid::EmailStats
49
+ end
50
+ end
51
+
52
+ describe 'successful response' do
53
+ before do
54
+ allow_any_instance_of(SendGrid::Response).to receive(:body) { sample_response.to_json }
55
+ end
56
+
57
+ describe '#by_day' do
58
+ it 'fetches data aggregated by day' do
59
+ day_stats = stats.by_day('2017-10-01', '2017-10-02')
60
+ day_metrics = day_stats.metrics.first
61
+
62
+ expect(day_metrics).to be_a SendGrid::Metrics
63
+ expect(day_metrics.date.to_s).to eq('2017-10-01')
64
+ expect(day_metrics.requests).to eq(110)
65
+ expect(day_metrics.clicks).to eq(104)
66
+ expect(day_metrics.bounces).to eq(103)
67
+ expect(day_metrics.opens).to eq(108)
68
+ end
69
+ end
70
+
71
+ describe '#by_week' do
72
+ it 'fetches data aggregated by week' do
73
+ day_stats = stats.by_week('2017-10-01', '2017-10-12')
74
+ day_metrics = day_stats.metrics.first
75
+
76
+ expect(day_metrics).to be_a SendGrid::Metrics
77
+ expect(day_metrics.date.to_s).to eq('2017-10-01')
78
+ expect(day_metrics.requests).to eq(110)
79
+ expect(day_metrics.clicks).to eq(104)
80
+ expect(day_metrics.bounces).to eq(103)
81
+ expect(day_metrics.opens).to eq(108)
82
+ end
83
+ end
84
+
85
+ describe '#by_month' do
86
+ it 'fetches data aggregated by month' do
87
+ day_stats = stats.by_month('2017-10-01', '2017-11-01')
88
+ day_metrics = day_stats.metrics.first
89
+
90
+ expect(day_metrics).to be_a SendGrid::Metrics
91
+ expect(day_metrics.date.to_s).to eq('2017-10-01')
92
+ expect(day_metrics.requests).to eq(110)
93
+ expect(day_metrics.clicks).to eq(104)
94
+ expect(day_metrics.bounces).to eq(103)
95
+ expect(day_metrics.opens).to eq(108)
96
+ end
97
+ end
98
+ end
99
+
100
+ describe 'error response' do
101
+ before do
102
+ allow_any_instance_of(SendGrid::Response).to receive(:body) { error_response.to_json }
103
+ end
104
+
105
+ it 'fetches data aggregated by month' do
106
+ day_stats = stats.by_month('2017-10-01', '2017-10-02')
107
+
108
+ expect(day_stats.errors).to include('end_date should be a YYYY-MM-DD formatted date')
109
+ expect(day_stats.error?).to be_truthy
110
+ end
111
+ end
112
+ end