sendgrid-ruby 5.3.0 → 6.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/pr-lint.yml +15 -0
- data/.github/workflows/test-and-deploy.yml +120 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +127 -0
- data/CHANGELOG.md +261 -8
- data/CODE_OF_CONDUCT.md +57 -25
- data/CONTRIBUTING.md +24 -71
- data/Dockerfile +14 -0
- data/FIRST_TIMERS.md +53 -0
- data/Gemfile +0 -1
- data/LICENSE +21 -0
- data/Makefile +14 -0
- data/PULL_REQUEST_TEMPLATE.md +31 -0
- data/README.md +39 -43
- data/Rakefile +3 -4
- data/TROUBLESHOOTING.md +41 -21
- data/UPGRADE.md +5 -0
- data/USAGE.md +1231 -1122
- data/examples/accesssettings/accesssettings.rb +9 -12
- data/examples/alerts/alerts.rb +8 -11
- data/examples/apikeys/apikeys.rb +12 -15
- data/examples/asm/asm.rb +27 -30
- data/examples/browsers/browsers.rb +0 -3
- data/examples/campaigns/campaigns.rb +29 -32
- data/examples/categories/categories.rb +0 -3
- data/examples/clients/clients.rb +1 -4
- data/examples/contactdb/contactdb.rb +63 -66
- data/examples/dataresidency/setregion.rb +48 -0
- data/examples/devices/devices.rb +0 -3
- data/examples/emailactivity/emailactivity.rb +52 -0
- data/examples/geo/geo.rb +0 -3
- data/examples/helpers/eventwebhook/example.rb +16 -0
- data/examples/helpers/mail/example.rb +30 -19
- data/examples/helpers/settings/example.rb +1 -1
- data/examples/helpers/stats/example.rb +4 -4
- data/examples/ips/ips.rb +31 -21
- data/examples/mail/mail.rb +73 -76
- data/examples/mailboxproviders/mailboxproviders.rb +0 -3
- data/examples/mailsettings/mailsettings.rb +21 -24
- data/examples/partnersettings/partnersettings.rb +3 -6
- data/examples/scopes/scopes.rb +49 -5
- data/examples/{whitelabel/whitelabel.rb → senderauthentication/senderauthentication.rb} +68 -71
- data/examples/senders/senders.rb +28 -31
- data/examples/stats/stats.rb +0 -3
- data/examples/subusers/subusers.rb +17 -20
- data/examples/suppression/suppression.rb +23 -26
- data/examples/templates/templates.rb +29 -31
- data/examples/trackingsettings/trackingsettings.rb +14 -17
- data/examples/user/user.rb +41 -44
- data/lib/rack/sendgrid_webhook_verification.rb +55 -0
- data/lib/sendgrid/base_interface.rb +57 -0
- data/lib/sendgrid/helpers/eventwebhook/eventwebhook.rb +50 -0
- data/lib/sendgrid/helpers/inbound/README.md +26 -9
- data/lib/sendgrid/helpers/inbound/app.rb +15 -3
- data/lib/sendgrid/helpers/inbound/public/index.html +2 -2
- data/lib/sendgrid/helpers/inbound/sample_data/default_data.txt +2 -2
- data/lib/sendgrid/helpers/inbound/sample_data/raw_data.txt +2 -2
- data/lib/sendgrid/helpers/inbound/sample_data/raw_data_with_attachments.txt +2 -2
- data/lib/sendgrid/helpers/inbound/send.rb +5 -5
- data/lib/sendgrid/helpers/ip_management/ip_management.rb +17 -0
- data/lib/sendgrid/helpers/mail/README.md +4 -4
- data/lib/sendgrid/helpers/mail/asm.rb +4 -18
- data/lib/sendgrid/helpers/mail/attachment.rb +30 -38
- data/lib/sendgrid/helpers/mail/bcc_settings.rb +4 -18
- data/lib/sendgrid/helpers/mail/bypass_list_management.rb +6 -18
- data/lib/sendgrid/helpers/mail/category.rb +2 -12
- data/lib/sendgrid/helpers/mail/click_tracking.rb +4 -18
- data/lib/sendgrid/helpers/mail/content.rb +4 -18
- data/lib/sendgrid/helpers/mail/custom_arg.rb +4 -10
- data/lib/sendgrid/helpers/mail/email.rb +10 -20
- data/lib/sendgrid/helpers/mail/footer.rb +5 -27
- data/lib/sendgrid/helpers/mail/ganalytics.rb +9 -55
- data/lib/sendgrid/helpers/mail/header.rb +4 -10
- data/lib/sendgrid/helpers/mail/mail.rb +37 -87
- data/lib/sendgrid/helpers/mail/mail_settings.rb +7 -25
- data/lib/sendgrid/helpers/mail/open_tracking.rb +4 -18
- data/lib/sendgrid/helpers/mail/personalization.rb +38 -27
- data/lib/sendgrid/helpers/mail/section.rb +4 -10
- data/lib/sendgrid/helpers/mail/spam_check.rb +5 -27
- data/lib/sendgrid/helpers/mail/subscription_tracking.rb +6 -36
- data/lib/sendgrid/helpers/mail/substitution.rb +4 -10
- data/lib/sendgrid/helpers/mail/tracking_settings.rb +6 -20
- data/lib/sendgrid/helpers/permissions/scope.rb +28 -0
- data/lib/sendgrid/helpers/permissions/scopes.yml +309 -0
- data/lib/sendgrid/helpers/settings/README.md +3 -3
- data/lib/sendgrid/helpers/settings/settings.rb +1 -1
- data/lib/sendgrid/helpers/settings/tracking_settings_dto.rb +3 -5
- data/lib/sendgrid/helpers/stats/metrics.rb +5 -7
- data/lib/sendgrid/helpers/stats/stats_response.rb +1 -3
- data/lib/sendgrid/sendgrid.rb +21 -0
- data/lib/sendgrid/twilio_email.rb +21 -0
- data/lib/sendgrid/version.rb +1 -1
- data/lib/sendgrid-ruby.rb +7 -1
- data/mail_helper_v3.md +21 -21
- data/sendgrid-ruby.gemspec +12 -12
- data/spec/fixtures/event_webhook.rb +22 -0
- data/spec/rack/sendgrid_webhook_verification_spec.rb +142 -0
- data/spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb +105 -0
- data/spec/sendgrid/helpers/ip_management/ip_management_spec.rb +12 -0
- data/spec/sendgrid/helpers/settings/mail_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/settings/partner_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/settings/settings_spec.rb +2 -2
- data/spec/sendgrid/helpers/settings/tracking_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/settings/user_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/stats/email_stats_spec.rb +22 -23
- data/spec/sendgrid/helpers/stats/metrics_spec.rb +19 -20
- data/spec/sendgrid/helpers/stats/stats_response_spec.rb +22 -23
- data/spec/sendgrid/sendgrid_spec.rb +11 -0
- data/spec/sendgrid/twilio_email_spec.rb +11 -0
- data/spec/spec_helper.rb +3 -1
- data/static/img/github-fork.png +0 -0
- data/static/img/github-sign-up.png +0 -0
- data/test/sendgrid/helpers/mail/test_attachment.rb +33 -0
- data/test/sendgrid/helpers/mail/test_category.rb +0 -2
- data/test/sendgrid/helpers/mail/test_data_residency.rb +44 -0
- data/test/sendgrid/helpers/mail/test_email.rb +17 -10
- data/test/sendgrid/helpers/mail/test_mail.rb +126 -119
- data/test/sendgrid/helpers/mail/test_personalizations.rb +145 -92
- data/test/sendgrid/permissions/test_scopes.rb +36 -0
- data/test/sendgrid/test_sendgrid-ruby.rb +1961 -1979
- data/twilio_sendgrid_logo.png +0 -0
- data/use-cases/README.md +17 -0
- data/use-cases/domain-authentication.md +5 -0
- data/use-cases/email-statistics.md +52 -0
- data/use-cases/legacy-templates.md +98 -0
- data/use-cases/personalizations.md +34 -0
- data/use-cases/sms.md +39 -0
- data/use-cases/transactional-templates.md +111 -0
- data/use-cases/twilio-email.md +13 -0
- data/use-cases/twilio-setup.md +54 -0
- metadata +99 -45
- data/.codeclimate.yml +0 -21
- data/.github/ISSUE_TEMPLATE +0 -17
- data/.github/PULL_REQUEST_TEMPLATE +0 -24
- data/.travis.yml +0 -29
- data/LICENSE.txt +0 -22
- data/USE_CASES.md +0 -147
- data/docker/Dockerfile +0 -12
- data/docker/README.md +0 -30
- data/lib/sendgrid/client.rb +0 -35
- data/test/prism.sh +0 -42
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'ruby_http_client'
|
|
2
|
+
require_relative 'version'
|
|
3
|
+
|
|
4
|
+
# Initialize the HTTP client
|
|
5
|
+
class BaseInterface
|
|
6
|
+
attr_accessor :client
|
|
7
|
+
attr_reader :request_headers, :host, :version, :impersonate_subuser, :http_options
|
|
8
|
+
|
|
9
|
+
# * *Args* :
|
|
10
|
+
# - +auth+ -> authorization header value
|
|
11
|
+
# - +host+ -> the base URL for the API
|
|
12
|
+
# - +request_headers+ -> any headers that you want to be globally applied
|
|
13
|
+
# - +version+ -> the version of the API you wish to access,
|
|
14
|
+
# currently only "v3" is supported
|
|
15
|
+
# - +impersonate_subuser+ -> the subuser to impersonate, will be passed
|
|
16
|
+
# in the "On-Behalf-Of" header
|
|
17
|
+
# - +http_options+ -> http options that you want to be globally applied to each request
|
|
18
|
+
#
|
|
19
|
+
def initialize(auth:, host:, request_headers: nil, version: nil, impersonate_subuser: nil, http_options: {})
|
|
20
|
+
@auth = auth
|
|
21
|
+
@host = host
|
|
22
|
+
@version = version || 'v3'
|
|
23
|
+
@impersonate_subuser = impersonate_subuser
|
|
24
|
+
@user_agent = "sendgrid/#{SendGrid::VERSION};ruby"
|
|
25
|
+
@request_headers = JSON.parse('
|
|
26
|
+
{
|
|
27
|
+
"Authorization": "' + @auth + '",
|
|
28
|
+
"Accept": "application/json",
|
|
29
|
+
"User-Agent": "' + @user_agent + '"
|
|
30
|
+
}
|
|
31
|
+
')
|
|
32
|
+
@request_headers['On-Behalf-Of'] = @impersonate_subuser if @impersonate_subuser
|
|
33
|
+
|
|
34
|
+
@request_headers = @request_headers.merge(request_headers) if request_headers
|
|
35
|
+
@http_options = http_options
|
|
36
|
+
@client = SendGrid::Client.new(host: "#{@host}/#{@version}",
|
|
37
|
+
request_headers: @request_headers,
|
|
38
|
+
http_options: @http_options)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Client libraries contain setters for specifying region/edge.
|
|
42
|
+
# This supports global and eu regions only. This set will likely expand in the future.
|
|
43
|
+
# Global is the default residency (or region)
|
|
44
|
+
# Global region means the message will be sent through https://api.sendgrid.com
|
|
45
|
+
# EU region means the message will be sent through https://api.eu.sendgrid.com
|
|
46
|
+
# Parameters:
|
|
47
|
+
# - region(String) : specify the region. Currently supports "global" and "eu"
|
|
48
|
+
def sendgrid_data_residency(region:)
|
|
49
|
+
region_host_dict = { "eu" => 'https://api.eu.sendgrid.com', "global" => 'https://api.sendgrid.com' }
|
|
50
|
+
raise ArgumentError, "region can only be \"eu\" or \"global\"" if region.nil? || !region_host_dict.key?(region)
|
|
51
|
+
|
|
52
|
+
@host = region_host_dict[region]
|
|
53
|
+
@client = SendGrid::Client.new(host: "#{@host}/#{@version}",
|
|
54
|
+
request_headers: @request_headers,
|
|
55
|
+
http_options: @http_options)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -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
|
|
@@ -2,12 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
## Table of Contents
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
- [Installation](#installation)
|
|
6
|
+
- [Quick Start for Local Testing with Sample Data](#quick-start-for-local-testing-with-sample-data)
|
|
7
|
+
- [Quick Start for Local Testing with Real Data](#quick-start-for-local-testing-with-real-data)
|
|
8
|
+
- [Code Walkthrough](#code-walkthrough)
|
|
9
|
+
- [app.rb](#apprb)
|
|
10
|
+
- [config.yml](#configyml)
|
|
11
|
+
- [send.rb & /sample_data](#sendrb--sampledata)
|
|
12
|
+
- [Contributing](#contributing)
|
|
9
13
|
|
|
10
14
|
<a name="quick_start_local_sample"></a>
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Installation
|
|
18
|
+
|
|
19
|
+
In addition to the installation instructions in
|
|
20
|
+
[the main readme](../../../../README.md#installation),
|
|
21
|
+
you must also add sinatra to your Gemfile:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
gem 'sinatra', '>= 1.4.7', '< 3'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
|
|
11
28
|
# Quick Start for Local Testing with Sample Data
|
|
12
29
|
|
|
13
30
|
```bash
|
|
@@ -30,7 +47,7 @@ bundle install
|
|
|
30
47
|
ruby ./lib/sendgrid/helpers/inbound/send.rb ./lib/sendgrid/helpers/inbound/sample_data/default_data.txt
|
|
31
48
|
```
|
|
32
49
|
|
|
33
|
-
More sample data can be found [here](
|
|
50
|
+
More sample data can be found [here](sample_data).
|
|
34
51
|
|
|
35
52
|
View the results in the first terminal.
|
|
36
53
|
|
|
@@ -53,7 +70,7 @@ In another terminal, use [ngrok](https://ngrok.com/) to allow external access to
|
|
|
53
70
|
ngrok http 9292
|
|
54
71
|
```
|
|
55
72
|
|
|
56
|
-
Update your SendGrid Incoming Parse settings: [Settings Page](https://app.sendgrid.com/settings/parse) | [Docs](https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_parse_webhook.html#-Pointing-to-a-Hostname-and-URL)
|
|
73
|
+
Update your Twilio SendGrid Incoming Parse settings: [Settings Page](https://app.sendgrid.com/settings/parse) | [Docs](https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_parse_webhook.html#-Pointing-to-a-Hostname-and-URL)
|
|
57
74
|
|
|
58
75
|
- For the HOSTNAME field, use the domain that you changed the MX records (e.g. inbound.yourdomain.com)
|
|
59
76
|
- For the URL field, use the URL generated by ngrok + /inbound, e.g http://XXXXXXX.ngrok.io/inbound
|
|
@@ -65,11 +82,11 @@ Next, send an email to [anything]@inbound.yourdomain.com, then look at the termi
|
|
|
65
82
|
|
|
66
83
|
## app.rb
|
|
67
84
|
|
|
68
|
-
This module runs a [Sinatra](http://www.sinatrarb.com/) server, that by default (you can change those settings [here](
|
|
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.
|
|
69
86
|
|
|
70
87
|
## config.yml
|
|
71
88
|
|
|
72
|
-
This module loads application environment variables (located in [config.yml](
|
|
89
|
+
This module loads application environment variables (located in [config.yml](config.yml)).
|
|
73
90
|
|
|
74
91
|
## send.rb & /sample_data
|
|
75
92
|
|
|
@@ -78,4 +95,4 @@ This module is used to send sample test data. It is useful for testing and devel
|
|
|
78
95
|
<a name="contributing"></a>
|
|
79
96
|
# Contributing
|
|
80
97
|
|
|
81
|
-
If you would like to contribute to this project, please see our [contributing guide](
|
|
98
|
+
If you would like to contribute to this project, please see our [contributing guide](../../../../CONTRIBUTING.md). Thanks!
|
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
begin
|
|
2
|
+
require 'sinatra'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts <<-NOTE
|
|
5
|
+
As of sengrid verison 6, sinatra is no longer specified as a dependency of
|
|
6
|
+
the sendgrid gem. All the functionality of the inbound server is still the same
|
|
7
|
+
and fully supported, but you just need to include the sinatra dependency in your gemfile
|
|
8
|
+
yourself, like so:
|
|
9
|
+
|
|
10
|
+
gem 'sinatra', '>= 1.4.7', '< 3'
|
|
11
|
+
NOTE
|
|
12
|
+
raise
|
|
13
|
+
end
|
|
2
14
|
require 'logger'
|
|
3
15
|
require 'json'
|
|
4
16
|
require 'yaml'
|
|
@@ -6,7 +18,7 @@ require 'yaml'
|
|
|
6
18
|
class Main < Sinatra::Base
|
|
7
19
|
configure :production, :development do
|
|
8
20
|
enable :logging
|
|
9
|
-
set :config, YAML.load_file(File.dirname(__FILE__)
|
|
21
|
+
set :config, YAML.load_file("#{File.dirname(__FILE__)}/config.yml")
|
|
10
22
|
end
|
|
11
23
|
|
|
12
24
|
get '/' do
|
|
@@ -14,7 +26,7 @@ class Main < Sinatra::Base
|
|
|
14
26
|
end
|
|
15
27
|
|
|
16
28
|
post settings.config['endpoint'] do
|
|
17
|
-
filtered = params.select {|k,
|
|
29
|
+
filtered = params.select { |k, _v| settings.config['keys'].include?(k) }
|
|
18
30
|
logger.info JSON.pretty_generate(filtered)
|
|
19
31
|
end
|
|
20
32
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<html>
|
|
2
2
|
<head>
|
|
3
|
-
<title>SendGrid Incoming Parse</title>
|
|
3
|
+
<title>Twilio SendGrid Incoming Parse</title>
|
|
4
4
|
</head>
|
|
5
5
|
<body>
|
|
6
6
|
<h1>You have successfuly launched the server!</h1>
|
|
7
7
|
|
|
8
|
-
Check out <a href="https://github.com/sendgrid/sendgrid-ruby/tree/
|
|
8
|
+
Check out <a href="https://github.com/sendgrid/sendgrid-ruby/tree/HEAD/sendgrid/helpers/inbound">the documentation</a> on how to use this software to utilize the SendGrid Inbound Parse webhook.
|
|
9
9
|
</body>
|
|
10
10
|
</html>
|
|
@@ -20,7 +20,7 @@ inbound@inbound.example.com
|
|
|
20
20
|
--xYzZY
|
|
21
21
|
Content-Disposition: form-data; name="html"
|
|
22
22
|
|
|
23
|
-
<html><body><strong>Hello SendGrid!</body></html>
|
|
23
|
+
<html><body><strong>Hello Twilio SendGrid!</body></html>
|
|
24
24
|
|
|
25
25
|
--xYzZY
|
|
26
26
|
Content-Disposition: form-data; name="from"
|
|
@@ -29,7 +29,7 @@ Example User <test@example.com>
|
|
|
29
29
|
--xYzZY
|
|
30
30
|
Content-Disposition: form-data; name="text"
|
|
31
31
|
|
|
32
|
-
Hello SendGrid!
|
|
32
|
+
Hello Twilio SendGrid!
|
|
33
33
|
|
|
34
34
|
--xYzZY
|
|
35
35
|
Content-Disposition: form-data; name="sender_ip"
|
|
@@ -16,13 +16,13 @@ Content-Type: multipart/alternative; boundary=001a113ee97c89842f0539be8e7a
|
|
|
16
16
|
--001a113ee97c89842f0539be8e7a
|
|
17
17
|
Content-Type: text/plain; charset=UTF-8
|
|
18
18
|
|
|
19
|
-
Hello SendGrid!
|
|
19
|
+
Hello Twilio SendGrid!
|
|
20
20
|
|
|
21
21
|
--001a113ee97c89842f0539be8e7a
|
|
22
22
|
Content-Type: text/html; charset=UTF-8
|
|
23
23
|
Content-Transfer-Encoding: quoted-printable
|
|
24
24
|
|
|
25
|
-
<html><body><strong>Hello SendGrid!</body></html>
|
|
25
|
+
<html><body><strong>Hello Twilio SendGrid!</body></html>
|
|
26
26
|
|
|
27
27
|
--001a113ee97c89842f0539be8e7a--
|
|
28
28
|
|
|
@@ -19,13 +19,13 @@ Content-Type: multipart/alternative; boundary=001a1140ffb6f4fc5f053a2257e0
|
|
|
19
19
|
--001a1140ffb6f4fc5f053a2257e0
|
|
20
20
|
Content-Type: text/plain; charset=UTF-8
|
|
21
21
|
|
|
22
|
-
Hello SendGrid!
|
|
22
|
+
Hello Twilio SendGrid!
|
|
23
23
|
|
|
24
24
|
--001a1140ffb6f4fc5f053a2257e0
|
|
25
25
|
Content-Type: text/html; charset=UTF-8
|
|
26
26
|
Content-Transfer-Encoding: quoted-printable
|
|
27
27
|
|
|
28
|
-
<html><body><strong>Hello SendGrid!</body></html>
|
|
28
|
+
<html><body><strong>Hello Twilio SendGrid!</body></html>
|
|
29
29
|
|
|
30
30
|
--001a1140ffb6f4fc5f053a2257e0--
|
|
31
31
|
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# A module for sending test SendGrid Inbound Parse messages
|
|
1
|
+
# A module for sending test Twilio SendGrid Inbound Parse messages
|
|
2
2
|
# Usage: ruby ./send.rb [path to file containing test data]
|
|
3
3
|
require 'ruby_http_client'
|
|
4
4
|
require 'yaml'
|
|
5
5
|
require 'optparse'
|
|
6
6
|
|
|
7
|
-
OPTS = {}
|
|
7
|
+
OPTS = {}.freeze
|
|
8
8
|
opt = OptionParser.new
|
|
9
|
-
opt.on('--host=HOST') {|v| OPTS[:host] = v}
|
|
9
|
+
opt.on('--host=HOST') { |v| OPTS[:host] = v }
|
|
10
10
|
argv = opt.parse!(ARGV)
|
|
11
|
-
config = YAML.load_file(File.dirname(__FILE__)
|
|
11
|
+
config = YAML.load_file("#{File.dirname(__FILE__)}/config.yml")
|
|
12
12
|
host = OPTS[:host] || config['host']
|
|
13
13
|
client = SendGrid::Client.new(host: host)
|
|
14
14
|
File.open(argv[0]) do |file|
|
|
15
15
|
data = file.read
|
|
16
16
|
headers = {
|
|
17
|
-
'User-Agent' => 'SendGrid-Test',
|
|
17
|
+
'User-Agent' => 'Twilio-SendGrid-Test',
|
|
18
18
|
'Content-Type' => 'multipart/form-data; boundary=xYzZY'
|
|
19
19
|
}
|
|
20
20
|
response = client.post(
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module SendGrid
|
|
4
|
+
class IpManagement
|
|
5
|
+
attr_accessor :sendgrid_client
|
|
6
|
+
|
|
7
|
+
def initialize(sendgrid_client:)
|
|
8
|
+
@sendgrid_client = sendgrid_client
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def unassigned
|
|
12
|
+
response = @sendgrid_client.ips.get
|
|
13
|
+
ips = JSON.parse(response.body)
|
|
14
|
+
ips.select { |ip| ip.subusers.empty? }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
**This helper allows you to quickly and easily build a Mail object for sending email through SendGrid.**
|
|
1
|
+
**This helper allows you to quickly and easily build a Mail object for sending email through Twilio SendGrid.**
|
|
2
2
|
|
|
3
3
|
# Quick Start
|
|
4
4
|
|
|
5
|
-
Run the [example](
|
|
5
|
+
Run the [example](../../../../examples/helpers/mail) (make sure you have set your environment variable to include your SENDGRID_API_KEY).
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
ruby examples/helpers/mail/example.rb
|
|
@@ -10,5 +10,5 @@ ruby examples/helpers/mail/example.rb
|
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
- See the [example](
|
|
14
|
-
- [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/
|
|
13
|
+
- See the [example](../../../../examples/helpers/mail) for a complete working example.
|
|
14
|
+
- [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Mail/index.html)
|
|
@@ -2,31 +2,17 @@ require 'json'
|
|
|
2
2
|
|
|
3
3
|
module SendGrid
|
|
4
4
|
class ASM
|
|
5
|
+
attr_accessor :group_id, :groups_to_display
|
|
6
|
+
|
|
5
7
|
def initialize(group_id: nil, groups_to_display: nil)
|
|
6
8
|
@group_id = group_id
|
|
7
9
|
@groups_to_display = groups_to_display
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
def group_id=(group_id)
|
|
11
|
-
@group_id = group_id
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def group_id
|
|
15
|
-
@group_id
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def groups_to_display=(groups_to_display)
|
|
19
|
-
@groups_to_display = groups_to_display
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def groups_to_display
|
|
23
|
-
@groups_to_display
|
|
24
|
-
end
|
|
25
|
-
|
|
26
12
|
def to_json(*)
|
|
27
13
|
{
|
|
28
|
-
'group_id' =>
|
|
29
|
-
'groups_to_display' =>
|
|
14
|
+
'group_id' => group_id,
|
|
15
|
+
'groups_to_display' => groups_to_display
|
|
30
16
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
31
17
|
end
|
|
32
18
|
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
require '
|
|
1
|
+
require 'base64'
|
|
2
2
|
|
|
3
3
|
module SendGrid
|
|
4
4
|
class Attachment
|
|
5
|
+
attr_accessor :type, :filename, :disposition, :content_id
|
|
6
|
+
|
|
5
7
|
def initialize
|
|
6
8
|
@content = nil
|
|
7
9
|
@type = nil
|
|
@@ -11,53 +13,43 @@ module SendGrid
|
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def content=(content)
|
|
16
|
+
@encoded_content = nil
|
|
14
17
|
@content = content
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
def content
|
|
18
|
-
@
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def type=(type)
|
|
22
|
-
@type = type
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def type
|
|
26
|
-
@type
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def filename=(filename)
|
|
30
|
-
@filename = filename
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def filename
|
|
34
|
-
@filename
|
|
35
|
-
end
|
|
21
|
+
return @encoded_content if @encoded_content
|
|
36
22
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
@disposition
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def content_id=(content_id)
|
|
46
|
-
@content_id = content_id
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def content_id
|
|
50
|
-
@content_id
|
|
23
|
+
@encoded_content = if @content.respond_to?(:read)
|
|
24
|
+
encode @content
|
|
25
|
+
else
|
|
26
|
+
@content
|
|
27
|
+
end
|
|
51
28
|
end
|
|
52
29
|
|
|
53
30
|
def to_json(*)
|
|
54
31
|
{
|
|
55
|
-
'content' =>
|
|
56
|
-
'type' =>
|
|
57
|
-
'filename' =>
|
|
58
|
-
'disposition' =>
|
|
59
|
-
'content_id' =>
|
|
32
|
+
'content' => content,
|
|
33
|
+
'type' => type,
|
|
34
|
+
'filename' => filename,
|
|
35
|
+
'disposition' => disposition,
|
|
36
|
+
'content_id' => content_id
|
|
60
37
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
61
38
|
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def encode(io)
|
|
43
|
+
str = io.read
|
|
44
|
+
# Since the API expects UTF-8, we need to ensure that we're
|
|
45
|
+
# converting other formats to it so (byte-wise) Base64 encoding
|
|
46
|
+
# will come through properly on the other side.
|
|
47
|
+
#
|
|
48
|
+
# Not much to be done to try to handle encoding for files opened
|
|
49
|
+
# in binary mode, but at least we can faithfully convey the
|
|
50
|
+
# bytes.
|
|
51
|
+
str = str.encode('UTF-8') unless io.respond_to?(:binmode?) && io.binmode?
|
|
52
|
+
Base64.encode64 str
|
|
53
|
+
end
|
|
62
54
|
end
|
|
63
55
|
end
|
|
@@ -2,31 +2,17 @@ require 'json'
|
|
|
2
2
|
|
|
3
3
|
module SendGrid
|
|
4
4
|
class BccSettings
|
|
5
|
+
attr_accessor :enable, :email
|
|
6
|
+
|
|
5
7
|
def initialize(enable: nil, email: nil)
|
|
6
8
|
@enable = enable
|
|
7
9
|
@email = email
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
def enable=(enable)
|
|
11
|
-
@enable = enable
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def enable
|
|
15
|
-
@enable
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def email=(email)
|
|
19
|
-
@email = email
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def email
|
|
23
|
-
@email
|
|
24
|
-
end
|
|
25
|
-
|
|
26
12
|
def to_json(*)
|
|
27
13
|
{
|
|
28
|
-
'enable' =>
|
|
29
|
-
'email' =>
|
|
14
|
+
'enable' => enable,
|
|
15
|
+
'email' => email
|
|
30
16
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
31
17
|
end
|
|
32
18
|
end
|
|
@@ -2,41 +2,29 @@ require 'json'
|
|
|
2
2
|
|
|
3
3
|
module SendGrid
|
|
4
4
|
class BypassListManagement
|
|
5
|
-
|
|
6
|
-
@enable = enable
|
|
7
|
-
end
|
|
5
|
+
attr_accessor :enable
|
|
8
6
|
|
|
9
|
-
def
|
|
7
|
+
def initialize(enable: nil)
|
|
10
8
|
@enable = enable
|
|
11
9
|
end
|
|
12
10
|
|
|
13
|
-
def enable
|
|
14
|
-
@enable
|
|
15
|
-
end
|
|
16
|
-
|
|
17
11
|
def to_json(*)
|
|
18
12
|
{
|
|
19
|
-
'enable' =>
|
|
13
|
+
'enable' => enable
|
|
20
14
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
21
15
|
end
|
|
22
16
|
end
|
|
23
17
|
|
|
24
18
|
class SandBoxMode
|
|
25
|
-
|
|
26
|
-
@enable = enable
|
|
27
|
-
end
|
|
19
|
+
attr_accessor :enable
|
|
28
20
|
|
|
29
|
-
def
|
|
21
|
+
def initialize(enable: nil)
|
|
30
22
|
@enable = enable
|
|
31
23
|
end
|
|
32
24
|
|
|
33
|
-
def enable
|
|
34
|
-
@enable
|
|
35
|
-
end
|
|
36
|
-
|
|
37
25
|
def to_json(*)
|
|
38
26
|
{
|
|
39
|
-
'enable' =>
|
|
27
|
+
'enable' => enable
|
|
40
28
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
41
29
|
end
|
|
42
30
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require 'json'
|
|
2
|
-
|
|
3
1
|
module SendGrid
|
|
4
2
|
class Category
|
|
5
3
|
attr_accessor :name
|
|
@@ -8,21 +6,13 @@ module SendGrid
|
|
|
8
6
|
@name = name
|
|
9
7
|
end
|
|
10
8
|
|
|
11
|
-
def name=(name)
|
|
12
|
-
@name = name
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def name
|
|
16
|
-
@name
|
|
17
|
-
end
|
|
18
|
-
|
|
19
9
|
def to_json(*)
|
|
20
10
|
{
|
|
21
11
|
'category' => name
|
|
22
12
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
23
13
|
end
|
|
24
14
|
|
|
25
|
-
alias
|
|
26
|
-
alias
|
|
15
|
+
alias category name
|
|
16
|
+
alias category= name=
|
|
27
17
|
end
|
|
28
18
|
end
|
|
@@ -2,31 +2,17 @@ require 'json'
|
|
|
2
2
|
|
|
3
3
|
module SendGrid
|
|
4
4
|
class ClickTracking
|
|
5
|
+
attr_accessor :enable, :enable_text
|
|
6
|
+
|
|
5
7
|
def initialize(enable: nil, enable_text: nil)
|
|
6
8
|
@enable = enable
|
|
7
9
|
@enable_text = enable_text
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
def enable=(enable)
|
|
11
|
-
@enable = enable
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def enable
|
|
15
|
-
@enable
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def enable_text=(enable_text)
|
|
19
|
-
@enable_text = enable_text
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def enable_text
|
|
23
|
-
@enable_text
|
|
24
|
-
end
|
|
25
|
-
|
|
26
12
|
def to_json(*)
|
|
27
13
|
{
|
|
28
|
-
'enable' =>
|
|
29
|
-
'enable_text' =>
|
|
14
|
+
'enable' => enable,
|
|
15
|
+
'enable_text' => enable_text
|
|
30
16
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
31
17
|
end
|
|
32
18
|
end
|
|
@@ -2,31 +2,17 @@ require 'json'
|
|
|
2
2
|
|
|
3
3
|
module SendGrid
|
|
4
4
|
class Content
|
|
5
|
+
attr_accessor :type, :value
|
|
6
|
+
|
|
5
7
|
def initialize(type: nil, value: nil)
|
|
6
8
|
@type = type
|
|
7
9
|
@value = value
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
def type=(type)
|
|
11
|
-
@type = type
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def type
|
|
15
|
-
@type
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def value=(value)
|
|
19
|
-
@value = value
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def value
|
|
23
|
-
@value
|
|
24
|
-
end
|
|
25
|
-
|
|
26
12
|
def to_json(*)
|
|
27
13
|
{
|
|
28
|
-
'type' =>
|
|
29
|
-
'value' =>
|
|
14
|
+
'type' => type,
|
|
15
|
+
'value' => value
|
|
30
16
|
}.delete_if { |_, value| value.to_s.strip == '' }
|
|
31
17
|
end
|
|
32
18
|
end
|