sendgrid-ruby 6.2.1 → 6.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -1
  3. data/.gitignore +1 -1
  4. data/.rubocop.yml +4 -0
  5. data/.rubocop_todo.yml +109 -0
  6. data/.travis.yml +3 -4
  7. data/CHANGELOG.md +69 -9
  8. data/CONTRIBUTING.md +11 -21
  9. data/FIRST_TIMERS.md +79 -0
  10. data/Gemfile +0 -1
  11. data/ISSUE_TEMPLATE.md +5 -1
  12. data/Makefile +4 -2
  13. data/PULL_REQUEST_TEMPLATE.md +1 -1
  14. data/README.md +22 -27
  15. data/Rakefile +2 -3
  16. data/TROUBLESHOOTING.md +5 -5
  17. data/USAGE.md +145 -38
  18. data/examples/accesssettings/accesssettings.rb +9 -12
  19. data/examples/alerts/alerts.rb +8 -11
  20. data/examples/apikeys/apikeys.rb +12 -15
  21. data/examples/asm/asm.rb +27 -30
  22. data/examples/browsers/browsers.rb +0 -3
  23. data/examples/campaigns/campaigns.rb +29 -32
  24. data/examples/categories/categories.rb +0 -3
  25. data/examples/clients/clients.rb +1 -4
  26. data/examples/contactdb/contactdb.rb +63 -66
  27. data/examples/devices/devices.rb +0 -3
  28. data/examples/emailactivity/emailactivity.rb +52 -0
  29. data/examples/geo/geo.rb +0 -3
  30. data/examples/helpers/eventwebhook/example.rb +16 -0
  31. data/examples/helpers/mail/example.rb +19 -13
  32. data/examples/helpers/settings/example.rb +1 -1
  33. data/examples/helpers/stats/example.rb +4 -4
  34. data/examples/ips/ips.rb +19 -22
  35. data/examples/mail/mail.rb +72 -75
  36. data/examples/mailboxproviders/mailboxproviders.rb +0 -3
  37. data/examples/mailsettings/mailsettings.rb +21 -24
  38. data/examples/partnersettings/partnersettings.rb +3 -6
  39. data/examples/scopes/scopes.rb +7 -9
  40. data/examples/senderauthentication/senderauthentication.rb +41 -44
  41. data/examples/senders/senders.rb +28 -31
  42. data/examples/stats/stats.rb +0 -3
  43. data/examples/subusers/subusers.rb +17 -20
  44. data/examples/suppression/suppression.rb +15 -18
  45. data/examples/templates/templates.rb +29 -31
  46. data/examples/trackingsettings/trackingsettings.rb +14 -17
  47. data/examples/user/user.rb +41 -44
  48. data/lib/rack/sendgrid_webhook_verification.rb +53 -0
  49. data/lib/sendgrid-ruby.rb +2 -0
  50. data/lib/sendgrid/base_interface.rb +1 -1
  51. data/lib/sendgrid/helpers/eventwebhook/eventwebhook.rb +50 -0
  52. data/lib/sendgrid/helpers/inbound/README.md +5 -5
  53. data/lib/sendgrid/helpers/inbound/app.rb +1 -1
  54. data/lib/sendgrid/helpers/inbound/public/index.html +1 -1
  55. data/lib/sendgrid/helpers/inbound/send.rb +2 -2
  56. data/lib/sendgrid/helpers/ip_management/ip_management.rb +1 -1
  57. data/lib/sendgrid/helpers/mail/README.md +3 -3
  58. data/lib/sendgrid/helpers/mail/asm.rb +6 -18
  59. data/lib/sendgrid/helpers/mail/attachment.rb +12 -42
  60. data/lib/sendgrid/helpers/mail/bcc_settings.rb +6 -18
  61. data/lib/sendgrid/helpers/mail/bypass_list_management.rb +8 -18
  62. data/lib/sendgrid/helpers/mail/category.rb +2 -2
  63. data/lib/sendgrid/helpers/mail/click_tracking.rb +6 -18
  64. data/lib/sendgrid/helpers/mail/content.rb +4 -3
  65. data/lib/sendgrid/helpers/mail/custom_arg.rb +6 -10
  66. data/lib/sendgrid/helpers/mail/email.rb +5 -4
  67. data/lib/sendgrid/helpers/mail/footer.rb +7 -27
  68. data/lib/sendgrid/helpers/mail/ganalytics.rb +10 -54
  69. data/lib/sendgrid/helpers/mail/header.rb +6 -10
  70. data/lib/sendgrid/helpers/mail/mail.rb +30 -48
  71. data/lib/sendgrid/helpers/mail/mail_settings.rb +9 -25
  72. data/lib/sendgrid/helpers/mail/open_tracking.rb +6 -18
  73. data/lib/sendgrid/helpers/mail/personalization.rb +34 -27
  74. data/lib/sendgrid/helpers/mail/section.rb +6 -10
  75. data/lib/sendgrid/helpers/mail/spam_check.rb +7 -27
  76. data/lib/sendgrid/helpers/mail/subscription_tracking.rb +8 -36
  77. data/lib/sendgrid/helpers/mail/substitution.rb +6 -10
  78. data/lib/sendgrid/helpers/mail/tracking_settings.rb +7 -20
  79. data/lib/sendgrid/helpers/permissions/scope.rb +1 -1
  80. data/lib/sendgrid/helpers/settings/README.md +2 -2
  81. data/lib/sendgrid/helpers/settings/settings.rb +1 -1
  82. data/lib/sendgrid/helpers/settings/tracking_settings_dto.rb +3 -5
  83. data/lib/sendgrid/helpers/stats/metrics.rb +5 -5
  84. data/lib/sendgrid/sendgrid.rb +1 -1
  85. data/lib/sendgrid/twilio_email.rb +1 -1
  86. data/lib/sendgrid/version.rb +1 -1
  87. data/mail_helper_v3.md +12 -12
  88. data/sendgrid-ruby.gemspec +8 -7
  89. data/spec/fixtures/event_webhook.rb +22 -0
  90. data/spec/rack/sendgrid_webhook_verification_spec.rb +116 -0
  91. data/spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb +105 -0
  92. data/spec/sendgrid/helpers/settings/mail_settings_dto_spec.rb +1 -1
  93. data/spec/sendgrid/helpers/settings/partner_settings_dto_spec.rb +1 -1
  94. data/spec/sendgrid/helpers/settings/settings_spec.rb +2 -2
  95. data/spec/sendgrid/helpers/settings/tracking_settings_dto_spec.rb +1 -1
  96. data/spec/sendgrid/helpers/settings/user_settings_dto_spec.rb +1 -1
  97. data/spec/sendgrid/helpers/stats/email_stats_spec.rb +22 -23
  98. data/spec/sendgrid/helpers/stats/metrics_spec.rb +19 -20
  99. data/spec/sendgrid/helpers/stats/stats_response_spec.rb +22 -23
  100. data/spec/spec_helper.rb +3 -1
  101. data/static/img/github-fork.png +0 -0
  102. data/static/img/github-sign-up.png +0 -0
  103. data/test/sendgrid/helpers/mail/test_attachment.rb +4 -6
  104. data/test/sendgrid/helpers/mail/test_category.rb +0 -2
  105. data/test/sendgrid/helpers/mail/test_email.rb +9 -11
  106. data/test/sendgrid/helpers/mail/test_mail.rb +101 -102
  107. data/test/sendgrid/helpers/mail/test_personalizations.rb +106 -93
  108. data/test/sendgrid/permissions/test_scopes.rb +0 -2
  109. data/test/sendgrid/test_sendgrid-ruby.rb +1948 -1958
  110. data/twilio_sendgrid_logo.png +0 -0
  111. data/use-cases/README.md +16 -0
  112. data/use-cases/domain-authentication.md +5 -0
  113. data/use-cases/email-statistics.md +52 -0
  114. data/use-cases/legacy-templates.md +98 -0
  115. data/use-cases/sms.md +39 -0
  116. data/use-cases/transactional-templates.md +111 -0
  117. data/use-cases/twilio-email.md +13 -0
  118. data/use-cases/twilio-setup.md +54 -0
  119. metadata +73 -24
  120. data/USE_CASES.md +0 -405
  121. data/docker/Dockerfile +0 -12
  122. data/docker/README.md +0 -30
@@ -1,9 +1,7 @@
1
1
  require 'sendgrid-ruby'
2
2
 
3
-
4
3
  sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
5
4
 
6
-
7
5
  ##################################################
8
6
  # Retrieve Tracking Settings #
9
7
  # GET /tracking_settings #
@@ -30,7 +28,7 @@ puts response.headers
30
28
  # Retrieve Click Track Settings #
31
29
  # GET /tracking_settings/click #
32
30
 
33
- response = sg.client.tracking_settings.click.get()
31
+ response = sg.client.tracking_settings.click.get
34
32
  puts response.status_code
35
33
  puts response.body
36
34
  puts response.headers
@@ -40,11 +38,11 @@ puts response.headers
40
38
  # PATCH /tracking_settings/google_analytics #
41
39
 
42
40
  data = JSON.parse('{
43
- "enabled": true,
44
- "utm_campaign": "website",
45
- "utm_content": "",
46
- "utm_medium": "email",
47
- "utm_source": "sendgrid.com",
41
+ "enabled": true,
42
+ "utm_campaign": "website",
43
+ "utm_content": "",
44
+ "utm_medium": "email",
45
+ "utm_source": "sendgrid.com",
48
46
  "utm_term": ""
49
47
  }')
50
48
  response = sg.client.tracking_settings.google_analytics.patch(request_body: data)
@@ -56,7 +54,7 @@ puts response.headers
56
54
  # Retrieve Google Analytics Settings #
57
55
  # GET /tracking_settings/google_analytics #
58
56
 
59
- response = sg.client.tracking_settings.google_analytics.get()
57
+ response = sg.client.tracking_settings.google_analytics.get
60
58
  puts response.status_code
61
59
  puts response.body
62
60
  puts response.headers
@@ -77,7 +75,7 @@ puts response.headers
77
75
  # Get Open Tracking Settings #
78
76
  # GET /tracking_settings/open #
79
77
 
80
- response = sg.client.tracking_settings.open.get()
78
+ response = sg.client.tracking_settings.open.get
81
79
  puts response.status_code
82
80
  puts response.body
83
81
  puts response.headers
@@ -87,11 +85,11 @@ puts response.headers
87
85
  # PATCH /tracking_settings/subscription #
88
86
 
89
87
  data = JSON.parse('{
90
- "enabled": true,
91
- "html_content": "html content",
92
- "landing": "landing page html",
93
- "plain_content": "text content",
94
- "replace": "replacement tag",
88
+ "enabled": true,
89
+ "html_content": "html content",
90
+ "landing": "landing page html",
91
+ "plain_content": "text content",
92
+ "replace": "replacement tag",
95
93
  "url": "url"
96
94
  }')
97
95
  response = sg.client.tracking_settings.subscription.patch(request_body: data)
@@ -103,8 +101,7 @@ puts response.headers
103
101
  # Retrieve Subscription Tracking Settings #
104
102
  # GET /tracking_settings/subscription #
105
103
 
106
- response = sg.client.tracking_settings.subscription.get()
104
+ response = sg.client.tracking_settings.subscription.get
107
105
  puts response.status_code
108
106
  puts response.body
109
107
  puts response.headers
110
-
@@ -1,14 +1,12 @@
1
1
  require 'sendgrid-ruby'
2
2
 
3
-
4
3
  sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
5
4
 
6
-
7
5
  ##################################################
8
6
  # Get a user's account information. #
9
7
  # GET /user/account #
10
8
 
11
- response = sg.client.user.account.get()
9
+ response = sg.client.user.account.get
12
10
  puts response.status_code
13
11
  puts response.body
14
12
  puts response.headers
@@ -17,7 +15,7 @@ puts response.headers
17
15
  # Retrieve your credit balance #
18
16
  # GET /user/credits #
19
17
 
20
- response = sg.client.user.credits.get()
18
+ response = sg.client.user.credits.get
21
19
  puts response.status_code
22
20
  puts response.body
23
21
  puts response.headers
@@ -38,7 +36,7 @@ puts response.headers
38
36
  # Retrieve your account email address #
39
37
  # GET /user/email #
40
38
 
41
- response = sg.client.user.email.get()
39
+ response = sg.client.user.email.get
42
40
  puts response.status_code
43
41
  puts response.body
44
42
  puts response.headers
@@ -48,7 +46,7 @@ puts response.headers
48
46
  # PUT /user/password #
49
47
 
50
48
  data = JSON.parse('{
51
- "new_password": "new_password",
49
+ "new_password": "new_password",
52
50
  "old_password": "old_password"
53
51
  }')
54
52
  response = sg.client.user.password.put(request_body: data)
@@ -61,8 +59,8 @@ puts response.headers
61
59
  # PATCH /user/profile #
62
60
 
63
61
  data = JSON.parse('{
64
- "city": "Orange",
65
- "first_name": "Example",
62
+ "city": "Orange",
63
+ "first_name": "Example",
66
64
  "last_name": "User"
67
65
  }')
68
66
  response = sg.client.user.profile.patch(request_body: data)
@@ -74,7 +72,7 @@ puts response.headers
74
72
  # Get a user's profile #
75
73
  # GET /user/profile #
76
74
 
77
- response = sg.client.user.profile.get()
75
+ response = sg.client.user.profile.get
78
76
  puts response.status_code
79
77
  puts response.body
80
78
  puts response.headers
@@ -84,7 +82,7 @@ puts response.headers
84
82
  # POST /user/scheduled_sends #
85
83
 
86
84
  data = JSON.parse('{
87
- "batch_id": "YOUR_BATCH_ID",
85
+ "batch_id": "YOUR_BATCH_ID",
88
86
  "status": "pause"
89
87
  }')
90
88
  response = sg.client.user.scheduled_sends.post(request_body: data)
@@ -96,7 +94,7 @@ puts response.headers
96
94
  # Retrieve all scheduled sends #
97
95
  # GET /user/scheduled_sends #
98
96
 
99
- response = sg.client.user.scheduled_sends.get()
97
+ response = sg.client.user.scheduled_sends.get
100
98
  puts response.status_code
101
99
  puts response.body
102
100
  puts response.headers
@@ -108,7 +106,7 @@ puts response.headers
108
106
  data = JSON.parse('{
109
107
  "status": "pause"
110
108
  }')
111
- batch_id = "test_url_param"
109
+ batch_id = 'test_url_param'
112
110
  response = sg.client.user.scheduled_sends._(batch_id).patch(request_body: data)
113
111
  puts response.status_code
114
112
  puts response.body
@@ -118,8 +116,8 @@ puts response.headers
118
116
  # Retrieve scheduled send #
119
117
  # GET /user/scheduled_sends/{batch_id} #
120
118
 
121
- batch_id = "test_url_param"
122
- response = sg.client.user.scheduled_sends._(batch_id).get()
119
+ batch_id = 'test_url_param'
120
+ response = sg.client.user.scheduled_sends._(batch_id).get
123
121
  puts response.status_code
124
122
  puts response.body
125
123
  puts response.headers
@@ -128,8 +126,8 @@ puts response.headers
128
126
  # Delete a cancellation or pause of a scheduled send #
129
127
  # DELETE /user/scheduled_sends/{batch_id} #
130
128
 
131
- batch_id = "test_url_param"
132
- response = sg.client.user.scheduled_sends._(batch_id).delete()
129
+ batch_id = 'test_url_param'
130
+ response = sg.client.user.scheduled_sends._(batch_id).delete
133
131
  puts response.status_code
134
132
  puts response.body
135
133
  puts response.headers
@@ -139,7 +137,7 @@ puts response.headers
139
137
  # PATCH /user/settings/enforced_tls #
140
138
 
141
139
  data = JSON.parse('{
142
- "require_tls": true,
140
+ "require_tls": true,
143
141
  "require_valid_cert": false
144
142
  }')
145
143
  response = sg.client.user.settings.enforced_tls.patch(request_body: data)
@@ -151,7 +149,7 @@ puts response.headers
151
149
  # Retrieve current Enforced TLS settings. #
152
150
  # GET /user/settings/enforced_tls #
153
151
 
154
- response = sg.client.user.settings.enforced_tls.get()
152
+ response = sg.client.user.settings.enforced_tls.get
155
153
  puts response.status_code
156
154
  puts response.body
157
155
  puts response.headers
@@ -172,7 +170,7 @@ puts response.headers
172
170
  # Retrieve your username #
173
171
  # GET /user/username #
174
172
 
175
- response = sg.client.user.username.get()
173
+ response = sg.client.user.username.get
176
174
  puts response.status_code
177
175
  puts response.body
178
176
  puts response.headers
@@ -182,18 +180,18 @@ puts response.headers
182
180
  # PATCH /user/webhooks/event/settings #
183
181
 
184
182
  data = JSON.parse('{
185
- "bounce": true,
186
- "click": true,
187
- "deferred": true,
188
- "delivered": true,
189
- "dropped": true,
190
- "enabled": true,
191
- "group_resubscribe": true,
192
- "group_unsubscribe": true,
193
- "open": true,
194
- "processed": true,
195
- "spam_report": true,
196
- "unsubscribe": true,
183
+ "bounce": true,
184
+ "click": true,
185
+ "deferred": true,
186
+ "delivered": true,
187
+ "dropped": true,
188
+ "enabled": true,
189
+ "group_resubscribe": true,
190
+ "group_unsubscribe": true,
191
+ "open": true,
192
+ "processed": true,
193
+ "spam_report": true,
194
+ "unsubscribe": true,
197
195
  "url": "url"
198
196
  }')
199
197
  response = sg.client.user.webhooks.event.settings.patch(request_body: data)
@@ -205,7 +203,7 @@ puts response.headers
205
203
  # Retrieve Event Webhook settings #
206
204
  # GET /user/webhooks/event/settings #
207
205
 
208
- response = sg.client.user.webhooks.event.settings.get()
206
+ response = sg.client.user.webhooks.event.settings.get
209
207
  puts response.status_code
210
208
  puts response.body
211
209
  puts response.headers
@@ -227,9 +225,9 @@ puts response.headers
227
225
  # POST /user/webhooks/parse/settings #
228
226
 
229
227
  data = JSON.parse('{
230
- "hostname": "myhostname.com",
231
- "send_raw": false,
232
- "spam_check": true,
228
+ "hostname": "myhostname.com",
229
+ "send_raw": false,
230
+ "spam_check": true,
233
231
  "url": "http://email.myhosthame.com"
234
232
  }')
235
233
  response = sg.client.user.webhooks.parse.settings.post(request_body: data)
@@ -241,7 +239,7 @@ puts response.headers
241
239
  # Retrieve all parse settings #
242
240
  # GET /user/webhooks/parse/settings #
243
241
 
244
- response = sg.client.user.webhooks.parse.settings.get()
242
+ response = sg.client.user.webhooks.parse.settings.get
245
243
  puts response.status_code
246
244
  puts response.body
247
245
  puts response.headers
@@ -251,11 +249,11 @@ puts response.headers
251
249
  # PATCH /user/webhooks/parse/settings/{hostname} #
252
250
 
253
251
  data = JSON.parse('{
254
- "send_raw": true,
255
- "spam_check": false,
252
+ "send_raw": true,
253
+ "spam_check": false,
256
254
  "url": "http://newdomain.com/parse"
257
255
  }')
258
- hostname = "test_url_param"
256
+ hostname = 'test_url_param'
259
257
  response = sg.client.user.webhooks.parse.settings._(hostname).patch(request_body: data)
260
258
  puts response.status_code
261
259
  puts response.body
@@ -265,8 +263,8 @@ puts response.headers
265
263
  # Retrieve a specific parse setting #
266
264
  # GET /user/webhooks/parse/settings/{hostname} #
267
265
 
268
- hostname = "test_url_param"
269
- response = sg.client.user.webhooks.parse.settings._(hostname).get()
266
+ hostname = 'test_url_param'
267
+ response = sg.client.user.webhooks.parse.settings._(hostname).get
270
268
  puts response.status_code
271
269
  puts response.body
272
270
  puts response.headers
@@ -275,8 +273,8 @@ puts response.headers
275
273
  # Delete a parse setting #
276
274
  # DELETE /user/webhooks/parse/settings/{hostname} #
277
275
 
278
- hostname = "test_url_param"
279
- response = sg.client.user.webhooks.parse.settings._(hostname).delete()
276
+ hostname = 'test_url_param'
277
+ response = sg.client.user.webhooks.parse.settings._(hostname).delete
280
278
  puts response.status_code
281
279
  puts response.body
282
280
  puts response.headers
@@ -290,4 +288,3 @@ response = sg.client.user.webhooks.parse.stats.get(query_params: params)
290
288
  puts response.status_code
291
289
  puts response.body
292
290
  puts response.headers
293
-
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rack
4
+ # Middleware that verifies webhooks from SendGrid using the EventWebhook
5
+ # verifier.
6
+ #
7
+ # The middleware takes a public key with which to set up the request
8
+ # validator and any number of paths. When a path matches the incoming request
9
+ # path, the request will be verified using the signature and timestamp of the
10
+ # request.
11
+ #
12
+ # Example:
13
+ #
14
+ # require 'rack'
15
+ # use Rack::SendGridWebhookVerification, ENV['PUBLIC_KEY'], /\/emails/
16
+ #
17
+ # The above appends this middleware to the stack, using a public key saved in
18
+ # the ENV and only against paths that match /\/emails/. If the request
19
+ # validates then it gets passed on to the action as normal. If the request
20
+ # doesn't validate then the middleware responds immediately with a 403 status.
21
+ class SendGridWebhookVerification
22
+ def initialize(app, public_key, *paths)
23
+ @app = app
24
+ @public_key = public_key
25
+ @path_regex = Regexp.union(paths)
26
+ end
27
+
28
+ def call(env)
29
+ return @app.call(env) unless env['PATH_INFO'].match(@path_regex)
30
+
31
+ request = Rack::Request.new(env)
32
+
33
+ event_webhook = SendGrid::EventWebhook.new
34
+ ec_public_key = event_webhook.convert_public_key_to_ecdsa(@public_key)
35
+ verified = event_webhook.verify_signature(
36
+ ec_public_key,
37
+ request.body.read,
38
+ request.env[SendGrid::EventWebhookHeader::SIGNATURE],
39
+ request.env[SendGrid::EventWebhookHeader::TIMESTAMP]
40
+ )
41
+
42
+ if verified
43
+ @app.call(env)
44
+ else
45
+ [
46
+ 403,
47
+ { 'Content-Type' => 'text/plain' },
48
+ ['SendGrid Request Verification Failed.']
49
+ ]
50
+ end
51
+ end
52
+ end
53
+ end
@@ -2,6 +2,7 @@ require_relative 'sendgrid/base_interface'
2
2
  require_relative 'sendgrid/sendgrid'
3
3
  require_relative 'sendgrid/twilio_email'
4
4
  require_relative 'sendgrid/version'
5
+ require_relative 'sendgrid/helpers/eventwebhook/eventwebhook'
5
6
  require_relative 'sendgrid/helpers/ip_management/ip_management'
6
7
  require_relative 'sendgrid/helpers/mail/asm'
7
8
  require_relative 'sendgrid/helpers/mail/attachment'
@@ -29,3 +30,4 @@ require_relative 'sendgrid/helpers/stats/email_stats'
29
30
  require_relative 'sendgrid/helpers/stats/stats_response'
30
31
  require_relative 'sendgrid/helpers/stats/metrics'
31
32
  require_relative 'sendgrid/helpers/permissions/scope'
33
+ require_relative 'rack/sendgrid_webhook_verification'
@@ -17,7 +17,7 @@ class BaseInterface
17
17
  def initialize(auth:, host:, request_headers: nil, version: nil, impersonate_subuser: nil)
18
18
  @auth = auth
19
19
  @host = host
20
- @version = version ? version : 'v3'
20
+ @version = version || 'v3'
21
21
  @impersonate_subuser = impersonate_subuser
22
22
  @user_agent = "sendgrid/#{SendGrid::VERSION};ruby"
23
23
  @request_headers = JSON.parse('
@@ -0,0 +1,50 @@
1
+ require 'base64'
2
+ require 'digest'
3
+ require 'openssl'
4
+
5
+ module SendGrid
6
+ # This class allows you to use the Event Webhook feature. Read the docs for
7
+ # more details: https://sendgrid.com/docs/for-developers/tracking-events/event
8
+ class EventWebhook
9
+ # * *Args* :
10
+ # - +public_key+ -> verification key under Mail Settings
11
+ #
12
+ def convert_public_key_to_ecdsa(public_key)
13
+ verify_engine
14
+ OpenSSL::PKey::EC.new(Base64.decode64(public_key))
15
+ end
16
+
17
+ # * *Args* :
18
+ # - +public_key+ -> elliptic curve public key
19
+ # - +payload+ -> event payload in the request body
20
+ # - +signature+ -> signature value obtained from the 'X-Twilio-Email-Event-Webhook-Signature' header
21
+ # - +timestamp+ -> timestamp value obtained from the 'X-Twilio-Email-Event-Webhook-Timestamp' header
22
+ def verify_signature(public_key, payload, signature, timestamp)
23
+ verify_engine
24
+ timestamped_playload = "#{timestamp}#{payload}"
25
+ payload_digest = Digest::SHA256.digest(timestamped_playload)
26
+ decoded_signature = Base64.decode64(signature)
27
+ public_key.dsa_verify_asn1(payload_digest, decoded_signature)
28
+ rescue StandardError
29
+ false
30
+ end
31
+
32
+ def verify_engine
33
+ # JRuby does not fully support ECDSA: https://github.com/jruby/jruby-openssl/issues/193
34
+ raise NotSupportedError, "Event Webhook verification is not supported by JRuby" if RUBY_PLATFORM == "java"
35
+ end
36
+
37
+ class Error < ::RuntimeError
38
+ end
39
+
40
+ class NotSupportedError < Error
41
+ end
42
+ end
43
+
44
+ # This class lists headers that get posted to the webhook. Read the docs for
45
+ # more details: https://sendgrid.com/docs/for-developers/tracking-events/event
46
+ class EventWebhookHeader
47
+ SIGNATURE = "HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE".freeze
48
+ TIMESTAMP = "HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP".freeze
49
+ end
50
+ end
@@ -17,7 +17,7 @@
17
17
  # Installation
18
18
 
19
19
  In addition to the installation instructions in
20
- [the main readme](https://github.com/sendgrid/sendgrid-ruby/tree/master/#installation),
20
+ [the main readme](../../../../README.md#installation),
21
21
  you must also add sinatra to your Gemfile:
22
22
 
23
23
  ```
@@ -47,7 +47,7 @@ bundle install
47
47
  ruby ./lib/sendgrid/helpers/inbound/send.rb ./lib/sendgrid/helpers/inbound/sample_data/default_data.txt
48
48
  ```
49
49
 
50
- More sample data can be found [here](https://github.com/sendgrid/sendgrid-ruby/tree/master/lib/sendgrid/helpers/inbound/sample_data).
50
+ More sample data can be found [here](sample_data).
51
51
 
52
52
  View the results in the first terminal.
53
53
 
@@ -82,11 +82,11 @@ Next, send an email to [anything]@inbound.yourdomain.com, then look at the termi
82
82
 
83
83
  ## app.rb
84
84
 
85
- This module runs a [Sinatra](http://www.sinatrarb.com/) server, that by default (you can change those settings [here](https://github.com/sendgrid/sendgrid-ruby/blob/master/sendgrid/helpers/inbound/config.yml)), listens for POSTs on http://localhost:9292. When the server receives the POST, it parses and prints the key/value data.
85
+ This module runs a [Sinatra](http://www.sinatrarb.com/) server, that by default (you can change those settings [here](config.yml)), listens for POSTs on http://localhost:9292. When the server receives the POST, it parses and prints the key/value data.
86
86
 
87
87
  ## config.yml
88
88
 
89
- This module loads application environment variables (located in [config.yml](https://github.com/sendgrid/sendgrid-ruby/blob/master/sendgrid/helpers/inbound/config.yml)).
89
+ This module loads application environment variables (located in [config.yml](config.yml)).
90
90
 
91
91
  ## send.rb & /sample_data
92
92
 
@@ -95,4 +95,4 @@ This module is used to send sample test data. It is useful for testing and devel
95
95
  <a name="contributing"></a>
96
96
  # Contributing
97
97
 
98
- If you would like to contribute to this project, please see our [contributing guide](https://github.com/sendgrid/sendgrid-ruby/blob/master/CONTRIBUTING.md). Thanks!
98
+ If you would like to contribute to this project, please see our [contributing guide](../../../../CONTRIBUTING.md). Thanks!