4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 | of the Software, and to permit persons to whom the Software is furnished to do
10 | so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: install test test-integ test-docker
2 |
3 | install:
4 | gem install bundler:2.1.2; bundle install
5 |
6 | test:
7 | bundle exec rake
8 |
9 | test-integ: test
10 |
11 | version ?= ruby:latest
12 | test-docker:
13 | curl -s https://raw.githubusercontent.com/sendgrid/sendgrid-oai/HEAD/prism/prism.sh -o prism.sh
14 | version=$(version) bash ./prism.sh
15 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
16 |
17 | # Fixes #
18 |
19 | A short description of what this PR does.
20 |
21 | ### Checklist
22 | - [x] I acknowledge that all my contributions will be made under the project's license
23 | - [ ] I have made a material change to the repo (functionality, testing, spelling, grammar)
24 | - [ ] I have read the [Contribution Guidelines](https://github.com/sendgrid/sendgrid-ruby/blob/main/CONTRIBUTING.md) and my PR follows them
25 | - [ ] I have titled the PR appropriately
26 | - [ ] I have updated my branch with the main branch
27 | - [ ] I have added tests that prove my fix is effective or that my feature works
28 | - [ ] I have added the necessary documentation about the functionality in the appropriate .md file
29 | - [ ] I have added inline documentation to the code I modified
30 |
31 | If you have questions, please file a [support ticket](https://support.sendgrid.com), or create a GitHub Issue in this repository.
32 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rake/testtask'
2 | require 'bundler/gem_tasks'
3 | require 'rspec/core/rake_task'
4 |
5 | Rake::TestTask.new do |t|
6 | t.libs << 'test'
7 | t.test_files = FileList['test/sendgrid/test*.rb', 'test/sendgrid/helpers/mail/test*.rb', 'test/sendgrid/helpers/permissions/test*.rb']
8 | t.verbose = true
9 | end
10 |
11 | RSpec::Core::RakeTask.new(:spec)
12 |
13 | desc 'Run tests'
14 | task default: %i[spec test]
15 |
--------------------------------------------------------------------------------
/TROUBLESHOOTING.md:
--------------------------------------------------------------------------------
1 | If you have an issue logging into your Twilio SendGrid account, please read this [document](https://sendgrid.com/docs/ui/account-and-settings/troubleshooting-login/). For any questions regarding login issues, please contact our [support team](https://support.sendgrid.com).
2 |
3 | If you have a non-library Twilio SendGrid issue, please contact our [support team](https://support.sendgrid.com).
4 |
5 | If you can't find a solution below, please open an [issue](https://github.com/sendgrid/sendgrid-ruby/issues).
6 |
7 |
8 | ## Table of Contents
9 |
10 | * [Migrating from v2 to v3](#migrating-from-v2-to-v3)
11 | * [Continue Using v2](#continue-using-v2)
12 | * [Testing v3 /mail/send Calls Directly](#testing-v3-mailsend-calls-directly)
13 | * [Error Messages](#error-messages)
14 | * [Versioning](#versioning)
15 | * [Environment Variables and Your Twilio SendGrid API Key](#environment-variables-and-your-twilio-sendgrid-api-key)
16 | * [Using the Package Manager](#using-the-package-manager)
17 | * [Rails Specifics](#rails-specifics)
18 | * [Ruby Versions](#ruby-versions)
19 | * [Viewing the Request Body](#viewing-the-request-body)
20 | * [Verifying Event Webhooks](#signed-webhooks)
21 |
22 |
23 | ## Migrating from v2 to v3
24 |
25 | Please review [our guide](https://sendgrid.com/docs/Classroom/Send/v3_Mail_Send/how_to_migrate_from_v2_to_v3_mail_send.html) on how to migrate from v2 to v3.
26 |
27 |
28 | ## Continue Using v2
29 |
30 | [Here](https://github.com/sendgrid/sendgrid-ruby/tree/0fbf579c0f7ed1dff87adc4957c4dc5a6b257068) is the last working version with v2 support.
31 |
32 | Using RubyGems:
33 |
34 | Add this line to your application's Gemfile:
35 |
36 | ```bash
37 | gem 'sendgrid-ruby', '1.1.6'
38 | ```
39 |
40 | And then execute:
41 |
42 | ```bash
43 | bundle
44 | ```
45 |
46 | Or install it yourself using:
47 |
48 | ```bash
49 | gem install sendgrid-ruby -v 1.1.6
50 | ```
51 |
52 | Download:
53 |
54 | Click the "Clone or download" green button in [GitHub](https://github.com/sendgrid/sendgrid-ruby/tree/0fbf579c0f7ed1dff87adc4957c4dc5a6b257068) and choose download.
55 |
56 |
57 | ## Testing v3 /mail/send Calls Directly
58 |
59 | [Here](https://sendgrid.com/docs/for-developers/sending-email/curl-examples/) are some cURL examples for common use cases.
60 |
61 |
62 | ## Error Messages
63 |
64 | To read the error message returned by SendGrid's API:
65 |
66 | ```ruby
67 | begin
68 | response = sg.client.mail._("send").post(request_body: mail.to_json)
69 | rescue Exception => e
70 | puts e.message
71 | end
72 | ```
73 |
74 |
75 | ## Versioning
76 |
77 | We follow the MAJOR.MINOR.PATCH versioning scheme as described by [SemVer.org](http://semver.org). Therefore, we recommend that you always pin (or vendor) the particular version you are working with your code and never auto-update to the latest version. Especially when there is a MAJOR point release since that is guaranteed to be a breaking change. Changes are documented in the [CHANGELOG](CHANGELOG.md) and [releases](https://github.com/sendgrid/sendgrid-ruby/releases) section.
78 |
79 |
80 | ## Environment Variables and Your Twilio SendGrid API Key
81 |
82 | All of our examples assume you are using [environment variables](https://github.com/sendgrid/sendgrid-ruby#setup-environment-variables) to hold your Twilio SendGrid API key.
83 |
84 | If you choose to add your Twilio SendGrid API key directly (not recommended):
85 |
86 | `sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])`
87 |
88 | becomes
89 |
90 | `sg = SendGrid::API.new(api_key: 'SENDGRID_API_KEY')`
91 |
92 | In the first case, SENDGRID_API_KEY is in reference to the name of the environment variable, while the second case references the actual Twilio SendGrid API Key.
93 |
94 |
95 | ## Using the Package Manager
96 |
97 | We upload this library to [RubyGems](https://rubygems.org/gems/sendgrid-ruby) whenever we make a release. This allows you to use [RubyGems](https://rubygems.org) for easy installation.
98 |
99 | In most cases we recommend you download the latest version of the library, but if you need a different version, please use:
100 |
101 | Add this line to your application's Gemfile:
102 |
103 | ```bash
104 | gem 'sendgrid-ruby', 'X.X.X'
105 | ```
106 |
107 | And then execute:
108 |
109 | ```bash
110 | bundle
111 | ```
112 |
113 | Or install it yourself using:
114 |
115 | ```bash
116 | gem install sendgrid-ruby -v X.X.X
117 | ```
118 |
119 |
120 | ## Rails Specifics
121 |
122 | - Namespace collision between Rails own `Mail` class and sendgrid class `Mail`. To avoid that issues please use `SendGrid:: Mail` instead.
123 |
124 | - The possibility of a namespace collision between the sendgrid class `Email` and your own defined `Email` class. To avoid these issues, you can skip the `include SendGrid` line and use the `SendGrid::` prefix for Email. Please see this [SO answer](https://stackoverflow.com/questions/41508464/rails-model-name-conflict-with-included-gem?noredirect=1#comment70223099_41508464) for specifics.
125 |
126 |
127 | ## Ruby Versions
128 |
129 | This SDK [does not work with ruby version 2.6.0](https://github.com/sendgrid/sendgrid-ruby/issues/378) because of [this bug](https://bugs.ruby-lang.org/issues/15468). Please use any other [supported version](https://github.com/sendgrid/sendgrid-ruby#prerequisites).
130 |
131 |
132 | ## Viewing the Request Body
133 |
134 | When debugging or testing, it may be useful to examine the raw request header to compare against the [documented format](https://sendgrid.com/docs/API_Reference/api_v3.html).
135 |
136 | You can do this before `response = sg.client.mail._('send').post(request_body: mail.to_json)` like so:
137 |
138 | ```ruby
139 | puts mail.to_json
140 | ```
141 |
142 |
143 | ## Signed Webhook Verification
144 |
145 | Twilio SendGrid's Event Webhook will notify a URL via HTTP POST with information about events that occur as your mail is processed. [This](https://docs.sendgrid.com/for-developers/tracking-events/getting-started-event-webhook-security-features) article covers all you need to know to secure the Event Webhook, allowing you to verify that incoming requests originate from Twilio SendGrid. The sendgrid-ruby library can help you verify these Signed Event Webhooks.
146 |
147 | You can find the usage example [here](examples/helpers/eventwebhook/example.rb) and the tests [here](spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb).
148 | If you are still having trouble getting the validation to work, follow the following instructions:
149 | - Be sure to use the *raw* payload for validation
150 | - Be sure to include a trailing carriage return and newline in your payload
151 | - In case of multi-event webhooks, make sure you include the trailing newline and carriage return after *each* event
152 |
--------------------------------------------------------------------------------
/UPGRADE.md:
--------------------------------------------------------------------------------
1 | # Upgrading from 5.X to 6.X
2 |
3 | Note, this is only necessary if you are using inbound processing.
4 |
5 | * Add this gem to your Gemfile: `gem 'sinatra', '>= 1.4.7', '< 3'`
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | require './lib/sendgrid/helpers/inbound/app'
2 |
3 | use Rack::Reloader, 0
4 | run Main
5 |
--------------------------------------------------------------------------------
/examples/accesssettings/accesssettings.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve all recent access attempts #
7 | # GET /access_settings/activity #
8 |
9 | params = JSON.parse('{"limit": 1}')
10 | response = sg.client.access_settings.activity.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Add one or more IPs to the whitelist #
17 | # POST /access_settings/whitelist #
18 |
19 | data = JSON.parse('{
20 | "ips": [
21 | {
22 | "ip": "192.168.1.1"
23 | },
24 | {
25 | "ip": "192.*.*.*"
26 | },
27 | {
28 | "ip": "192.168.1.3/32"
29 | }
30 | ]
31 | }')
32 | response = sg.client.access_settings.whitelist.post(request_body: data)
33 | puts response.status_code
34 | puts response.body
35 | puts response.headers
36 |
37 | ##################################################
38 | # Retrieve a list of currently whitelisted IPs #
39 | # GET /access_settings/whitelist #
40 |
41 | response = sg.client.access_settings.whitelist.get
42 | puts response.status_code
43 | puts response.body
44 | puts response.headers
45 |
46 | ##################################################
47 | # Remove one or more IPs from the whitelist #
48 | # DELETE /access_settings/whitelist #
49 |
50 | data = JSON.parse('{
51 | "ids": [
52 | 1,
53 | 2,
54 | 3
55 | ]
56 | }')
57 | response = sg.client.access_settings.whitelist.delete(request_body: data)
58 | puts response.status_code
59 | puts response.body
60 | puts response.headers
61 |
62 | ##################################################
63 | # Retrieve a specific whitelisted IP #
64 | # GET /access_settings/whitelist/{rule_id} #
65 |
66 | rule_id = 'test_url_param'
67 | response = sg.client.access_settings.whitelist._(rule_id).get
68 | puts response.status_code
69 | puts response.body
70 | puts response.headers
71 |
72 | ##################################################
73 | # Remove a specific IP from the whitelist #
74 | # DELETE /access_settings/whitelist/{rule_id} #
75 |
76 | rule_id = 'test_url_param'
77 | response = sg.client.access_settings.whitelist._(rule_id).delete
78 | puts response.status_code
79 | puts response.body
80 | puts response.headers
81 |
--------------------------------------------------------------------------------
/examples/alerts/alerts.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create a new Alert #
7 | # POST /alerts #
8 |
9 | data = JSON.parse('{
10 | "email_to": "example@example.com",
11 | "frequency": "daily",
12 | "type": "stats_notification"
13 | }')
14 | response = sg.client.alerts.post(request_body: data)
15 | puts response.status_code
16 | puts response.body
17 | puts response.headers
18 |
19 | ##################################################
20 | # Retrieve all alerts #
21 | # GET /alerts #
22 |
23 | response = sg.client.alerts.get
24 | puts response.status_code
25 | puts response.body
26 | puts response.headers
27 |
28 | ##################################################
29 | # Update an alert #
30 | # PATCH /alerts/{alert_id} #
31 |
32 | data = JSON.parse('{
33 | "email_to": "example@example.com"
34 | }')
35 | alert_id = 'test_url_param'
36 | response = sg.client.alerts._(alert_id).patch(request_body: data)
37 | puts response.status_code
38 | puts response.body
39 | puts response.headers
40 |
41 | ##################################################
42 | # Retrieve a specific alert #
43 | # GET /alerts/{alert_id} #
44 |
45 | alert_id = 'test_url_param'
46 | response = sg.client.alerts._(alert_id).get
47 | puts response.status_code
48 | puts response.body
49 | puts response.headers
50 |
51 | ##################################################
52 | # Delete an alert #
53 | # DELETE /alerts/{alert_id} #
54 |
55 | alert_id = 'test_url_param'
56 | response = sg.client.alerts._(alert_id).delete
57 | puts response.status_code
58 | puts response.body
59 | puts response.headers
60 |
--------------------------------------------------------------------------------
/examples/apikeys/apikeys.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create API keys #
7 | # POST /api_keys #
8 |
9 | data = JSON.parse('{
10 | "name": "My API Key",
11 | "sample": "data",
12 | "scopes": [
13 | "mail.send",
14 | "alerts.create",
15 | "alerts.read"
16 | ]
17 | }')
18 | response = sg.client.api_keys.post(request_body: data)
19 | puts response.status_code
20 | puts response.body
21 | puts response.headers
22 |
23 | ##################################################
24 | # Retrieve all API Keys belonging to the authenticated user #
25 | # GET /api_keys #
26 |
27 | params = JSON.parse('{"limit": 1}')
28 | response = sg.client.api_keys.get(query_params: params)
29 | puts response.status_code
30 | puts response.body
31 | puts response.headers
32 |
33 | ##################################################
34 | # Update the name & scopes of an API Key #
35 | # PUT /api_keys/{api_key_id} #
36 |
37 | data = JSON.parse('{
38 | "name": "A New Hope",
39 | "scopes": [
40 | "user.profile.read",
41 | "user.profile.update"
42 | ]
43 | }')
44 | api_key_id = 'test_url_param'
45 | response = sg.client.api_keys._(api_key_id).put(request_body: data)
46 | puts response.status_code
47 | puts response.body
48 | puts response.headers
49 |
50 | ##################################################
51 | # Update API keys #
52 | # PATCH /api_keys/{api_key_id} #
53 |
54 | data = JSON.parse('{
55 | "name": "A New Hope"
56 | }')
57 | api_key_id = 'test_url_param'
58 | response = sg.client.api_keys._(api_key_id).patch(request_body: data)
59 | puts response.status_code
60 | puts response.body
61 | puts response.headers
62 |
63 | ##################################################
64 | # Retrieve an existing API Key #
65 | # GET /api_keys/{api_key_id} #
66 |
67 | api_key_id = 'test_url_param'
68 | response = sg.client.api_keys._(api_key_id).get
69 | puts response.status_code
70 | puts response.body
71 | puts response.headers
72 |
73 | ##################################################
74 | # Delete API keys #
75 | # DELETE /api_keys/{api_key_id} #
76 |
77 | api_key_id = 'test_url_param'
78 | response = sg.client.api_keys._(api_key_id).delete
79 | puts response.status_code
80 | puts response.body
81 | puts response.headers
82 |
--------------------------------------------------------------------------------
/examples/asm/asm.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create a new suppression group #
7 | # POST /asm/groups #
8 |
9 | data = JSON.parse('{
10 | "description": "Suggestions for products our users might like.",
11 | "is_default": true,
12 | "name": "Product Suggestions"
13 | }')
14 | response = sg.client.asm.groups.post(request_body: data)
15 | puts response.status_code
16 | puts response.body
17 | puts response.headers
18 |
19 | ##################################################
20 | # Retrieve information about multiple suppression groups #
21 | # GET /asm/groups #
22 |
23 | params = JSON.parse('{"id": 1}')
24 | response = sg.client.asm.groups.get(query_params: params)
25 | puts response.status_code
26 | puts response.body
27 | puts response.headers
28 |
29 | ##################################################
30 | # Update a suppression group. #
31 | # PATCH /asm/groups/{group_id} #
32 |
33 | data = JSON.parse('{
34 | "description": "Suggestions for items our users might like.",
35 | "id": 103,
36 | "name": "Item Suggestions"
37 | }')
38 | group_id = 'test_url_param'
39 | response = sg.client.asm.groups._(group_id).patch(request_body: data)
40 | puts response.status_code
41 | puts response.body
42 | puts response.headers
43 |
44 | ##################################################
45 | # Get information on a single suppression group. #
46 | # GET /asm/groups/{group_id} #
47 |
48 | group_id = 'test_url_param'
49 | response = sg.client.asm.groups._(group_id).get
50 | puts response.status_code
51 | puts response.body
52 | puts response.headers
53 |
54 | ##################################################
55 | # Delete a suppression group. #
56 | # DELETE /asm/groups/{group_id} #
57 |
58 | group_id = 'test_url_param'
59 | response = sg.client.asm.groups._(group_id).delete
60 | puts response.status_code
61 | puts response.body
62 | puts response.headers
63 |
64 | ##################################################
65 | # Add suppressions to a suppression group #
66 | # POST /asm/groups/{group_id}/suppressions #
67 |
68 | data = JSON.parse('{
69 | "recipient_emails": [
70 | "test1@example.com",
71 | "test2@example.com"
72 | ]
73 | }')
74 | group_id = 'test_url_param'
75 | response = sg.client.asm.groups._(group_id).suppressions.post(request_body: data)
76 | puts response.status_code
77 | puts response.body
78 | puts response.headers
79 |
80 | ##################################################
81 | # Retrieve all suppressions for a suppression group #
82 | # GET /asm/groups/{group_id}/suppressions #
83 |
84 | group_id = 'test_url_param'
85 | response = sg.client.asm.groups._(group_id).suppressions.get
86 | puts response.status_code
87 | puts response.body
88 | puts response.headers
89 |
90 | ##################################################
91 | # Search for suppressions within a group #
92 | # POST /asm/groups/{group_id}/suppressions/search #
93 |
94 | data = JSON.parse('{
95 | "recipient_emails": [
96 | "exists1@example.com",
97 | "exists2@example.com",
98 | "doesnotexists@example.com"
99 | ]
100 | }')
101 | group_id = 'test_url_param'
102 | response = sg.client.asm.groups._(group_id).suppressions.search.post(request_body: data)
103 | puts response.status_code
104 | puts response.body
105 | puts response.headers
106 |
107 | ##################################################
108 | # Delete a suppression from a suppression group #
109 | # DELETE /asm/groups/{group_id}/suppressions/{email} #
110 |
111 | group_id = 'test_url_param'
112 | email = 'test_url_param'
113 | response = sg.client.asm.groups._(group_id).suppressions._(email).delete
114 | puts response.status_code
115 | puts response.body
116 | puts response.headers
117 |
118 | ##################################################
119 | # Retrieve all suppressions #
120 | # GET /asm/suppressions #
121 |
122 | response = sg.client.asm.suppressions.get
123 | puts response.status_code
124 | puts response.body
125 | puts response.headers
126 |
127 | ##################################################
128 | # Add recipient addresses to the global suppression group. #
129 | # POST /asm/suppressions/global #
130 |
131 | data = JSON.parse('{
132 | "recipient_emails": [
133 | "test1@example.com",
134 | "test2@example.com"
135 | ]
136 | }')
137 | response = sg.client.asm.suppressions.global.post(request_body: data)
138 | puts response.status_code
139 | puts response.body
140 | puts response.headers
141 |
142 | ##################################################
143 | # Retrieve a Global Suppression #
144 | # GET /asm/suppressions/global/{email} #
145 |
146 | email = 'test_url_param'
147 | response = sg.client.asm.suppressions.global._(email).get
148 | puts response.status_code
149 | puts response.body
150 | puts response.headers
151 |
152 | ##################################################
153 | # Delete a Global Suppression #
154 | # DELETE /asm/suppressions/global/{email} #
155 |
156 | email = 'test_url_param'
157 | response = sg.client.asm.suppressions.global._(email).delete
158 | puts response.status_code
159 | puts response.body
160 | puts response.headers
161 |
162 | ##################################################
163 | # Retrieve all suppression groups for an email address #
164 | # GET /asm/suppressions/{email} #
165 |
166 | email = 'test_url_param'
167 | response = sg.client.asm.suppressions._(email).get
168 | puts response.status_code
169 | puts response.body
170 | puts response.headers
171 |
--------------------------------------------------------------------------------
/examples/browsers/browsers.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve email statistics by browser. #
7 | # GET /browsers/stats #
8 |
9 | params = JSON.parse('{"end_date": "2016-04-01", "aggregated_by": "day", "browsers": "test_string", "limit": "test_string", "offset": "test_string", "start_date": "2016-01-01"}')
10 | response = sg.client.browsers.stats.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
--------------------------------------------------------------------------------
/examples/campaigns/campaigns.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create a Campaign #
7 | # POST /campaigns #
8 |
9 | data = JSON.parse('{
10 | "categories": [
11 | "spring line"
12 | ],
13 | "custom_unsubscribe_url": "",
14 | "html_content": "Check out our spring line!
",
15 | "ip_pool": "marketing",
16 | "list_ids": [
17 | 110,
18 | 124
19 | ],
20 | "plain_content": "Check out our spring line!",
21 | "segment_ids": [
22 | 110
23 | ],
24 | "sender_id": 124451,
25 | "subject": "New Products for Spring!",
26 | "suppression_group_id": 42,
27 | "title": "March Newsletter"
28 | }')
29 | response = sg.client.campaigns.post(request_body: data)
30 | puts response.status_code
31 | puts response.body
32 | puts response.headers
33 |
34 | ##################################################
35 | # Retrieve all Campaigns #
36 | # GET /campaigns #
37 |
38 | params = JSON.parse('{"limit": 1, "offset": 1}')
39 | response = sg.client.campaigns.get(query_params: params)
40 | puts response.status_code
41 | puts response.body
42 | puts response.headers
43 |
44 | ##################################################
45 | # Update a Campaign #
46 | # PATCH /campaigns/{campaign_id} #
47 |
48 | data = JSON.parse('{
49 | "categories": [
50 | "summer line"
51 | ],
52 | "html_content": "Check out our summer line!
",
53 | "plain_content": "Check out our summer line!",
54 | "subject": "New Products for Summer!",
55 | "title": "May Newsletter"
56 | }')
57 | campaign_id = 'test_url_param'
58 | response = sg.client.campaigns._(campaign_id).patch(request_body: data)
59 | puts response.status_code
60 | puts response.body
61 | puts response.headers
62 |
63 | ##################################################
64 | # Retrieve a single campaign #
65 | # GET /campaigns/{campaign_id} #
66 |
67 | campaign_id = 'test_url_param'
68 | response = sg.client.campaigns._(campaign_id).get
69 | puts response.status_code
70 | puts response.body
71 | puts response.headers
72 |
73 | ##################################################
74 | # Delete a Campaign #
75 | # DELETE /campaigns/{campaign_id} #
76 |
77 | campaign_id = 'test_url_param'
78 | response = sg.client.campaigns._(campaign_id).delete
79 | puts response.status_code
80 | puts response.body
81 | puts response.headers
82 |
83 | ##################################################
84 | # Update a Scheduled Campaign #
85 | # PATCH /campaigns/{campaign_id}/schedules #
86 |
87 | data = JSON.parse('{
88 | "send_at": 1489451436
89 | }')
90 | campaign_id = 'test_url_param'
91 | response = sg.client.campaigns._(campaign_id).schedules.patch(request_body: data)
92 | puts response.status_code
93 | puts response.body
94 | puts response.headers
95 |
96 | ##################################################
97 | # Schedule a Campaign #
98 | # POST /campaigns/{campaign_id}/schedules #
99 |
100 | data = JSON.parse('{
101 | "send_at": 1489771528
102 | }')
103 | campaign_id = 'test_url_param'
104 | response = sg.client.campaigns._(campaign_id).schedules.post(request_body: data)
105 | puts response.status_code
106 | puts response.body
107 | puts response.headers
108 |
109 | ##################################################
110 | # View Scheduled Time of a Campaign #
111 | # GET /campaigns/{campaign_id}/schedules #
112 |
113 | campaign_id = 'test_url_param'
114 | response = sg.client.campaigns._(campaign_id).schedules.get
115 | puts response.status_code
116 | puts response.body
117 | puts response.headers
118 |
119 | ##################################################
120 | # Unschedule a Scheduled Campaign #
121 | # DELETE /campaigns/{campaign_id}/schedules #
122 |
123 | campaign_id = 'test_url_param'
124 | response = sg.client.campaigns._(campaign_id).schedules.delete
125 | puts response.status_code
126 | puts response.body
127 | puts response.headers
128 |
129 | ##################################################
130 | # Send a Campaign #
131 | # POST /campaigns/{campaign_id}/schedules/now #
132 |
133 | campaign_id = 'test_url_param'
134 | response = sg.client.campaigns._(campaign_id).schedules.now.post
135 | puts response.status_code
136 | puts response.body
137 | puts response.headers
138 |
139 | ##################################################
140 | # Send a Test Campaign #
141 | # POST /campaigns/{campaign_id}/schedules/test #
142 |
143 | data = JSON.parse('{
144 | "to": "your.email@example.com"
145 | }')
146 | campaign_id = 'test_url_param'
147 | response = sg.client.campaigns._(campaign_id).schedules.test.post(request_body: data)
148 | puts response.status_code
149 | puts response.body
150 | puts response.headers
151 |
--------------------------------------------------------------------------------
/examples/categories/categories.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve all categories #
7 | # GET /categories #
8 |
9 | params = JSON.parse('{"category": "test_string", "limit": 1, "offset": 1}')
10 | response = sg.client.categories.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Retrieve Email Statistics for Categories #
17 | # GET /categories/stats #
18 |
19 | params = JSON.parse('{"end_date": "2016-04-01", "aggregated_by": "day", "limit": 1, "offset": 1, "start_date": "2016-01-01", "categories": "test_string"}')
20 | response = sg.client.categories.stats.get(query_params: params)
21 | puts response.status_code
22 | puts response.body
23 | puts response.headers
24 |
25 | ##################################################
26 | # Retrieve sums of email stats for each category [Needs: Stats object defined, has category ID?] #
27 | # GET /categories/stats/sums #
28 |
29 | params = JSON.parse('{"end_date": "2016-04-01", "aggregated_by": "day", "limit": 1, "sort_by_metric": "test_string", "offset": 1, "start_date": "2016-01-01", "sort_by_direction": "asc"}')
30 | response = sg.client.categories.stats.sums.get(query_params: params)
31 | puts response.status_code
32 | puts response.body
33 | puts response.headers
34 |
--------------------------------------------------------------------------------
/examples/clients/clients.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve email statistics by client type. #
7 | # GET /clients/stats #
8 |
9 | params = JSON.parse('{"aggregated_by": "day", "start_date": "2016-01-01", "end_date": "2016-04-01"}')
10 | response = sg.client.clients.stats.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Retrieve stats by a specific client type. #
17 | # GET /clients/{client_type}/stats #
18 |
19 | params = JSON.parse('{"aggregated_by": "day", "start_date": "2016-01-01", "end_date": "2016-04-01"}')
20 | client_type = 'test_url_param'
21 | response = sg.client.clients._(client_type).stats.get(query_params: params)
22 | puts response.status_code
23 | puts response.body
24 | puts response.headers
25 |
--------------------------------------------------------------------------------
/examples/dataresidency/setregion.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | # Example 1
4 | # Sending using "global" data residency
5 |
6 | from = SendGrid::Email.new(email: 'example@abc.com')
7 | to = SendGrid::Email.new(email: 'example@abc.com')
8 | subject = 'Sending with Twilio SendGrid is Fun'
9 | content = SendGrid::Content.new(type: 'text/plain', value: 'and easy to do anywhere, even with Ruby')
10 | mail = SendGrid::Mail.new(from, subject, to, content)
11 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
12 | sg.sendgrid_data_residency(region: "global")
13 | puts sg.host
14 | response = sg.client.mail._('send').post(request_body: mail.to_json)
15 | puts response.status_code
16 | puts response.body
17 | puts response.headers
18 |
19 | # Example 2
20 | # Sending using "eu" data residency
21 |
22 | from = SendGrid::Email.new(email: 'example@abc.com')
23 | to = SendGrid::Email.new(email: 'example@abc.com')
24 | subject = 'Sending with Twilio SendGrid is Fun'
25 | content = SendGrid::Content.new(type: 'text/plain', value: 'and easy to do anywhere, even with Ruby')
26 | mail = SendGrid::Mail.new(from, subject, to, content)
27 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY_EU'])
28 | sg.sendgrid_data_residency(region: 'eu')
29 | puts sg.host
30 | response = sg.client.mail._('send').post(request_body: mail.to_json)
31 | puts response.status_code
32 | puts response.body
33 | puts response.headers
34 |
35 | # Example 3
36 | # Sending using no data residency
37 |
38 | from = SendGrid::Email.new(email: 'example@abc.com')
39 | to = SendGrid::Email.new(email: 'example@abc.com')
40 | subject = 'Sending with Twilio SendGrid is Fun'
41 | content = SendGrid::Content.new(type: 'text/plain', value: 'and easy to do anywhere, even with Ruby')
42 | mail = SendGrid::Mail.new(from, subject, to, content)
43 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
44 | puts sg.host
45 | response = sg.client.mail._('send').post(request_body: mail.to_json)
46 | puts response.status_code
47 | puts response.body
48 | puts response.headers
49 |
--------------------------------------------------------------------------------
/examples/devices/devices.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve email statistics by device type. #
7 | # GET /devices/stats #
8 |
9 | params = JSON.parse('{"aggregated_by": "day", "limit": 1, "start_date": "2016-01-01", "end_date": "2016-04-01", "offset": 1}')
10 | response = sg.client.devices.stats.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
--------------------------------------------------------------------------------
/examples/emailactivity/emailactivity.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Filter all messages #
7 | # GET /messages #
8 |
9 | require 'erb'
10 |
11 | filter_key = 'to_email'
12 | filter_operator = ERB::Util.url_encode('=')
13 | filter_value = 'testing@sendgrid.net'
14 | filter_value = ERB::Util.url_encode(format('"%s"', filter_value))
15 | query_params = {}
16 | query_params['query'] = format("%s%s%s", filter_key, filter_operator, filter_value)
17 | query_params['limit'] = '1'
18 |
19 | params = query_params
20 | response = sg.client.messages.get(query_params: params)
21 | puts response.status_code
22 | puts response.body
23 | puts response.headers
24 |
25 | ##################################################
26 | # Filter messages by message ID #
27 | # GET /messages/{msg_id} #
28 |
29 | msg_id = "test_url_param"
30 | response = sg.client.messages._(msg_id).get
31 | puts response.status_code
32 | puts response.body
33 | puts response.headers
34 |
35 | ##################################################
36 | # Request a CSV #
37 | # POST /messages/download #
38 |
39 | response = sg.client.messages.download.post
40 | puts response.status_code
41 | puts response.body
42 | puts response.headers
43 |
44 | ##################################################
45 | # Download CSV #
46 | # GET /messages/download/{download_uuid} #
47 |
48 | download_uuid = "test_url_param"
49 | response = sg.client.messages.download._(download_uuid).get
50 | puts response.status_code
51 | puts response.body
52 | puts response.headers
53 |
--------------------------------------------------------------------------------
/examples/geo/geo.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve email statistics by country and state/province. #
7 | # GET /geo/stats #
8 |
9 | params = JSON.parse('{"end_date": "2016-04-01", "country": "US", "aggregated_by": "day", "limit": 1, "offset": 1, "start_date": "2016-01-01"}')
10 | response = sg.client.geo.stats.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
--------------------------------------------------------------------------------
/examples/helpers/eventwebhook/example.rb:
--------------------------------------------------------------------------------
1 | require 'sengrid-ruby'
2 | include SendGrid
3 |
4 | def is_valid_signature(request)
5 | public_key = 'base64-encoded public key'
6 |
7 | event_webhook = SendGrid::EventWebhook.new
8 | ec_public_key = event_webhook.convert_public_key_to_ecdsa(public_key)
9 |
10 | event_webhook.verify_signature(
11 | ec_public_key,
12 | request.body.read,
13 | request.env[SendGrid::EventWebhookHeader::SIGNATURE],
14 | request.env[SendGrid::EventWebhookHeader::TIMESTAMP]
15 | )
16 | end
17 |
--------------------------------------------------------------------------------
/examples/helpers/settings/example.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 | include SendGrid
3 |
4 | sg_client = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY']).client
5 | settings = SendGrid::Settings.new(sendgrid_client: sg_client)
6 |
7 | # Fetch settings
8 | response = settings.bcc
9 | puts response.status_code
10 | puts response.body
11 | puts response.headers
12 |
13 | # Turn on bcc settings
14 | response = settings.update_bcc(enabled: true, email: 'email@example.com')
15 | puts response.status_code
16 | puts response.body
17 | puts response.headers
18 |
19 | # Turn off bcc settings
20 | response = settings.update_bcc(enabled: false)
21 | puts response.status_code
22 | puts response.body
23 | puts response.headers
24 |
--------------------------------------------------------------------------------
/examples/helpers/stats/example.rb:
--------------------------------------------------------------------------------
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, 1)
11 | to = Date.new(2017, 10, 12)
12 |
13 | email_stats = stats.by_day(from, to)
14 |
15 | email_stats.metrics
16 |
17 | unless 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, 1)
29 | to = Date.new(2017, 10, 12)
30 | category = 'abcd'
31 |
32 | email_stats = stats.by_week(from, to, category)
33 |
34 | unless 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
43 |
--------------------------------------------------------------------------------
/examples/ips/ips.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve all IP addresses #
7 | # GET /ips #
8 |
9 | params = JSON.parse('{"subuser": "test_string", "ip": "test_string", "limit": 1, "exclude_whitelabels": "true", "offset": 1}')
10 | response = sg.client.ips.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Retrieve all assigned IPs #
17 | # GET /ips/assigned #
18 |
19 | response = sg.client.ips.assigned.get
20 | puts response.status_code
21 | puts response.body
22 | puts response.headers
23 |
24 | ##################################################
25 | # Retrieve unassigned IPs #
26 | # GET /ips #
27 |
28 | params = {}
29 | response = sg.client.ips.get(query_params: params)
30 | all_ips = JSON.parse(response.body)
31 | unassigned_ips = all_ips.select { |ip| ip.subusers.empty? }
32 | puts response.status_code
33 | puts response.body
34 | puts unassigned_ips
35 | puts response.headers
36 |
37 | ##################################################
38 | # Create an IP pool. #
39 | # POST /ips/pools #
40 |
41 | data = JSON.parse('{
42 | "name": "marketing"
43 | }')
44 | response = sg.client.ips.pools.post(request_body: data)
45 | puts response.status_code
46 | puts response.body
47 | puts response.headers
48 |
49 | ##################################################
50 | # Retrieve all IP pools. #
51 | # GET /ips/pools #
52 |
53 | response = sg.client.ips.pools.get
54 | puts response.status_code
55 | puts response.body
56 | puts response.headers
57 |
58 | ##################################################
59 | # Update an IP pools name. #
60 | # PUT /ips/pools/{pool_name} #
61 |
62 | data = JSON.parse('{
63 | "name": "new_pool_name"
64 | }')
65 | pool_name = 'test_url_param'
66 | response = sg.client.ips.pools._(pool_name).put(request_body: data)
67 | puts response.status_code
68 | puts response.body
69 | puts response.headers
70 |
71 | ##################################################
72 | # Retrieve all IPs in a specified pool. #
73 | # GET /ips/pools/{pool_name} #
74 |
75 | pool_name = 'test_url_param'
76 | response = sg.client.ips.pools._(pool_name).get
77 | puts response.status_code
78 | puts response.body
79 | puts response.headers
80 |
81 | ##################################################
82 | # Delete an IP pool. #
83 | # DELETE /ips/pools/{pool_name} #
84 |
85 | pool_name = 'test_url_param'
86 | response = sg.client.ips.pools._(pool_name).delete
87 | puts response.status_code
88 | puts response.body
89 | puts response.headers
90 |
91 | ##################################################
92 | # Add an IP address to a pool #
93 | # POST /ips/pools/{pool_name}/ips #
94 |
95 | data = JSON.parse('{
96 | "ip": "0.0.0.0"
97 | }')
98 | pool_name = 'test_url_param'
99 | response = sg.client.ips.pools._(pool_name).ips.post(request_body: data)
100 | puts response.status_code
101 | puts response.body
102 | puts response.headers
103 |
104 | ##################################################
105 | # Remove an IP address from a pool. #
106 | # DELETE /ips/pools/{pool_name}/ips/{ip} #
107 |
108 | pool_name = 'test_url_param'
109 | ip = 'test_url_param'
110 | response = sg.client.ips.pools._(pool_name).ips._(ip).delete
111 | puts response.status_code
112 | puts response.body
113 | puts response.headers
114 |
115 | ##################################################
116 | # Add an IP to warmup #
117 | # POST /ips/warmup #
118 |
119 | data = JSON.parse('{
120 | "ip": "0.0.0.0"
121 | }')
122 | response = sg.client.ips.warmup.post(request_body: data)
123 | puts response.status_code
124 | puts response.body
125 | puts response.headers
126 |
127 | ##################################################
128 | # Retrieve all IPs currently in warmup #
129 | # GET /ips/warmup #
130 |
131 | response = sg.client.ips.warmup.get
132 | puts response.status_code
133 | puts response.body
134 | puts response.headers
135 |
136 | ##################################################
137 | # Retrieve warmup status for a specific IP address #
138 | # GET /ips/warmup/{ip_address} #
139 |
140 | ip_address = 'test_url_param'
141 | response = sg.client.ips.warmup._(ip_address).get
142 | puts response.status_code
143 | puts response.body
144 | puts response.headers
145 |
146 | ##################################################
147 | # Remove an IP from warmup #
148 | # DELETE /ips/warmup/{ip_address} #
149 |
150 | ip_address = 'test_url_param'
151 | response = sg.client.ips.warmup._(ip_address).delete
152 | puts response.status_code
153 | puts response.body
154 | puts response.headers
155 |
156 | ##################################################
157 | # Retrieve all IP pools an IP address belongs to #
158 | # GET /ips/{ip_address} #
159 |
160 | ip_address = 'test_url_param'
161 | response = sg.client.ips._(ip_address).get
162 | puts response.status_code
163 | puts response.body
164 | puts response.headers
165 |
--------------------------------------------------------------------------------
/examples/mail/mail.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create a batch ID #
7 | # POST /mail/batch #
8 |
9 | response = sg.client.mail.batch.post
10 | puts response.status_code
11 | puts response.body
12 | puts response.headers
13 |
14 | ##################################################
15 | # Validate batch ID #
16 | # GET /mail/batch/{batch_id} #
17 |
18 | batch_id = 'test_url_param'
19 | response = sg.client.mail.batch._(batch_id).get
20 | puts response.status_code
21 | puts response.body
22 | puts response.headers
23 |
24 | ##################################################
25 | # v3 Mail Send #
26 | # POST /mail/send #
27 | # This endpoint has a helper, check it out [here](https://github.com/sendgrid/sendgrid-ruby/blob/HEAD/lib/sendgrid/helpers/mail/README.md).
28 |
29 | data = JSON.parse('{
30 | "asm": {
31 | "group_id": 1,
32 | "groups_to_display": [
33 | 1,
34 | 2,
35 | 3
36 | ]
37 | },
38 | "attachments": [
39 | {
40 | "content": "[BASE64 encoded content block here]",
41 | "content_id": "ii_139db99fdb5c3704",
42 | "disposition": "inline",
43 | "filename": "file1.jpg",
44 | "name": "file1",
45 | "type": "jpg"
46 | }
47 | ],
48 | "batch_id": "[YOUR BATCH ID GOES HERE]",
49 | "categories": [
50 | "category1",
51 | "category2"
52 | ],
53 | "content": [
54 | {
55 | "type": "text/html",
56 | "value": "Hello, world!
"
57 | }
58 | ],
59 | "custom_args": {
60 | "New Argument 1": "New Value 1",
61 | "activationAttempt": "1",
62 | "customerAccountNumber": "[CUSTOMER ACCOUNT NUMBER GOES HERE]"
63 | },
64 | "from": {
65 | "email": "sam.smith@example.com",
66 | "name": "Sam Smith"
67 | },
68 | "headers": {},
69 | "ip_pool_name": "[YOUR POOL NAME GOES HERE]",
70 | "mail_settings": {
71 | "bcc": {
72 | "email": "ben.doe@example.com",
73 | "enable": true
74 | },
75 | "bypass_list_management": {
76 | "enable": true
77 | },
78 | "footer": {
79 | "enable": true,
80 | "html": "ThanksThe Twilio SendGrid Team
",
81 | "text": "Thanks,/n The Twilio SendGrid Team"
82 | },
83 | "sandbox_mode": {
84 | "enable": false
85 | },
86 | "spam_check": {
87 | "enable": true,
88 | "post_to_url": "http://example.com/compliance",
89 | "threshold": 3
90 | }
91 | },
92 | "personalizations": [
93 | {
94 | "bcc": [
95 | {
96 | "email": "sam.doe@example.com",
97 | "name": "Sam Doe"
98 | }
99 | ],
100 | "cc": [
101 | {
102 | "email": "jane.doe@example.com",
103 | "name": "Jane Doe"
104 | }
105 | ],
106 | "custom_args": {
107 | "New Argument 1": "New Value 1",
108 | "activationAttempt": "1",
109 | "customerAccountNumber": "[CUSTOMER ACCOUNT NUMBER GOES HERE]"
110 | },
111 | "headers": {
112 | "X-Accept-Language": "en",
113 | "X-Mailer": "MyApp"
114 | },
115 | "send_at": 1409348513,
116 | "subject": "Hello, World!",
117 | "substitutions": {
118 | "id": "substitutions",
119 | "type": "object"
120 | },
121 | "to": [
122 | {
123 | "email": "john.doe@example.com",
124 | "name": "John Doe"
125 | }
126 | ]
127 | }
128 | ],
129 | "reply_to": {
130 | "email": "sam.smith@example.com",
131 | "name": "Sam Smith"
132 | },
133 | "sections": {
134 | "section": {
135 | ":sectionName1": "section 1 text",
136 | ":sectionName2": "section 2 text"
137 | }
138 | },
139 | "send_at": 1409348513,
140 | "subject": "Hello, World!",
141 | "template_id": "[YOUR TEMPLATE ID GOES HERE]",
142 | "tracking_settings": {
143 | "click_tracking": {
144 | "enable": true,
145 | "enable_text": true
146 | },
147 | "ganalytics": {
148 | "enable": true,
149 | "utm_campaign": "[NAME OF YOUR REFERRER SOURCE]",
150 | "utm_content": "[USE THIS SPACE TO DIFFERENTIATE YOUR EMAIL FROM ADS]",
151 | "utm_medium": "[NAME OF YOUR MARKETING MEDIUM e.g. email]",
152 | "utm_name": "[NAME OF YOUR CAMPAIGN]",
153 | "utm_term": "[IDENTIFY PAID KEYWORDS HERE]"
154 | },
155 | "open_tracking": {
156 | "enable": true,
157 | "substitution_tag": "%opentrack"
158 | },
159 | "subscription_tracking": {
160 | "enable": true,
161 | "html": "If you would like to unsubscribe and stop receiving these emails <% clickhere %>.",
162 | "substitution_tag": "<%click here%>",
163 | "text": "If you would like to unsubscribe and stop receiveing these emails <% click here %>."
164 | }
165 | }
166 | }')
167 | response = sg.client.mail._('send').post(request_body: data)
168 | puts response.status_code
169 | puts response.body
170 | puts response.headers
171 |
--------------------------------------------------------------------------------
/examples/mailboxproviders/mailboxproviders.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve email statistics by mailbox provider. #
7 | # GET /mailbox_providers/stats #
8 |
9 | params = JSON.parse('{"end_date": "2016-04-01", "mailbox_providers": "test_string", "aggregated_by": "day", "limit": 1, "offset": 1, "start_date": "2016-01-01"}')
10 | response = sg.client.mailbox_providers.stats.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
--------------------------------------------------------------------------------
/examples/mailsettings/mailsettings.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve all mail settings #
7 | # GET /mail_settings #
8 |
9 | params = JSON.parse('{"limit": 1, "offset": 1}')
10 | response = sg.client.mail_settings.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Update address whitelist mail settings #
17 | # PATCH /mail_settings/address_whitelist #
18 |
19 | data = JSON.parse('{
20 | "enabled": true,
21 | "list": [
22 | "email1@example.com",
23 | "example.com"
24 | ]
25 | }')
26 | response = sg.client.mail_settings.address_whitelist.patch(request_body: data)
27 | puts response.status_code
28 | puts response.body
29 | puts response.headers
30 |
31 | ##################################################
32 | # Retrieve address whitelist mail settings #
33 | # GET /mail_settings/address_whitelist #
34 |
35 | response = sg.client.mail_settings.address_whitelist.get
36 | puts response.status_code
37 | puts response.body
38 | puts response.headers
39 |
40 | ##################################################
41 | # Update BCC mail settings #
42 | # PATCH /mail_settings/bcc #
43 |
44 | data = JSON.parse('{
45 | "email": "email@example.com",
46 | "enabled": false
47 | }')
48 | response = sg.client.mail_settings.bcc.patch(request_body: data)
49 | puts response.status_code
50 | puts response.body
51 | puts response.headers
52 |
53 | ##################################################
54 | # Retrieve all BCC mail settings #
55 | # GET /mail_settings/bcc #
56 |
57 | response = sg.client.mail_settings.bcc.get
58 | puts response.status_code
59 | puts response.body
60 | puts response.headers
61 |
62 | ##################################################
63 | # Update bounce purge mail settings #
64 | # PATCH /mail_settings/bounce_purge #
65 |
66 | data = JSON.parse('{
67 | "enabled": true,
68 | "hard_bounces": 5,
69 | "soft_bounces": 5
70 | }')
71 | response = sg.client.mail_settings.bounce_purge.patch(request_body: data)
72 | puts response.status_code
73 | puts response.body
74 | puts response.headers
75 |
76 | ##################################################
77 | # Retrieve bounce purge mail settings #
78 | # GET /mail_settings/bounce_purge #
79 |
80 | response = sg.client.mail_settings.bounce_purge.get
81 | puts response.status_code
82 | puts response.body
83 | puts response.headers
84 |
85 | ##################################################
86 | # Update footer mail settings #
87 | # PATCH /mail_settings/footer #
88 |
89 | data = JSON.parse('{
90 | "enabled": true,
91 | "html_content": "...",
92 | "plain_content": "..."
93 | }')
94 | response = sg.client.mail_settings.footer.patch(request_body: data)
95 | puts response.status_code
96 | puts response.body
97 | puts response.headers
98 |
99 | ##################################################
100 | # Retrieve footer mail settings #
101 | # GET /mail_settings/footer #
102 |
103 | response = sg.client.mail_settings.footer.get
104 | puts response.status_code
105 | puts response.body
106 | puts response.headers
107 |
108 | ##################################################
109 | # Update forward bounce mail settings #
110 | # PATCH /mail_settings/forward_bounce #
111 |
112 | data = JSON.parse('{
113 | "email": "example@example.com",
114 | "enabled": true
115 | }')
116 | response = sg.client.mail_settings.forward_bounce.patch(request_body: data)
117 | puts response.status_code
118 | puts response.body
119 | puts response.headers
120 |
121 | ##################################################
122 | # Retrieve forward bounce mail settings #
123 | # GET /mail_settings/forward_bounce #
124 |
125 | response = sg.client.mail_settings.forward_bounce.get
126 | puts response.status_code
127 | puts response.body
128 | puts response.headers
129 |
130 | ##################################################
131 | # Update forward spam mail settings #
132 | # PATCH /mail_settings/forward_spam #
133 |
134 | data = JSON.parse('{
135 | "email": "",
136 | "enabled": false
137 | }')
138 | response = sg.client.mail_settings.forward_spam.patch(request_body: data)
139 | puts response.status_code
140 | puts response.body
141 | puts response.headers
142 |
143 | ##################################################
144 | # Retrieve forward spam mail settings #
145 | # GET /mail_settings/forward_spam #
146 |
147 | response = sg.client.mail_settings.forward_spam.get
148 | puts response.status_code
149 | puts response.body
150 | puts response.headers
151 |
152 | ##################################################
153 | # Update plain content mail settings #
154 | # PATCH /mail_settings/plain_content #
155 |
156 | data = JSON.parse('{
157 | "enabled": false
158 | }')
159 | response = sg.client.mail_settings.plain_content.patch(request_body: data)
160 | puts response.status_code
161 | puts response.body
162 | puts response.headers
163 |
164 | ##################################################
165 | # Retrieve plain content mail settings #
166 | # GET /mail_settings/plain_content #
167 |
168 | response = sg.client.mail_settings.plain_content.get
169 | puts response.status_code
170 | puts response.body
171 | puts response.headers
172 |
173 | ##################################################
174 | # Update spam check mail settings #
175 | # PATCH /mail_settings/spam_check #
176 |
177 | data = JSON.parse('{
178 | "enabled": true,
179 | "max_score": 5,
180 | "url": "url"
181 | }')
182 | response = sg.client.mail_settings.spam_check.patch(request_body: data)
183 | puts response.status_code
184 | puts response.body
185 | puts response.headers
186 |
187 | ##################################################
188 | # Retrieve spam check mail settings #
189 | # GET /mail_settings/spam_check #
190 |
191 | response = sg.client.mail_settings.spam_check.get
192 | puts response.status_code
193 | puts response.body
194 | puts response.headers
195 |
196 | ##################################################
197 | # Update template mail settings #
198 | # PATCH /mail_settings/template #
199 |
200 | data = JSON.parse('{
201 | "enabled": true,
202 | "html_content": "<% body %>"
203 | }')
204 | response = sg.client.mail_settings.template.patch(request_body: data)
205 | puts response.status_code
206 | puts response.body
207 | puts response.headers
208 |
209 | ##################################################
210 | # Retrieve legacy template mail settings #
211 | # GET /mail_settings/template #
212 |
213 | response = sg.client.mail_settings.template.get
214 | puts response.status_code
215 | puts response.body
216 | puts response.headers
217 |
--------------------------------------------------------------------------------
/examples/partnersettings/partnersettings.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Returns a list of all partner settings. #
7 | # GET /partner_settings #
8 |
9 | params = JSON.parse('{"limit": 1, "offset": 1}')
10 | response = sg.client.partner_settings.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Updates New Relic partner settings. #
17 | # PATCH /partner_settings/new_relic #
18 |
19 | data = JSON.parse('{
20 | "enable_subuser_statistics": true,
21 | "enabled": true,
22 | "license_key": ""
23 | }')
24 | response = sg.client.partner_settings.new_relic.patch(request_body: data)
25 | puts response.status_code
26 | puts response.body
27 | puts response.headers
28 |
29 | ##################################################
30 | # Returns all New Relic partner settings. #
31 | # GET /partner_settings/new_relic #
32 |
33 | response = sg.client.partner_settings.new_relic.get
34 | puts response.status_code
35 | puts response.body
36 | puts response.headers
37 |
--------------------------------------------------------------------------------
/examples/scopes/scopes.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../lib/sendgrid-ruby'
2 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
3 |
4 | ##################################################
5 | # Retrieve a list of scopes for which this user has access. #
6 | # GET /scopes #
7 |
8 | response = sg.client.scopes.get
9 | puts response.status_code
10 | puts response.body
11 | puts response.headers
12 |
13 | ##################################################
14 | # Update the name & scopes of an API Key #
15 | # PUT /api_keys/{api_key_id} #
16 |
17 | scopes = [
18 | "user.profile.read",
19 | "user.profile.update"
20 | ]
21 |
22 | data = {
23 | "name": "A New Hope",
24 | "scopes": scopes
25 | }
26 | api_key_id = "test_url_param"
27 | response = sg.client.api_keys._(api_key_id).put(request_body: data)
28 | puts response.status_code
29 | puts response.body
30 | puts response.headers
31 |
32 | # The above method shows how to update the scopes
33 | # To get various scopes that each of the endpoint has, use the following
34 |
35 | # To get all admin permissions
36 | scopes = SendGrid::Scope.admin_permissions
37 |
38 | # To get all read only permissions
39 | scopes = SendGrid::Scope.read_only_permissions
40 |
41 | # There are two methods for each endpoints, namely
42 | # {endpoint}_read_only_permissions and {endpoint}_full_access_permissions
43 |
44 | # These are the endpoints :
45 | # alerts, api_keys, asm_groups, billing, categories, credentials, stats, ips, mail_settings, mail,
46 | # marketing_campaigns, partner_settings, scheduled_sends, subusers, suppression, teammates,
47 | # templates, tracking_settings, user_settings, webhooks, whitelabel, access_settings
48 |
49 | # read only permissions for alerts
50 | scopes = SendGrid::Scope.alerts_read_only_permissions
51 |
52 | # full access permissions for alerts
53 | scopes = SendGrid::Scope.alerts_full_access_permissions
54 |
55 | # read only permissions for billing
56 | scopes = SendGrid::Scope.billing_read_only_permissions
57 |
58 | # full access permissions for billing
59 | scopes = SendGrid::Scope.billing_full_access_permissions
60 |
--------------------------------------------------------------------------------
/examples/senders/senders.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create a Sender Identity #
7 | # POST /senders #
8 |
9 | data = JSON.parse('{
10 | "address": "123 Elm St.",
11 | "address_2": "Apt. 456",
12 | "city": "Denver",
13 | "country": "United States",
14 | "from": {
15 | "email": "from@example.com",
16 | "name": "Example INC"
17 | },
18 | "nickname": "My Sender ID",
19 | "reply_to": {
20 | "email": "replyto@example.com",
21 | "name": "Example INC"
22 | },
23 | "state": "Colorado",
24 | "zip": "80202"
25 | }')
26 | response = sg.client.senders.post(request_body: data)
27 | puts response.status_code
28 | puts response.body
29 | puts response.headers
30 |
31 | ##################################################
32 | # Get all Sender Identities #
33 | # GET /senders #
34 |
35 | response = sg.client.senders.get
36 | puts response.status_code
37 | puts response.body
38 | puts response.headers
39 |
40 | ##################################################
41 | # Update a Sender Identity #
42 | # PATCH /senders/{sender_id} #
43 |
44 | data = JSON.parse('{
45 | "address": "123 Elm St.",
46 | "address_2": "Apt. 456",
47 | "city": "Denver",
48 | "country": "United States",
49 | "from": {
50 | "email": "from@example.com",
51 | "name": "Example INC"
52 | },
53 | "nickname": "My Sender ID",
54 | "reply_to": {
55 | "email": "replyto@example.com",
56 | "name": "Example INC"
57 | },
58 | "state": "Colorado",
59 | "zip": "80202"
60 | }')
61 | sender_id = 'test_url_param'
62 | response = sg.client.senders._(sender_id).patch(request_body: data)
63 | puts response.status_code
64 | puts response.body
65 | puts response.headers
66 |
67 | ##################################################
68 | # View a Sender Identity #
69 | # GET /senders/{sender_id} #
70 |
71 | sender_id = 'test_url_param'
72 | response = sg.client.senders._(sender_id).get
73 | puts response.status_code
74 | puts response.body
75 | puts response.headers
76 |
77 | ##################################################
78 | # Delete a Sender Identity #
79 | # DELETE /senders/{sender_id} #
80 |
81 | sender_id = 'test_url_param'
82 | response = sg.client.senders._(sender_id).delete
83 | puts response.status_code
84 | puts response.body
85 | puts response.headers
86 |
87 | ##################################################
88 | # Resend Sender Identity Verification #
89 | # POST /senders/{sender_id}/resend_verification #
90 |
91 | sender_id = 'test_url_param'
92 | response = sg.client.senders._(sender_id).resend_verification.post
93 | puts response.status_code
94 | puts response.body
95 | puts response.headers
96 |
--------------------------------------------------------------------------------
/examples/stats/stats.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve global email statistics #
7 | # GET /stats #
8 |
9 | params = JSON.parse('{"aggregated_by": "day", "limit": 1, "start_date": "2016-01-01", "end_date": "2016-04-01", "offset": 1}')
10 | response = sg.client.stats.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
--------------------------------------------------------------------------------
/examples/subusers/subusers.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create Subuser #
7 | # POST /subusers #
8 |
9 | data = JSON.parse('{
10 | "email": "John@example.com",
11 | "ips": [
12 | "1.1.1.1",
13 | "2.2.2.2"
14 | ],
15 | "password": "johns_password",
16 | "username": "John@example.com"
17 | }')
18 | response = sg.client.subusers.post(request_body: data)
19 | puts response.status_code
20 | puts response.body
21 | puts response.headers
22 |
23 | ##################################################
24 | # List all Subusers #
25 | # GET /subusers #
26 |
27 | params = JSON.parse('{"username": "test_string", "limit": 1, "offset": 1}')
28 | response = sg.client.subusers.get(query_params: params)
29 | puts response.status_code
30 | puts response.body
31 | puts response.headers
32 |
33 | ##################################################
34 | # Retrieve Subuser Reputations #
35 | # GET /subusers/reputations #
36 |
37 | params = JSON.parse('{"usernames": "test_string"}')
38 | response = sg.client.subusers.reputations.get(query_params: params)
39 | puts response.status_code
40 | puts response.body
41 | puts response.headers
42 |
43 | ##################################################
44 | # Retrieve email statistics for your subusers. #
45 | # GET /subusers/stats #
46 |
47 | params = JSON.parse('{"end_date": "2016-04-01", "aggregated_by": "day", "limit": 1, "offset": 1, "start_date": "2016-01-01", "subusers": "test_string"}')
48 | response = sg.client.subusers.stats.get(query_params: params)
49 | puts response.status_code
50 | puts response.body
51 | puts response.headers
52 |
53 | ##################################################
54 | # Retrieve monthly stats for all subusers #
55 | # GET /subusers/stats/monthly #
56 |
57 | params = JSON.parse('{"subuser": "test_string", "limit": 1, "sort_by_metric": "test_string", "offset": 1, "date": "test_string", "sort_by_direction": "asc"}')
58 | response = sg.client.subusers.stats.monthly.get(query_params: params)
59 | puts response.status_code
60 | puts response.body
61 | puts response.headers
62 |
63 | ##################################################
64 | # Retrieve the totals for each email statistic metric for all subusers. #
65 | # GET /subusers/stats/sums #
66 |
67 | params = JSON.parse('{"end_date": "2016-04-01", "aggregated_by": "day", "limit": 1, "sort_by_metric": "test_string", "offset": 1, "start_date": "2016-01-01", "sort_by_direction": "asc"}')
68 | response = sg.client.subusers.stats.sums.get(query_params: params)
69 | puts response.status_code
70 | puts response.body
71 | puts response.headers
72 |
73 | ##################################################
74 | # Enable/disable a subuser #
75 | # PATCH /subusers/{subuser_name} #
76 |
77 | data = JSON.parse('{
78 | "disabled": false
79 | }')
80 | subuser_name = 'test_url_param'
81 | response = sg.client.subusers._(subuser_name).patch(request_body: data)
82 | puts response.status_code
83 | puts response.body
84 | puts response.headers
85 |
86 | ##################################################
87 | # Delete a subuser #
88 | # DELETE /subusers/{subuser_name} #
89 |
90 | subuser_name = 'test_url_param'
91 | response = sg.client.subusers._(subuser_name).delete
92 | puts response.status_code
93 | puts response.body
94 | puts response.headers
95 |
96 | ##################################################
97 | # Update IPs assigned to a subuser #
98 | # PUT /subusers/{subuser_name}/ips #
99 |
100 | data = JSON.parse('[
101 | "127.0.0.1"
102 | ]')
103 | subuser_name = 'test_url_param'
104 | response = sg.client.subusers._(subuser_name).ips.put(request_body: data)
105 | puts response.status_code
106 | puts response.body
107 | puts response.headers
108 |
109 | ##################################################
110 | # Update Monitor Settings for a subuser #
111 | # PUT /subusers/{subuser_name}/monitor #
112 |
113 | data = JSON.parse('{
114 | "email": "example@example.com",
115 | "frequency": 500
116 | }')
117 | subuser_name = 'test_url_param'
118 | response = sg.client.subusers._(subuser_name).monitor.put(request_body: data)
119 | puts response.status_code
120 | puts response.body
121 | puts response.headers
122 |
123 | ##################################################
124 | # Create monitor settings #
125 | # POST /subusers/{subuser_name}/monitor #
126 |
127 | data = JSON.parse('{
128 | "email": "example@example.com",
129 | "frequency": 50000
130 | }')
131 | subuser_name = 'test_url_param'
132 | response = sg.client.subusers._(subuser_name).monitor.post(request_body: data)
133 | puts response.status_code
134 | puts response.body
135 | puts response.headers
136 |
137 | ##################################################
138 | # Retrieve monitor settings for a subuser #
139 | # GET /subusers/{subuser_name}/monitor #
140 |
141 | subuser_name = 'test_url_param'
142 | response = sg.client.subusers._(subuser_name).monitor.get
143 | puts response.status_code
144 | puts response.body
145 | puts response.headers
146 |
147 | ##################################################
148 | # Delete monitor settings #
149 | # DELETE /subusers/{subuser_name}/monitor #
150 |
151 | subuser_name = 'test_url_param'
152 | response = sg.client.subusers._(subuser_name).monitor.delete
153 | puts response.status_code
154 | puts response.body
155 | puts response.headers
156 |
157 | ##################################################
158 | # Retrieve the monthly email statistics for a single subuser #
159 | # GET /subusers/{subuser_name}/stats/monthly #
160 |
161 | params = JSON.parse('{"date": "test_string", "sort_by_direction": "asc", "limit": 1, "sort_by_metric": "test_string", "offset": 1}')
162 | subuser_name = 'test_url_param'
163 | response = sg.client.subusers._(subuser_name).stats.monthly.get(query_params: params)
164 | puts response.status_code
165 | puts response.body
166 | puts response.headers
167 |
--------------------------------------------------------------------------------
/examples/suppression/suppression.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve all blocks #
7 | # GET /suppression/blocks #
8 |
9 | params = JSON.parse('{"start_time": 1, "limit": 1, "end_time": 1, "offset": 1}')
10 | response = sg.client.suppression.blocks.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Delete blocks #
17 | # DELETE /suppression/blocks #
18 |
19 | data = JSON.parse('{
20 | "delete_all": false,
21 | "emails": [
22 | "example1@example.com",
23 | "example2@example.com"
24 | ]
25 | }')
26 | response = sg.client.suppression.blocks.delete(request_body: data)
27 | puts response.status_code
28 | puts response.body
29 | puts response.headers
30 |
31 | ##################################################
32 | # Retrieve a specific block #
33 | # GET /suppression/blocks/{email} #
34 |
35 | email = 'test_url_param'
36 | response = sg.client.suppression.blocks._(email).get
37 | puts response.status_code
38 | puts response.body
39 | puts response.headers
40 |
41 | ##################################################
42 | # Delete a specific block #
43 | # DELETE /suppression/blocks/{email} #
44 |
45 | email = 'test_url_param'
46 | response = sg.client.suppression.blocks._(email).delete
47 | puts response.status_code
48 | puts response.body
49 | puts response.headers
50 |
51 | ##################################################
52 | # Retrieve all bounces #
53 | # GET /suppression/bounces #
54 |
55 | params = JSON.parse('{"start_time": 1, "end_time": 1}')
56 | response = sg.client.suppression.bounces.get(query_params: params)
57 | puts response.status_code
58 | puts response.body
59 | puts response.headers
60 |
61 | ##################################################
62 | # Delete bounces #
63 | # DELETE /suppression/bounces #
64 |
65 | data = JSON.parse('{
66 | "delete_all": true,
67 | "emails": [
68 | "example@example.com",
69 | "example2@example.com"
70 | ]
71 | }')
72 | response = sg.client.suppression.bounces.delete(request_body: data)
73 | puts response.status_code
74 | puts response.body
75 | puts response.headers
76 |
77 | ##################################################
78 | # Retrieve a Bounce #
79 | # GET /suppression/bounces/{email} #
80 |
81 | email = 'test_url_param'
82 | response = sg.client.suppression.bounces._(email).get
83 | puts response.status_code
84 | puts response.body
85 | puts response.headers
86 |
87 | ##################################################
88 | # Delete a bounce #
89 | # DELETE /suppression/bounces/{email} #
90 |
91 | params = JSON.parse('{"email_address": "example@example.com"}')
92 | email = 'test_url_param'
93 | response = sg.client.suppression.bounces._(email).delete(query_params: params)
94 | puts response.status_code
95 | puts response.body
96 | puts response.headers
97 |
98 | ##################################################
99 | # Retrieve all invalid emails #
100 | # GET /suppression/invalid_emails #
101 |
102 | params = JSON.parse('{"start_time": 1, "limit": 1, "end_time": 1, "offset": 1}')
103 | response = sg.client.suppression.invalid_emails.get(query_params: params)
104 | puts response.status_code
105 | puts response.body
106 | puts response.headers
107 |
108 | ##################################################
109 | # Delete invalid emails #
110 | # DELETE /suppression/invalid_emails #
111 |
112 | data = JSON.parse('{
113 | "delete_all": false,
114 | "emails": [
115 | "example1@example.com",
116 | "example2@example.com"
117 | ]
118 | }')
119 | response = sg.client.suppression.invalid_emails.delete(request_body: data)
120 | puts response.status_code
121 | puts response.body
122 | puts response.headers
123 |
124 | ##################################################
125 | # Retrieve a specific invalid email #
126 | # GET /suppression/invalid_emails/{email} #
127 |
128 | email = 'test_url_param'
129 | response = sg.client.suppression.invalid_emails._(email).get
130 | puts response.status_code
131 | puts response.body
132 | puts response.headers
133 |
134 | ##################################################
135 | # Delete a specific invalid email #
136 | # DELETE /suppression/invalid_emails/{email} #
137 |
138 | email = 'test_url_param'
139 | response = sg.client.suppression.invalid_emails._(email).delete
140 | puts response.status_code
141 | puts response.body
142 | puts response.headers
143 |
144 | ##################################################
145 | # Retrieve a specific spam report #
146 | # GET /suppression/spam_report/{email} #
147 |
148 | email = 'test_url_param'
149 | response = sg.client.suppression.spam_report._(email).get
150 | puts response.status_code
151 | puts response.body
152 | puts response.headers
153 |
154 | ##################################################
155 | # Delete a specific spam report #
156 | # DELETE /suppression/spam_report/{email} #
157 |
158 | email = 'test_url_param'
159 | response = sg.client.suppression.spam_reports._(email).delete
160 | puts response.status_code
161 | puts response.body
162 | puts response.headers
163 |
164 | ##################################################
165 | # Retrieve all spam reports #
166 | # GET /suppression/spam_reports #
167 |
168 | params = JSON.parse('{"start_time": 1, "limit": 1, "end_time": 1, "offset": 1}')
169 | response = sg.client.suppression.spam_reports.get(query_params: params)
170 | puts response.status_code
171 | puts response.body
172 | puts response.headers
173 |
174 | ##################################################
175 | # Delete spam reports #
176 | # DELETE /suppression/spam_reports #
177 |
178 | data = JSON.parse('{
179 | "delete_all": false,
180 | "emails": [
181 | "example1@example.com",
182 | "example2@example.com"
183 | ]
184 | }')
185 | response = sg.client.suppression.spam_reports.delete(request_body: data)
186 | puts response.status_code
187 | puts response.body
188 | puts response.headers
189 |
190 | ##################################################
191 | # Retrieve all global suppressions #
192 | # GET /suppression/unsubscribes #
193 |
194 | params = JSON.parse('{"start_time": 1, "limit": 1, "end_time": 1, "offset": 1}')
195 | response = sg.client.suppression.unsubscribes.get(query_params: params)
196 | puts response.status_code
197 | puts response.body
198 | puts response.headers
199 |
--------------------------------------------------------------------------------
/examples/templates/templates.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Create a transactional template. #
7 | # POST /templates #
8 |
9 | data = JSON.parse('{
10 | "name": "example_name"
11 | }')
12 | response = sg.client.templates.post(request_body: data)
13 | puts response.status_code
14 | puts response.body
15 | puts response.headers
16 |
17 | ##################################################
18 | # Retrieve all transactional templates (legacy & dynamic). #
19 | # GET /templates #
20 |
21 | params = JSON.parse('{"generations": "legacy,dynamic"}')
22 | response = sg.client.templates.get(query_params: params)
23 | puts response.status_code
24 | puts response.body
25 | puts response.headers
26 |
27 | ##################################################
28 | # Edit a transactional template. #
29 | # PATCH /templates/{template_id} #
30 |
31 | data = JSON.parse('{
32 | "name": "new_example_name"
33 | }')
34 | template_id = 'test_url_param'
35 | response = sg.client.templates._(template_id).patch(request_body: data)
36 | puts response.status_code
37 | puts response.body
38 | puts response.headers
39 |
40 | ##################################################
41 | # Retrieve a single transactional template. #
42 | # GET /templates/{template_id} #
43 |
44 | template_id = 'test_url_param'
45 | response = sg.client.templates._(template_id).get
46 | puts response.status_code
47 | puts response.body
48 | puts response.headers
49 |
50 | ##################################################
51 | # Delete a template. #
52 | # DELETE /templates/{template_id} #
53 |
54 | template_id = 'test_url_param'
55 | response = sg.client.templates._(template_id).delete
56 | puts response.status_code
57 | puts response.body
58 | puts response.headers
59 |
60 | ##################################################
61 | # Create a new transactional template version. #
62 | # POST /templates/{template_id}/versions #
63 |
64 | data = JSON.parse('{
65 | "active": 1,
66 | "html_content": "<%body%>",
67 | "name": "example_version_name",
68 | "plain_content": "<%body%>",
69 | "subject": "<%subject%>",
70 | "template_id": "ddb96bbc-9b92-425e-8979-99464621b543"
71 | }')
72 | template_id = 'test_url_param'
73 | response = sg.client.templates._(template_id).versions.post(request_body: data)
74 | puts response.status_code
75 | puts response.body
76 | puts response.headers
77 |
78 | ##################################################
79 | # Edit a transactional template version. #
80 | # PATCH /templates/{template_id}/versions/{version_id} #
81 |
82 | data = JSON.parse('{
83 | "active": 1,
84 | "html_content": "<%body%>",
85 | "name": "updated_example_name",
86 | "plain_content": "<%body%>",
87 | "subject": "<%subject%>"
88 | }')
89 | template_id = 'test_url_param'
90 | version_id = 'test_url_param'
91 | response = sg.client.templates._(template_id).versions._(version_id).patch(request_body: data)
92 | puts response.status_code
93 | puts response.body
94 | puts response.headers
95 |
96 | ##################################################
97 | # Retrieve a specific transactional template version. #
98 | # GET /templates/{template_id}/versions/{version_id} #
99 |
100 | template_id = 'test_url_param'
101 | version_id = 'test_url_param'
102 | response = sg.client.templates._(template_id).versions._(version_id).get
103 | puts response.status_code
104 | puts response.body
105 | puts response.headers
106 |
107 | ##################################################
108 | # Delete a transactional template version. #
109 | # DELETE /templates/{template_id}/versions/{version_id} #
110 |
111 | template_id = 'test_url_param'
112 | version_id = 'test_url_param'
113 | response = sg.client.templates._(template_id).versions._(version_id).delete
114 | puts response.status_code
115 | puts response.body
116 | puts response.headers
117 |
118 | ##################################################
119 | # Activate a transactional template version. #
120 | # POST /templates/{template_id}/versions/{version_id}/activate #
121 |
122 | template_id = 'test_url_param'
123 | version_id = 'test_url_param'
124 | response = sg.client.templates._(template_id).versions._(version_id).activate.post
125 | puts response.status_code
126 | puts response.body
127 | puts response.headers
128 |
--------------------------------------------------------------------------------
/examples/trackingsettings/trackingsettings.rb:
--------------------------------------------------------------------------------
1 | require 'sendgrid-ruby'
2 |
3 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
4 |
5 | ##################################################
6 | # Retrieve Tracking Settings #
7 | # GET /tracking_settings #
8 |
9 | params = JSON.parse('{"limit": 1, "offset": 1}')
10 | response = sg.client.tracking_settings.get(query_params: params)
11 | puts response.status_code
12 | puts response.body
13 | puts response.headers
14 |
15 | ##################################################
16 | # Update Click Tracking Settings #
17 | # PATCH /tracking_settings/click #
18 |
19 | data = JSON.parse('{
20 | "enabled": true
21 | }')
22 | response = sg.client.tracking_settings.click.patch(request_body: data)
23 | puts response.status_code
24 | puts response.body
25 | puts response.headers
26 |
27 | ##################################################
28 | # Retrieve Click Track Settings #
29 | # GET /tracking_settings/click #
30 |
31 | response = sg.client.tracking_settings.click.get
32 | puts response.status_code
33 | puts response.body
34 | puts response.headers
35 |
36 | ##################################################
37 | # Update Google Analytics Settings #
38 | # PATCH /tracking_settings/google_analytics #
39 |
40 | data = JSON.parse('{
41 | "enabled": true,
42 | "utm_campaign": "website",
43 | "utm_content": "",
44 | "utm_medium": "email",
45 | "utm_source": "sendgrid.com",
46 | "utm_term": ""
47 | }')
48 | response = sg.client.tracking_settings.google_analytics.patch(request_body: data)
49 | puts response.status_code
50 | puts response.body
51 | puts response.headers
52 |
53 | ##################################################
54 | # Retrieve Google Analytics Settings #
55 | # GET /tracking_settings/google_analytics #
56 |
57 | response = sg.client.tracking_settings.google_analytics.get
58 | puts response.status_code
59 | puts response.body
60 | puts response.headers
61 |
62 | ##################################################
63 | # Update Open Tracking Settings #
64 | # PATCH /tracking_settings/open #
65 |
66 | data = JSON.parse('{
67 | "enabled": true
68 | }')
69 | response = sg.client.tracking_settings.open.patch(request_body: data)
70 | puts response.status_code
71 | puts response.body
72 | puts response.headers
73 |
74 | ##################################################
75 | # Get Open Tracking Settings #
76 | # GET /tracking_settings/open #
77 |
78 | response = sg.client.tracking_settings.open.get
79 | puts response.status_code
80 | puts response.body
81 | puts response.headers
82 |
83 | ##################################################
84 | # Update Subscription Tracking Settings #
85 | # PATCH /tracking_settings/subscription #
86 |
87 | data = JSON.parse('{
88 | "enabled": true,
89 | "html_content": "html content",
90 | "landing": "landing page html",
91 | "plain_content": "text content",
92 | "replace": "replacement tag",
93 | "url": "url"
94 | }')
95 | response = sg.client.tracking_settings.subscription.patch(request_body: data)
96 | puts response.status_code
97 | puts response.body
98 | puts response.headers
99 |
100 | ##################################################
101 | # Retrieve Subscription Tracking Settings #
102 | # GET /tracking_settings/subscription #
103 |
104 | response = sg.client.tracking_settings.subscription.get
105 | puts response.status_code
106 | puts response.body
107 | puts response.headers
108 |
--------------------------------------------------------------------------------
/gemfiles/Sinatra_1.gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | gemspec path: '..'
4 |
5 | gem 'ruby_http_client'
6 | gem 'sinatra', '~> 1.4'
7 |
--------------------------------------------------------------------------------
/gemfiles/Sinatra_2.gemfile:
--------------------------------------------------------------------------------
1 | source 'http://rubygems.org'
2 |
3 | gemspec path: '..'
4 |
5 | gem 'ruby_http_client'
6 | gem 'sinatra', '>= 2.0.0.rc2'
7 |
--------------------------------------------------------------------------------
/lib/rack/sendgrid_webhook_verification.rb:
--------------------------------------------------------------------------------
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 | request.body.rewind
43 |
44 | if verified
45 | @app.call(env)
46 | else
47 | [
48 | 403,
49 | { 'Content-Type' => 'text/plain' },
50 | ['SendGrid Request Verification Failed.']
51 | ]
52 | end
53 | end
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/lib/sendgrid-ruby.rb:
--------------------------------------------------------------------------------
1 | require_relative 'sendgrid/base_interface'
2 | require_relative 'sendgrid/sendgrid'
3 | require_relative 'sendgrid/twilio_email'
4 | require_relative 'sendgrid/version'
5 | require_relative 'sendgrid/helpers/eventwebhook/eventwebhook'
6 | require_relative 'sendgrid/helpers/ip_management/ip_management'
7 | require_relative 'sendgrid/helpers/mail/asm'
8 | require_relative 'sendgrid/helpers/mail/attachment'
9 | require_relative 'sendgrid/helpers/mail/bcc_settings'
10 | require_relative 'sendgrid/helpers/mail/bypass_list_management'
11 | require_relative 'sendgrid/helpers/mail/category'
12 | require_relative 'sendgrid/helpers/mail/click_tracking'
13 | require_relative 'sendgrid/helpers/mail/content'
14 | require_relative 'sendgrid/helpers/mail/custom_arg'
15 | require_relative 'sendgrid/helpers/mail/email'
16 | require_relative 'sendgrid/helpers/mail/footer'
17 | require_relative 'sendgrid/helpers/mail/ganalytics'
18 | require_relative 'sendgrid/helpers/mail/header'
19 | require_relative 'sendgrid/helpers/mail/mail'
20 | require_relative 'sendgrid/helpers/mail/mail_settings'
21 | require_relative 'sendgrid/helpers/mail/open_tracking'
22 | require_relative 'sendgrid/helpers/mail/personalization'
23 | require_relative 'sendgrid/helpers/mail/section'
24 | require_relative 'sendgrid/helpers/mail/spam_check'
25 | require_relative 'sendgrid/helpers/mail/subscription_tracking'
26 | require_relative 'sendgrid/helpers/mail/substitution'
27 | require_relative 'sendgrid/helpers/mail/tracking_settings'
28 | require_relative 'sendgrid/helpers/settings/settings'
29 | require_relative 'sendgrid/helpers/stats/email_stats'
30 | require_relative 'sendgrid/helpers/stats/stats_response'
31 | require_relative 'sendgrid/helpers/stats/metrics'
32 | require_relative 'sendgrid/helpers/permissions/scope'
33 | require_relative 'rack/sendgrid_webhook_verification'
34 |
--------------------------------------------------------------------------------
/lib/sendgrid/base_interface.rb:
--------------------------------------------------------------------------------
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
58 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/eventwebhook/eventwebhook.rb:
--------------------------------------------------------------------------------
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
51 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/inbound/README.md:
--------------------------------------------------------------------------------
1 | **This helper is a stand alone module to help get you started consuming and processing Inbound Parse data.**
2 |
3 | ## Table of Contents
4 |
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)
13 |
14 |
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 |
28 | # Quick Start for Local Testing with Sample Data
29 |
30 | ```bash
31 | git clone https://github.com/sendgrid/sendgrid-ruby.git
32 | cd sendgrid-ruby
33 | bundle install
34 | ```
35 |
36 | Run the Inbound Parse listener in your terminal:
37 |
38 | ```ruby
39 | rackup
40 | ```
41 |
42 | In another terminal, run the test data sender:
43 |
44 | ```bash
45 | cd [path to sendgrid-ruby]
46 | bundle install
47 | ruby ./lib/sendgrid/helpers/inbound/send.rb ./lib/sendgrid/helpers/inbound/sample_data/default_data.txt
48 | ```
49 |
50 | More sample data can be found [here](sample_data).
51 |
52 | View the results in the first terminal.
53 |
54 |
55 | # Quick Start for Local Testing with Real Data
56 |
57 | [Setup your MX records.](https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_parse_webhook.html#-Setup) Depending on your domain name host, you may need to wait up to 48 hours for the settings to propagate.
58 |
59 | Run the Inbound Parse listener in your terminal:
60 |
61 | ```bash
62 | git clone https://github.com/sendgrid/sendgrid-ruby.git
63 | cd sendgrid-ruby
64 | bundle install
65 | rackup
66 | ```
67 |
68 | In another terminal, use [ngrok](https://ngrok.com/) to allow external access to your machine:
69 | ```bash
70 | ngrok http 9292
71 | ```
72 |
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)
74 |
75 | - For the HOSTNAME field, use the domain that you changed the MX records (e.g. inbound.yourdomain.com)
76 | - For the URL field, use the URL generated by ngrok + /inbound, e.g http://XXXXXXX.ngrok.io/inbound
77 |
78 | Next, send an email to [anything]@inbound.yourdomain.com, then look at the terminal where you started the Inbound Parse listener.
79 |
80 |
81 | # Code Walkthrough
82 |
83 | ## app.rb
84 |
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 |
87 | ## config.yml
88 |
89 | This module loads application environment variables (located in [config.yml](config.yml)).
90 |
91 | ## send.rb & /sample_data
92 |
93 | This module is used to send sample test data. It is useful for testing and development, particularly while you wait for your MX records to propagate.
94 |
95 |
96 | # Contributing
97 |
98 | If you would like to contribute to this project, please see our [contributing guide](../../../../CONTRIBUTING.md). Thanks!
99 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/inbound/app.rb:
--------------------------------------------------------------------------------
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
14 | require 'logger'
15 | require 'json'
16 | require 'yaml'
17 |
18 | class Main < Sinatra::Base
19 | configure :production, :development do
20 | enable :logging
21 | set :config, YAML.load_file("#{File.dirname(__FILE__)}/config.yml")
22 | end
23 |
24 | get '/' do
25 | redirect to('index.html')
26 | end
27 |
28 | post settings.config['endpoint'] do
29 | filtered = params.select { |k, _v| settings.config['keys'].include?(k) }
30 | logger.info JSON.pretty_generate(filtered)
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/inbound/config.yml:
--------------------------------------------------------------------------------
1 | # Incoming Parse endpoint for receiver
2 | endpoint: '/inbound'
3 |
4 | # List all Incoming Parse fields you would like parsed
5 | # Reference: https://sendgrid.com/docs/Classroom/Basics/Inbound_Parse_Webhook/setting_up_the_inbound_parse_webhook.html
6 | keys:
7 | - from
8 | - attachments
9 | - headers
10 | - text
11 | - envelope
12 | - to
13 | - html
14 | - sender_ip
15 | - attachment-info
16 | - subject
17 | - dkim
18 | - SPF
19 | - charsets
20 | - content-ids
21 | - spam_report
22 | - spam_score
23 | - email
24 |
25 | # URL that the sender will POST to
26 | host: 'http://127.0.0.1:9292/inbound'
27 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/inbound/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Twilio SendGrid Incoming Parse
4 |
5 |
6 | You have successfuly launched the server!
7 |
8 | Check out the documentation on how to use this software to utilize the SendGrid Inbound Parse webhook.
9 |
10 |
11 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/inbound/sample_data/default_data.txt:
--------------------------------------------------------------------------------
1 | --xYzZY
2 | Content-Disposition: form-data; name="headers"
3 |
4 | MIME-Version: 1.0
5 | Received: by 0.0.0.0 with HTTP; Wed, 10 Aug 2016 18:10:13 -0700 (PDT)
6 | From: Example User
7 | Date: Wed, 10 Aug 2016 18:10:13 -0700
8 | Subject: Inbound Parse Test Data
9 | To: inbound@inbound.example.com
10 | Content-Type: multipart/alternative; boundary=001a113df448cad2d00539c16e89
11 |
12 | --xYzZY
13 | Content-Disposition: form-data; name="dkim"
14 |
15 | {@sendgrid.com : pass}
16 | --xYzZY
17 | Content-Disposition: form-data; name="to"
18 |
19 | inbound@inbound.example.com
20 | --xYzZY
21 | Content-Disposition: form-data; name="html"
22 |
23 | Hello Twilio SendGrid!
24 |
25 | --xYzZY
26 | Content-Disposition: form-data; name="from"
27 |
28 | Example User
29 | --xYzZY
30 | Content-Disposition: form-data; name="text"
31 |
32 | Hello Twilio SendGrid!
33 |
34 | --xYzZY
35 | Content-Disposition: form-data; name="sender_ip"
36 |
37 | 0.0.0.0
38 | --xYzZY
39 | Content-Disposition: form-data; name="envelope"
40 |
41 | {"to":["inbound@inbound.example.com"],"from":"test@example.com"}
42 | --xYzZY
43 | Content-Disposition: form-data; name="attachments"
44 |
45 | 0
46 | --xYzZY
47 | Content-Disposition: form-data; name="subject"
48 |
49 | Testing non-raw
50 | --xYzZY
51 | Content-Disposition: form-data; name="charsets"
52 |
53 | {"to":"UTF-8","html":"UTF-8","subject":"UTF-8","from":"UTF-8","text":"UTF-8"}
54 | --xYzZY
55 | Content-Disposition: form-data; name="SPF"
56 |
57 | pass
58 | --xYzZY--
59 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/inbound/sample_data/raw_data.txt:
--------------------------------------------------------------------------------
1 | --xYzZY
2 | Content-Disposition: form-data; name="dkim"
3 |
4 | {@sendgrid.com : pass}
5 | --xYzZY
6 | Content-Disposition: form-data; name="email"
7 |
8 | MIME-Version: 1.0
9 | Received: by 0.0.0.0 with HTTP; Wed, 10 Aug 2016 14:44:21 -0700 (PDT)
10 | From: Example User
11 | Date: Wed, 10 Aug 2016 14:44:21 -0700
12 | Subject: Inbound Parse Test Raw Data
13 | To: inbound@inbound.inbound.com
14 | Content-Type: multipart/alternative; boundary=001a113ee97c89842f0539be8e7a
15 |
16 | --001a113ee97c89842f0539be8e7a
17 | Content-Type: text/plain; charset=UTF-8
18 |
19 | Hello Twilio SendGrid!
20 |
21 | --001a113ee97c89842f0539be8e7a
22 | Content-Type: text/html; charset=UTF-8
23 | Content-Transfer-Encoding: quoted-printable
24 |
25 | Hello Twilio SendGrid!
26 |
27 | --001a113ee97c89842f0539be8e7a--
28 |
29 | --xYzZY
30 | Content-Disposition: form-data; name="to"
31 |
32 | inbound@inbound.inbound.com
33 | --xYzZY
34 | Content-Disposition: form-data; name="from"
35 |
36 | Example User
37 | --xYzZY
38 | Content-Disposition: form-data; name="sender_ip"
39 |
40 | 0.0.0.0
41 | --xYzZY
42 | Content-Disposition: form-data; name="envelope"
43 |
44 | {"to":["inbound@inbound.inbound.com"],"from":"test@example.com"}
45 | --xYzZY
46 | Content-Disposition: form-data; name="subject"
47 |
48 | Testing with Request.bin
49 | --xYzZY
50 | Content-Disposition: form-data; name="charsets"
51 |
52 | {"to":"UTF-8","subject":"UTF-8","from":"UTF-8"}
53 | --xYzZY
54 | Content-Disposition: form-data; name="SPF"
55 |
56 | pass
57 | --xYzZY--
58 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/inbound/send.rb:
--------------------------------------------------------------------------------
1 | # A module for sending test Twilio SendGrid Inbound Parse messages
2 | # Usage: ruby ./send.rb [path to file containing test data]
3 | require 'ruby_http_client'
4 | require 'yaml'
5 | require 'optparse'
6 |
7 | OPTS = {}.freeze
8 | opt = OptionParser.new
9 | opt.on('--host=HOST') { |v| OPTS[:host] = v }
10 | argv = opt.parse!(ARGV)
11 | config = YAML.load_file("#{File.dirname(__FILE__)}/config.yml")
12 | host = OPTS[:host] || config['host']
13 | client = SendGrid::Client.new(host: host)
14 | File.open(argv[0]) do |file|
15 | data = file.read
16 | headers = {
17 | 'User-Agent' => 'Twilio-SendGrid-Test',
18 | 'Content-Type' => 'multipart/form-data; boundary=xYzZY'
19 | }
20 | response = client.post(
21 | request_body: data, request_headers: headers
22 | )
23 | puts response.status_code
24 | puts response.body
25 | puts response.headers
26 | end
27 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/ip_management/ip_management.rb:
--------------------------------------------------------------------------------
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
18 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/README.md:
--------------------------------------------------------------------------------
1 | **This helper allows you to quickly and easily build a Mail object for sending email through Twilio SendGrid.**
2 |
3 | # Quick Start
4 |
5 | Run the [example](../../../../examples/helpers/mail) (make sure you have set your environment variable to include your SENDGRID_API_KEY).
6 |
7 | ```bash
8 | ruby examples/helpers/mail/example.rb
9 | ```
10 |
11 | ## Usage
12 |
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)
15 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/asm.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class ASM
5 | attr_accessor :group_id, :groups_to_display
6 |
7 | def initialize(group_id: nil, groups_to_display: nil)
8 | @group_id = group_id
9 | @groups_to_display = groups_to_display
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'group_id' => group_id,
15 | 'groups_to_display' => groups_to_display
16 | }.delete_if { |_, value| value.to_s.strip == '' }
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/attachment.rb:
--------------------------------------------------------------------------------
1 | require 'base64'
2 |
3 | module SendGrid
4 | class Attachment
5 | attr_accessor :type, :filename, :disposition, :content_id
6 |
7 | def initialize
8 | @content = nil
9 | @type = nil
10 | @filename = nil
11 | @disposition = nil
12 | @content_id = nil
13 | end
14 |
15 | def content=(content)
16 | @encoded_content = nil
17 | @content = content
18 | end
19 |
20 | def content
21 | return @encoded_content if @encoded_content
22 |
23 | @encoded_content = if @content.respond_to?(:read)
24 | encode @content
25 | else
26 | @content
27 | end
28 | end
29 |
30 | def to_json(*)
31 | {
32 | 'content' => content,
33 | 'type' => type,
34 | 'filename' => filename,
35 | 'disposition' => disposition,
36 | 'content_id' => content_id
37 | }.delete_if { |_, value| value.to_s.strip == '' }
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
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/bcc_settings.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class BccSettings
5 | attr_accessor :enable, :email
6 |
7 | def initialize(enable: nil, email: nil)
8 | @enable = enable
9 | @email = email
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'enable' => enable,
15 | 'email' => email
16 | }.delete_if { |_, value| value.to_s.strip == '' }
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/bypass_list_management.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class BypassListManagement
5 | attr_accessor :enable
6 |
7 | def initialize(enable: nil)
8 | @enable = enable
9 | end
10 |
11 | def to_json(*)
12 | {
13 | 'enable' => enable
14 | }.delete_if { |_, value| value.to_s.strip == '' }
15 | end
16 | end
17 |
18 | class SandBoxMode
19 | attr_accessor :enable
20 |
21 | def initialize(enable: nil)
22 | @enable = enable
23 | end
24 |
25 | def to_json(*)
26 | {
27 | 'enable' => enable
28 | }.delete_if { |_, value| value.to_s.strip == '' }
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/category.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | class Category
3 | attr_accessor :name
4 |
5 | def initialize(name: nil)
6 | @name = name
7 | end
8 |
9 | def to_json(*)
10 | {
11 | 'category' => name
12 | }.delete_if { |_, value| value.to_s.strip == '' }
13 | end
14 |
15 | alias category name
16 | alias category= name=
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/click_tracking.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class ClickTracking
5 | attr_accessor :enable, :enable_text
6 |
7 | def initialize(enable: nil, enable_text: nil)
8 | @enable = enable
9 | @enable_text = enable_text
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'enable' => enable,
15 | 'enable_text' => enable_text
16 | }.delete_if { |_, value| value.to_s.strip == '' }
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/content.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Content
5 | attr_accessor :type, :value
6 |
7 | def initialize(type: nil, value: nil)
8 | @type = type
9 | @value = value
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'type' => type,
15 | 'value' => value
16 | }.delete_if { |_, value| value.to_s.strip == '' }
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/custom_arg.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class CustomArg
5 | attr_accessor :custom_arg
6 |
7 | def initialize(key: nil, value: nil)
8 | @custom_arg = {}
9 | key.nil? || value.nil? ? @custom_arg = nil : @custom_arg[key.to_s] = value.to_s
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'custom_arg' => custom_arg
15 | }.delete_if { |_, value| value.to_s.strip == '' }
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/email.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Email
5 | attr_accessor :email, :name
6 |
7 | # @param [String] email required e-mail address
8 | # @param [String] name optionally personification
9 | def initialize(email:, name: nil)
10 | if name
11 | @email = email
12 | @name = name
13 | else
14 | @email, @name = split_email(email)
15 | end
16 | end
17 |
18 | def split_email(email)
19 | split = /(?:(?.+)\s)?(?.+@[^>]+)>?/.match(email)
20 | raise ArgumentError, "email (#{email}) is invalid" unless split
21 |
22 | [split[:email], split[:address]]
23 | end
24 |
25 | def to_json(*)
26 | {
27 | 'email' => email,
28 | 'name' => name
29 | }.delete_if { |_, value| value.to_s.strip == '' }
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/footer.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Footer
5 | attr_accessor :enable, :text, :html
6 |
7 | def initialize(enable: nil, text: nil, html: nil)
8 | @enable = enable
9 | @text = text
10 | @html = html
11 | end
12 |
13 | def to_json(*)
14 | {
15 | 'enable' => enable,
16 | 'text' => text,
17 | 'html' => html
18 | }.delete_if { |_, value| value.to_s.strip == '' }
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/ganalytics.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Ganalytics
5 | attr_accessor :enable, :utm_source, :utm_medium, :utm_term, :utm_content, :utm_name, :utm_campaign
6 |
7 | def initialize(enable: nil, utm_source: nil, utm_medium: nil, utm_term: nil, utm_content: nil, utm_campaign: nil, utm_name: nil)
8 | @enable = enable
9 | @utm_source = utm_source
10 | @utm_medium = utm_medium
11 | @utm_term = utm_term
12 | @utm_content = utm_content
13 | @utm_campaign = utm_campaign
14 | @utm_name = utm_name
15 | end
16 |
17 | def to_json(*)
18 | {
19 | 'enable' => enable,
20 | 'utm_source' => utm_source,
21 | 'utm_medium' => utm_medium,
22 | 'utm_term' => utm_term,
23 | 'utm_content' => utm_content,
24 | 'utm_campaign' => utm_campaign
25 | }.delete_if { |_, value| value.to_s.strip == '' }
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/header.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Header
5 | attr_accessor :header
6 |
7 | def initialize(key: nil, value: nil)
8 | @header = {}
9 | key.nil? || value.nil? ? @header = nil : @header[key] = value
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'header' => header
15 | }.delete_if { |_, value| value.to_s.strip == '' }
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/mail.rb:
--------------------------------------------------------------------------------
1 | # Build the request body for the v3/mail/send endpoint
2 | # Please see the examples/helpers/mail/example.rb for a demonstration of usage
3 | require 'json'
4 |
5 | module SendGrid
6 | class Mail
7 | attr_accessor :subject, :ip_pool_name, :template_id, :send_at, :batch_id
8 | attr_reader :personalizations, :contents, :attachments, :categories, :sections, :headers, :custom_args
9 | attr_writer :from, :asm, :mail_settings, :tracking_settings, :reply_to
10 |
11 | # We allow for all nil values here to create uninitialized Mail objects
12 | # (e.g. /use-cases/transactional-templates.md)
13 | def initialize(from_email = nil, subj = nil, to_email = nil, cont = nil) # rubocop:disable Metrics/ParameterLists
14 | @from = nil
15 | @subject = nil
16 | @personalizations = []
17 | @contents = []
18 | @attachments = []
19 | @template_id = nil
20 | @sections = {}
21 | @headers = {}
22 | @categories = []
23 | @custom_args = {}
24 | @send_at = nil
25 | @batch_id = nil
26 | @asm = nil
27 | @ip_pool_name = nil
28 | @mail_settings = nil
29 | @tracking_settings = nil
30 | @reply_to = nil
31 |
32 | return if from_email.nil? && subj.nil? && to_email.nil? && cont.nil?
33 |
34 | self.from = from_email
35 | self.subject = subj
36 | personalization = Personalization.new
37 | personalization.add_to(to_email)
38 | add_personalization(personalization)
39 | add_content(cont)
40 | end
41 |
42 | def from
43 | @from.nil? ? nil : @from.to_json
44 | end
45 |
46 | def add_personalization(personalization)
47 | @personalizations << personalization.to_json
48 | end
49 |
50 | def add_content(content)
51 | @contents << content.to_json
52 | end
53 |
54 | def check_for_secrets(patterns)
55 | contents = @contents.map { |content| content['value'] }.join(' ')
56 | patterns.each do |pattern|
57 | raise SecurityError, 'Content contains sensitive information.' if contents.match(pattern)
58 | end
59 | end
60 |
61 | def add_attachment(attachment)
62 | @attachments << attachment.to_json
63 | end
64 |
65 | def add_category(category)
66 | @categories << category.name
67 | end
68 |
69 | def add_section(section)
70 | section = section.to_json
71 | @sections = @sections.merge(section['section'])
72 | end
73 |
74 | def add_header(header)
75 | header = header.to_json
76 | @headers = @headers.merge(header['header'])
77 | end
78 |
79 | def add_custom_arg(custom_arg)
80 | custom_arg = custom_arg.to_json
81 | @custom_args = @custom_args.merge(custom_arg['custom_arg'])
82 | end
83 |
84 | def asm
85 | @asm.nil? ? nil : @asm.to_json
86 | end
87 |
88 | def mail_settings
89 | @mail_settings.nil? ? nil : @mail_settings.to_json
90 | end
91 |
92 | def tracking_settings
93 | @tracking_settings.nil? ? nil : @tracking_settings.to_json
94 | end
95 |
96 | def reply_to
97 | @reply_to.nil? ? nil : @reply_to.to_json
98 | end
99 |
100 | def to_json(*)
101 | {
102 | 'from' => from,
103 | 'subject' => subject,
104 | 'personalizations' => personalizations,
105 | 'content' => contents,
106 | 'attachments' => attachments,
107 | 'template_id' => template_id,
108 | 'sections' => sections,
109 | 'headers' => headers,
110 | 'categories' => categories,
111 | 'custom_args' => custom_args,
112 | 'send_at' => send_at,
113 | 'batch_id' => batch_id,
114 | 'asm' => asm,
115 | 'ip_pool_name' => ip_pool_name,
116 | 'mail_settings' => mail_settings,
117 | 'tracking_settings' => tracking_settings,
118 | 'reply_to' => reply_to
119 | }.delete_if { |_, value| value.to_s.strip == '' || value == [] || value == {} }
120 | end
121 | end
122 | end
123 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/mail_settings.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class MailSettings
5 | attr_writer :sandbox_mode, :footer, :bcc, :spam_check, :bypass_list_management
6 |
7 | def initialize
8 | @bcc = nil
9 | @bypass_list_management = nil
10 | @footer = nil
11 | @sandbox_mode = nil
12 | @spam_check = nil
13 | end
14 |
15 | def sandbox_mode
16 | @sandbox_mode.nil? ? nil : @sandbox_mode.to_json
17 | end
18 |
19 | def bypass_list_management
20 | @bypass_list_management.nil? ? nil : @bypass_list_management.to_json
21 | end
22 |
23 | def footer
24 | @footer.nil? ? nil : @footer.to_json
25 | end
26 |
27 | def bcc
28 | @bcc.nil? ? nil : @bcc.to_json
29 | end
30 |
31 | def spam_check
32 | @spam_check.nil? ? nil : @spam_check.to_json
33 | end
34 |
35 | def to_json(*)
36 | {
37 | 'bcc' => bcc,
38 | 'bypass_list_management' => bypass_list_management,
39 | 'footer' => footer,
40 | 'sandbox_mode' => sandbox_mode,
41 | 'spam_check' => spam_check
42 | }.delete_if { |_, value| value.to_s.strip == '' }
43 | end
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/open_tracking.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class OpenTracking
5 | attr_accessor :enable, :substitution_tag
6 |
7 | def initialize(enable: nil, substitution_tag: nil)
8 | @enable = enable
9 | @substitution_tag = substitution_tag
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'enable' => enable,
15 | 'substitution_tag' => substitution_tag
16 | }.delete_if { |_, value| value.to_s.strip == '' }
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/personalization.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Personalization
5 | attr_reader :tos, :from, :ccs, :bccs, :headers, :substitutions, :custom_args,
6 | :dynamic_template_data
7 |
8 | attr_accessor :send_at, :subject
9 |
10 | def initialize
11 | @tos = []
12 | @from = nil
13 | @ccs = []
14 | @bccs = []
15 | @subject = nil
16 | @headers = {}
17 | @substitutions = {}
18 | @custom_args = {}
19 | @dynamic_template_data = {}
20 | @send_at = nil
21 | end
22 |
23 | def add_to(to)
24 | raise DuplicatePersonalizationError if duplicate?(to)
25 |
26 | @tos << to.to_json
27 | end
28 |
29 | def add_from(from)
30 | @from = from.to_json
31 | end
32 |
33 | def add_cc(cc)
34 | raise DuplicatePersonalizationError if duplicate?(cc)
35 |
36 | @ccs << cc.to_json
37 | end
38 |
39 | def add_bcc(bcc)
40 | raise DuplicatePersonalizationError if duplicate?(bcc)
41 |
42 | @bccs << bcc.to_json
43 | end
44 |
45 | def add_header(header)
46 | header = header.to_json
47 | @headers = @headers.merge(header['header'])
48 | end
49 |
50 | def add_substitution(substitution)
51 | substitution = substitution.to_json
52 | @substitutions = @substitutions.merge(substitution['substitution'])
53 | end
54 |
55 | def add_custom_arg(custom_arg)
56 | custom_arg = custom_arg.to_json
57 | @custom_args = @custom_args.merge(custom_arg['custom_arg'])
58 | end
59 |
60 | def add_dynamic_template_data(dynamic_template_data)
61 | @dynamic_template_data.merge!(dynamic_template_data)
62 | end
63 |
64 | def to_json(*)
65 | {
66 | 'to' => tos,
67 | 'from' => from,
68 | 'cc' => ccs,
69 | 'bcc' => bccs,
70 | 'subject' => subject,
71 | 'headers' => headers,
72 | 'substitutions' => substitutions,
73 | 'custom_args' => custom_args,
74 | 'dynamic_template_data' => dynamic_template_data,
75 | 'send_at' => send_at
76 | }.delete_if { |_, value| value.to_s.strip == '' || value == [] || value == {} }
77 | end
78 |
79 | private
80 |
81 | def duplicate?(addition)
82 | additional_email = addition.email.downcase
83 |
84 | [@tos, @ccs, @bccs].flatten.each do |elm|
85 | return true if elm&.dig('email')&.downcase == additional_email
86 | end
87 |
88 | false
89 | end
90 | end
91 |
92 | class DuplicatePersonalizationError < StandardError; end
93 | end
94 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/section.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Section
5 | attr_accessor :section
6 |
7 | def initialize(key: nil, value: nil)
8 | @section = {}
9 | key.nil? || value.nil? ? @section = nil : @section[key] = value
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'section' => section
15 | }.delete_if { |_, value| value.to_s.strip == '' }
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/spam_check.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class SpamCheck
5 | attr_accessor :enable, :threshold, :post_to_url
6 |
7 | def initialize(enable: nil, threshold: nil, post_to_url: nil)
8 | @enable = enable
9 | @threshold = threshold
10 | @post_to_url = post_to_url
11 | end
12 |
13 | def to_json(*)
14 | {
15 | 'enable' => enable,
16 | 'threshold' => threshold,
17 | 'post_to_url' => post_to_url
18 | }.delete_if { |_, value| value.to_s.strip == '' }
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/subscription_tracking.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class SubscriptionTracking
5 | attr_accessor :enable, :text, :html, :substitution_tag
6 |
7 | def initialize(enable: nil, text: nil, html: nil, substitution_tag: nil)
8 | @enable = enable
9 | @text = text
10 | @html = html
11 | @substitution_tag = substitution_tag
12 | end
13 |
14 | def to_json(*)
15 | {
16 | 'enable' => enable,
17 | 'text' => text,
18 | 'html' => html,
19 | 'substitution_tag' => substitution_tag
20 | }.delete_if { |_, value| value.to_s.strip == '' }
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/substitution.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class Substitution
5 | attr_accessor :substitution
6 |
7 | def initialize(key: nil, value: nil)
8 | @substitution = {}
9 | key.nil? || value.nil? ? @substitution = nil : @substitution[key] = value
10 | end
11 |
12 | def to_json(*)
13 | {
14 | 'substitution' => substitution
15 | }.delete_if { |_, value| value.to_s.strip == '' }
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/mail/tracking_settings.rb:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | module SendGrid
4 | class TrackingSettings
5 | attr_writer :click_tracking, :open_tracking, :subscription_tracking, :ganalytics
6 |
7 | def initialize
8 | @click_tracking = nil
9 | @open_tracking = nil
10 | @subscription_tracking = nil
11 | @ganalytics = nil
12 | end
13 |
14 | def click_tracking
15 | @click_tracking.nil? ? nil : @click_tracking.to_json
16 | end
17 |
18 | def open_tracking
19 | @open_tracking.nil? ? nil : @open_tracking.to_json
20 | end
21 |
22 | def subscription_tracking
23 | @subscription_tracking.nil? ? nil : @subscription_tracking.to_json
24 | end
25 |
26 | def ganalytics
27 | @ganalytics.nil? ? nil : @ganalytics.to_json
28 | end
29 |
30 | def to_json(*)
31 | {
32 | 'click_tracking' => click_tracking,
33 | 'open_tracking' => open_tracking,
34 | 'subscription_tracking' => subscription_tracking,
35 | 'ganalytics' => ganalytics
36 | }.delete_if { |_, value| value.to_s.strip == '' }
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/permissions/scope.rb:
--------------------------------------------------------------------------------
1 | # This is used for getting scopes
2 | require 'yaml'
3 |
4 | module SendGrid
5 | class Scope
6 | SCOPES = YAML.load_file("#{File.dirname(__FILE__)}/scopes.yml").freeze
7 |
8 | class << self
9 | def admin_permissions
10 | SCOPES.values.map(&:values).flatten
11 | end
12 |
13 | def read_only_permissions
14 | SCOPES.map { |_, v| v[:read] }.flatten
15 | end
16 |
17 | SCOPES.each_key do |endpoint|
18 | define_method "#{endpoint}_read_only_permissions" do
19 | SCOPES[endpoint][:read]
20 | end
21 |
22 | define_method "#{endpoint}_full_access_permissions" do
23 | SCOPES[endpoint].values.flatten
24 | end
25 | end
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/settings/README.md:
--------------------------------------------------------------------------------
1 | **This module allows you to quickly and easily build a Settings object for retrieving or updating your Twilio SendGrid Settings.**
2 |
3 | # Quick Start
4 |
5 | Run the [example](../../../../examples/helpers/settings) (make sure you have set your environment variable to include your SENDGRID_API_KEY).
6 |
7 | ```bash
8 | ruby examples/helpers/settings/example.rb
9 | ```
10 |
11 | ## Usage
12 |
13 | - See the [example](../../../../examples/helpers/settings) for a complete working example.
14 | - [Documentation](https://sendgrid.com/docs/API_Reference/Web_API_v3/Settings/index.html)
15 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/settings/mail_settings_dto.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | class MailSettingsDto
3 | attr_reader :bcc, :address_whitelist, :bounce_purge, :footer, :forward_spam, :forward_bounce, :plain_content, :spam_check, :template
4 |
5 | def self.fetch(sendgrid_client:, name:, query_params:)
6 | sendgrid_client.mail_settings.public_send(name).get(query_params: query_params)
7 | end
8 |
9 | def self.update(sendgrid_client:, name:, request_body:)
10 | sendgrid_client.mail_settings.public_send(name).patch(request_body: request_body)
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/settings/partner_settings_dto.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | class PartnerSettingsDto
3 | attr_reader :new_relic
4 |
5 | def self.fetch(sendgrid_client:, name:, query_params:)
6 | sendgrid_client.partner_settings.public_send(name).get(query_params: query_params)
7 | end
8 |
9 | def self.update(sendgrid_client:, name:, request_body:)
10 | sendgrid_client.partner_settings.public_send(name).patch(request_body: request_body)
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/settings/settings.rb:
--------------------------------------------------------------------------------
1 | require_relative 'mail_settings_dto'
2 | require_relative 'partner_settings_dto'
3 | require_relative 'tracking_settings_dto'
4 | require_relative 'user_settings_dto'
5 |
6 | module SendGrid
7 | class Settings
8 | attr_accessor :sendgrid_client
9 |
10 | SETTING_TYPES = [SendGrid::MailSettingsDto, SendGrid::TrackingSettingsDto,
11 | SendGrid::PartnerSettingsDto, SendGrid::UserSettingsDto].freeze
12 |
13 | def initialize(sendgrid_client:)
14 | @sendgrid_client = sendgrid_client
15 | end
16 |
17 | SETTING_TYPES.each do |setting_type|
18 | setting_type.instance_methods(false).each do |name|
19 | define_method(name) do |**args|
20 | setting_type.fetch(sendgrid_client: sendgrid_client, name: name, query_params: args)
21 | end
22 | define_method("update_#{name}") do |**args|
23 | setting_type.update(sendgrid_client: sendgrid_client, name: name, request_body: args)
24 | end
25 | end
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/settings/tracking_settings_dto.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | class TrackingSettingsDto
3 | attr_reader :open, :click, :google_analytics, :subscription
4 | alias click_tracking click
5 | alias open_tracking open
6 | alias subscription_tracking subscription
7 |
8 | def self.fetch(sendgrid_client:, name:, query_params:)
9 | name = scrub_alias_names(name.to_s)
10 | sendgrid_client.tracking_settings.public_send(name).get(query_params: query_params)
11 | end
12 |
13 | def self.update(sendgrid_client:, name:, request_body:)
14 | name = scrub_alias_names(name.to_s)
15 | sendgrid_client.tracking_settings.public_send(name).patch(request_body: request_body)
16 | end
17 |
18 | def self.scrub_alias_names(name)
19 | name.gsub(/_tracking/, '')
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/settings/user_settings_dto.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | class UserSettingsDto
3 | attr_reader :enforced_tls
4 |
5 | def self.fetch(sendgrid_client:, name:, query_params:)
6 | sendgrid_client.user.settings.public_send(name).get(query_params: query_params)
7 | end
8 |
9 | def self.update(sendgrid_client:, name:, request_body:)
10 | sendgrid_client.user.settings.public_send(name).patch(request_body: request_body)
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/stats/email_stats.rb:
--------------------------------------------------------------------------------
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
47 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/stats/metrics.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | class Metrics
3 | attr_reader :blocks, :bounce_drops,
4 | :bounces, :clicks, :deferred, :delivered,
5 | :invalid_emails, :opens, :processed, :requests,
6 | :spam_report_drops, :spam_reports, :unique_clicks,
7 | :unique_opens, :unsubscribe_drops, :unsubscribes
8 |
9 | def initialize(args = {})
10 | @date = args['date']
11 | @blocks = args['blocks']
12 | @bounce_drops = args['bounce_drops']
13 | @bounces = args['bounces']
14 | @clicks = args['clicks']
15 | @deferred = args['deferred']
16 | @delivered = args['delivered']
17 | @invalid_emails = args['invalid_emails']
18 | @opens = args['opens']
19 | @processed = args['processed']
20 | @requests = args['requests']
21 | @spam_report_drops = args['spam_report_drops']
22 | @spam_reports = args['spam_reports']
23 | @unique_clicks = args['unique_clicks']
24 | @unique_opens = args['unique_opens']
25 | @unsubscribe_drops = args['unsubscribe_drops']
26 | @unsubscribes = args['unsubscribes']
27 | end
28 |
29 | def date
30 | Date.parse(@date)
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/lib/sendgrid/helpers/stats/stats_response.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | class StatsResponse
3 | def initialize(args)
4 | @errors = args['errors'] if args.is_a? Hash
5 | @stats = args if args.is_a? Array
6 | end
7 |
8 | def errors
9 | @errors.map do |error|
10 | error['message']
11 | end
12 | end
13 |
14 | def error?
15 | !@errors.nil?
16 | end
17 |
18 | def metrics
19 | @stats.flat_map do |stat|
20 | starting_date = stat['date']
21 | all_stats_for_date = stat['stats']
22 |
23 | all_stats_for_date.map do |metric|
24 | Metrics.new(metric['metrics'].merge('date' => starting_date))
25 | end
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/lib/sendgrid/sendgrid.rb:
--------------------------------------------------------------------------------
1 | # Quickly and easily access the Twilio SendGrid API.
2 | module SendGrid
3 | class API < BaseInterface
4 | # * *Args* :
5 | # - +api_key+ -> your Twilio SendGrid API key
6 | # - +host+ -> the base URL for the API
7 | # - +request_headers+ -> any headers that you want to be globally applied
8 | # - +version+ -> the version of the API you wish to access,
9 | # currently only "v3" is supported
10 | # - +impersonate_subuser+ -> the subuser to impersonate, will be passed
11 | # in the "On-Behalf-Of" header
12 | # - +http_options+ -> http options that you want to be globally applied to each request
13 | #
14 | def initialize(api_key:, host: nil, request_headers: nil, version: nil, impersonate_subuser: nil, http_options: {})
15 | auth = "Bearer #{api_key}"
16 | host ||= 'https://api.sendgrid.com'
17 |
18 | super(auth: auth, host: host, request_headers: request_headers, version: version, impersonate_subuser: impersonate_subuser, http_options: http_options)
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/sendgrid/twilio_email.rb:
--------------------------------------------------------------------------------
1 | # Quickly and easily access the Twilio Email API.
2 | module TwilioEmail
3 | class API < BaseInterface
4 | # * *Args* :
5 | # - +username+ -> your Twilio Email API key SID or Account SID
6 | # - +password+ -> your Twilio Email API key secret or Account Auth Token
7 | # - +host+ -> the base URL for the API
8 | # - +request_headers+ -> any headers that you want to be globally applied
9 | # - +version+ -> the version of the API you wish to access,
10 | # currently only "v3" is supported
11 | # - +impersonate_subuser+ -> the subuser to impersonate, will be passed
12 | # in the "On-Behalf-Of" header
13 | #
14 | def initialize(username:, password:, host: nil, request_headers: nil, version: nil, impersonate_subuser: nil)
15 | auth = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
16 | host ||= 'https://email.twilio.com'
17 |
18 | super(auth: auth, host: host, request_headers: request_headers, version: version, impersonate_subuser: impersonate_subuser)
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/sendgrid/version.rb:
--------------------------------------------------------------------------------
1 | module SendGrid
2 | VERSION = '6.7.0'.freeze
3 | end
4 |
--------------------------------------------------------------------------------
/sendgrid-ruby.gemspec:
--------------------------------------------------------------------------------
1 | lib = File.expand_path('lib', __dir__)
2 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3 | require 'sendgrid/version'
4 |
5 | Gem::Specification.new do |spec|
6 | spec.name = 'sendgrid-ruby'
7 | spec.version = SendGrid::VERSION
8 | spec.authors = ['Elmer Thomas', 'Robin Johnson', 'Eddie Zaneski']
9 | spec.email = 'help@twilio.com'
10 | spec.summary = 'Official Twilio SendGrid Gem'
11 | spec.description = 'Official Twilio SendGrid Gem to Interact with Twilio SendGrids API in native Ruby'
12 | spec.homepage = 'http://github.com/sendgrid/sendgrid-ruby'
13 |
14 | spec.required_ruby_version = '>= 2.2'
15 |
16 | spec.license = 'MIT'
17 | spec.files = `git ls-files -z`.split("\x0")
18 | spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
19 | spec.test_files = spec.files.grep(/^(test|spec|features)/)
20 | spec.require_paths = ['lib']
21 | spec.add_dependency 'ruby_http_client', '~> 3.4'
22 | spec.add_development_dependency 'faker'
23 | spec.add_development_dependency 'minitest', '~> 5.9'
24 | spec.add_development_dependency 'pry'
25 | spec.add_development_dependency 'rack'
26 | spec.add_development_dependency 'rake', '~> 13.0'
27 | spec.add_development_dependency 'rspec'
28 | spec.add_development_dependency 'simplecov', '~> 0.18.5'
29 | spec.add_development_dependency 'sinatra', '>= 1.4.7', '< 3'
30 | end
31 |
--------------------------------------------------------------------------------
/spec/fixtures/event_webhook.rb:
--------------------------------------------------------------------------------
1 | require "json"
2 |
3 | module Fixtures
4 | module EventWebhook
5 | PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=='.freeze
6 | FAILING_PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqTxd43gyp8IOEto2LdIfjRQrIbsd4SXZkLW6jDutdhXSJCWHw8REntlo7aNDthvj+y7GjUuFDb/R1NGe1OPzpA=='.freeze
7 | SIGNATURE = 'MEUCIGHQVtGj+Y3LkG9fLcxf3qfI10QysgDWmMOVmxG0u6ZUAiEAyBiXDWzM+uOe5W0JuG+luQAbPIqHh89M15TluLtEZtM='.freeze
8 | FAILING_SIGNATURE = 'MEUCIQCtIHJeH93Y+qpYeWrySphQgpNGNr/U+UyUlBkU6n7RAwIgJTz2C+8a8xonZGi6BpSzoQsbVRamr2nlxFDWYNH3j/0='.freeze
9 | TIMESTAMP = '1600112502'.freeze
10 | PAYLOAD = "#{[
11 | {
12 | email: 'hello@world.com',
13 | event: 'dropped',
14 | reason: 'Bounced Address',
15 | sg_event_id: 'ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA',
16 | sg_message_id: 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0',
17 | 'smtp-id': '',
18 | timestamp: 1_600_112_492
19 | }
20 | ].to_json}\r\n".freeze # Be sure to include the trailing carriage return and newline!
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/spec/rack/sendgrid_webhook_verification_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 | require 'rack/mock'
3 | require './spec/fixtures/event_webhook'
4 |
5 | unless RUBY_PLATFORM == 'java'
6 | describe Rack::SendGridWebhookVerification do
7 | let(:public_key) { Fixtures::EventWebhook::PUBLIC_KEY }
8 | before do
9 | @app = ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['Hello']] }
10 | end
11 |
12 | describe 'new' do
13 | it 'should initialize with an app, public key and a path' do
14 | expect do
15 | Rack::SendGridWebhookVerification.new(@app, 'ABC', %r{/email})
16 | end.not_to raise_error
17 | end
18 |
19 | it 'should initialize with an app, public key and paths' do
20 | expect do
21 | Rack::SendGridWebhookVerification.new(@app, 'ABC', %r{/email}, %r{/event})
22 | end.not_to raise_error
23 | end
24 | end
25 |
26 | describe 'calling against one path' do
27 | let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, %r{/email}) }
28 |
29 | it "should not intercept when the path doesn't match" do
30 | expect(SendGrid::EventWebhook).to_not receive(:new)
31 | request = Rack::MockRequest.env_for('/login')
32 | status, headers, body = middleware.call(request)
33 | expect(status).to eq(200)
34 | end
35 |
36 | it 'should allow a request through if it is verified' do
37 | options = {
38 | :input => Fixtures::EventWebhook::PAYLOAD,
39 | 'Content-Type' => "application/json"
40 | }
41 | options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
42 | options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
43 | request = Rack::MockRequest.env_for('/email', options)
44 | status, headers, body = middleware.call(request)
45 | expect(status).to eq(200)
46 | end
47 |
48 | it 'should short circuit a request to 403 if there is no signature or timestamp' do
49 | options = {
50 | :input => Fixtures::EventWebhook::PAYLOAD,
51 | 'Content-Type' => "application/json"
52 | }
53 | request = Rack::MockRequest.env_for('/email', options)
54 | status, headers, body = middleware.call(request)
55 | expect(status).to eq(403)
56 | end
57 |
58 | it 'should short circuit a request to 403 if the signature is incorrect' do
59 | options = {
60 | :input => Fixtures::EventWebhook::PAYLOAD,
61 | 'Content-Type' => "application/json"
62 | }
63 | options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::FAILING_SIGNATURE
64 | options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
65 | request = Rack::MockRequest.env_for('/email', options)
66 | status, headers, body = middleware.call(request)
67 | expect(status).to eq(403)
68 | end
69 |
70 | it 'should short circuit a request to 403 if the payload is incorrect' do
71 | options = {
72 | :input => 'payload',
73 | 'Content-Type' => "application/json"
74 | }
75 | options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
76 | options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
77 | request = Rack::MockRequest.env_for('/email', options)
78 | status, headers, body = middleware.call(request)
79 | expect(status).to eq(403)
80 | end
81 | end
82 |
83 | describe 'calling with multiple paths' do
84 | let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, %r{/email}, %r{/events}) }
85 |
86 | it "should not intercept when the path doesn't match" do
87 | expect(SendGrid::EventWebhook).to_not receive(:new)
88 | request = Rack::MockRequest.env_for('/sms_events')
89 | status, headers, body = middleware.call(request)
90 | expect(status).to eq(200)
91 | end
92 |
93 | it 'should allow a request through if it is verified' do
94 | options = {
95 | :input => Fixtures::EventWebhook::PAYLOAD,
96 | 'Content-Type' => "application/json"
97 | }
98 | options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
99 | options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
100 | request = Rack::MockRequest.env_for('/events', options)
101 | status, headers, body = middleware.call(request)
102 | expect(status).to eq(200)
103 | end
104 |
105 | it 'should short circuit a request to 403 if there is no signature or timestamp' do
106 | options = {
107 | :input => Fixtures::EventWebhook::PAYLOAD,
108 | 'Content-Type' => "application/json"
109 | }
110 | request = Rack::MockRequest.env_for('/events', options)
111 | status, headers, body = middleware.call(request)
112 | expect(status).to eq(403)
113 | end
114 | end
115 |
116 | describe 'request body which passed to an app' do
117 | before do
118 | @payload = nil
119 | @spy_app = lambda do |env|
120 | @payload = Rack::Request.new(env).body
121 | [200, { 'Content-Type' => 'text/plain' }, ['Hello']]
122 | end
123 | end
124 |
125 | let(:middleware) { Rack::SendGridWebhookVerification.new(@spy_app, public_key, %r{/email}) }
126 |
127 | it 'keeps orignal reading position' do
128 | options = {
129 | :input => Fixtures::EventWebhook::PAYLOAD,
130 | 'Content-Type' => "application/json"
131 | }
132 | options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
133 | options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
134 | request = Rack::MockRequest.env_for('/email', options)
135 | status, headers, body = middleware.call(request)
136 | expect(status).to eq(200)
137 | expect(@payload).not_to be_nil
138 | expect(@payload.pos).to be_zero
139 | end
140 | end
141 | end
142 | end
143 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 | require './spec/fixtures/event_webhook'
3 |
4 | describe SendGrid::EventWebhook do
5 | describe '.verify_signature' do
6 | it 'verifies a valid signature' do
7 | unless skip_jruby
8 | expect(verify(
9 | Fixtures::EventWebhook::PUBLIC_KEY,
10 | Fixtures::EventWebhook::PAYLOAD,
11 | Fixtures::EventWebhook::SIGNATURE,
12 | Fixtures::EventWebhook::TIMESTAMP
13 | )).to be true
14 | end
15 | end
16 |
17 | it 'rejects a bad key' do
18 | unless skip_jruby
19 | expect(verify(
20 | Fixtures::EventWebhook::FAILING_PUBLIC_KEY,
21 | Fixtures::EventWebhook::PAYLOAD,
22 | Fixtures::EventWebhook::SIGNATURE,
23 | Fixtures::EventWebhook::TIMESTAMP
24 | )).to be false
25 | end
26 | end
27 |
28 | it 'rejects a bad payload' do
29 | unless skip_jruby
30 | expect(verify(
31 | Fixtures::EventWebhook::PUBLIC_KEY,
32 | 'payload',
33 | Fixtures::EventWebhook::SIGNATURE,
34 | Fixtures::EventWebhook::TIMESTAMP
35 | )).to be false
36 | end
37 | end
38 |
39 | it 'rejects a bad signature' do
40 | unless skip_jruby
41 | expect(verify(
42 | Fixtures::EventWebhook::PUBLIC_KEY,
43 | Fixtures::EventWebhook::PAYLOAD,
44 | Fixtures::EventWebhook::FAILING_SIGNATURE,
45 | Fixtures::EventWebhook::TIMESTAMP
46 | )).to be false
47 | end
48 | end
49 |
50 | it 'rejects a bad timestamp' do
51 | unless skip_jruby
52 | expect(verify(
53 | Fixtures::EventWebhook::PUBLIC_KEY,
54 | Fixtures::EventWebhook::PAYLOAD,
55 | Fixtures::EventWebhook::SIGNATURE,
56 | 'timestamp'
57 | )).to be false
58 | end
59 | end
60 |
61 | it 'rejects a missing signature' do
62 | unless skip_jruby
63 | expect(verify(
64 | Fixtures::EventWebhook::PUBLIC_KEY,
65 | Fixtures::EventWebhook::PAYLOAD,
66 | nil,
67 | Fixtures::EventWebhook::TIMESTAMP
68 | )).to be false
69 | end
70 | end
71 |
72 | it 'throws an error when using jruby' do
73 | if skip_jruby
74 | expect do
75 | verify(
76 | Fixtures::EventWebhook::PUBLIC_KEY,
77 | Fixtures::EventWebhook::PAYLOAD,
78 | Fixtures::EventWebhook::SIGNATURE,
79 | Fixtures::EventWebhook::TIMESTAMP
80 | )
81 | end.to raise_error(SendGrid::EventWebhook::NotSupportedError)
82 | end
83 | end
84 | end
85 | end
86 |
87 | describe SendGrid::EventWebhookHeader do
88 | it 'sets the signature header constant' do
89 | expect(SendGrid::EventWebhookHeader::SIGNATURE).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE")
90 | end
91 |
92 | it 'sets the timestamp header constant' do
93 | expect(SendGrid::EventWebhookHeader::TIMESTAMP).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP")
94 | end
95 | end
96 |
97 | def verify(public_key, payload, signature, timestamp)
98 | ew = SendGrid::EventWebhook.new
99 | ec_public_key = ew.convert_public_key_to_ecdsa(public_key)
100 | ew.verify_signature(ec_public_key, payload, signature, timestamp)
101 | end
102 |
103 | def skip_jruby
104 | RUBY_PLATFORM == 'java'
105 | end
106 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/ip_management/ip_management_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::IpManagement do
4 | let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5 | let(:ip_management) { SendGrid::IpManagement.new(sendgrid_client: sendgrid_client) }
6 |
7 | describe '.new' do
8 | it 'initializes correctly' do
9 | expect(ip_management).to be_a SendGrid::IpManagement
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/settings/mail_settings_dto_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::MailSettingsDto do
4 | let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5 | let(:mail_settings) { SendGrid::MailSettingsDto }
6 | let(:setting_name) { 'bcc' }
7 | let(:setting_params) { { email: Faker::Internet.email, enabled: rand(1..100).even? } }
8 |
9 | it { should respond_to :bcc }
10 | it { should respond_to :address_whitelist }
11 | it { should respond_to :bounce_purge }
12 | it { should respond_to :footer }
13 | it { should respond_to :forward_spam }
14 | it { should respond_to :forward_bounce }
15 | it { should respond_to :plain_content }
16 | it { should respond_to :spam_check }
17 | it { should respond_to :template }
18 |
19 | describe '.fetch' do
20 | it 'calls get on sendgrid_client' do
21 | args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
22 | expect(mail_settings.fetch(**args)).to be_a SendGrid::Response
23 | end
24 | end
25 |
26 | describe '.update' do
27 | it 'calls patch on sendgrid_client' do
28 | args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
29 | expect(mail_settings.update(**args)).to be_a SendGrid::Response
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/settings/partner_settings_dto_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::PartnerSettingsDto do
4 | let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5 | let(:partner_settings) { SendGrid::PartnerSettingsDto }
6 | let(:setting_name) { 'new_relic' }
7 | let(:setting_params) { { license_key: 'key', enabled: rand(1..100).even? } }
8 |
9 | it { should respond_to :new_relic }
10 |
11 | describe '.fetch' do
12 | it 'calls get on sendgrid_client' do
13 | args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
14 | expect(partner_settings.fetch(**args)).to be_a SendGrid::Response
15 | end
16 | end
17 |
18 | describe '.update' do
19 | it 'calls patch on sendgrid_client' do
20 | args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
21 | expect(partner_settings.update(**args)).to be_a SendGrid::Response
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/settings/settings_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::Settings do
4 | let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5 | let(:settings) { SendGrid::Settings.new(sendgrid_client: sendgrid_client) }
6 |
7 | describe '.new' do
8 | it 'initializes correctly' do
9 | expect(settings).to be_a SendGrid::Settings
10 | end
11 | end
12 |
13 | describe '.bcc' do
14 | it 'fetches bcc data' do
15 | expect(settings.bcc).to be_a SendGrid::Response
16 | end
17 | end
18 |
19 | describe '.update_bcc' do
20 | it 'updates bcc' do
21 | bcc_response = settings.update_bcc(enabled: true, email: 'email@example.com')
22 | expect(bcc_response).to be_a SendGrid::Response
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/settings/tracking_settings_dto_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::TrackingSettingsDto do
4 | let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5 | let(:tracking_settings) { SendGrid::TrackingSettingsDto }
6 | let(:setting_name) { 'open_tracking' }
7 | let(:setting_params) { { enabled: rand(1..100).even? } }
8 |
9 | it { should respond_to :open_tracking }
10 | it { should respond_to :click_tracking }
11 | it { should respond_to :google_analytics }
12 | it { should respond_to :subscription_tracking }
13 |
14 | describe '.fetch' do
15 | it 'calls get on sendgrid_client' do
16 | args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
17 | expect(tracking_settings.fetch(**args)).to be_a SendGrid::Response
18 | end
19 | end
20 |
21 | describe '.update' do
22 | it 'calls patch on sendgrid_client' do
23 | args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
24 | expect(tracking_settings.update(**args)).to be_a SendGrid::Response
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/settings/user_settings_dto_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::UserSettingsDto do
4 | let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
5 | let(:user_settings) { SendGrid::UserSettingsDto }
6 | let(:setting_name) { 'enforced_tls' }
7 | let(:setting_params) { { require_tls: rand(1..100).even? } }
8 |
9 | it { should respond_to :enforced_tls }
10 |
11 | describe '.fetch' do
12 | it 'calls get on sendgrid_client' do
13 | args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
14 | expect(user_settings.fetch(**args)).to be_a SendGrid::Response
15 | end
16 | end
17 |
18 | describe '.update' do
19 | it 'calls patch on sendgrid_client' do
20 | args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
21 | expect(user_settings.update(**args)).to be_a SendGrid::Response
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/stats/email_stats_spec.rb:
--------------------------------------------------------------------------------
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 | end
34 |
35 | let(:error_response) do
36 | {
37 | 'errors' => [
38 | {
39 | 'message' => 'end_date should be a YYYY-MM-DD formatted date'
40 | }
41 | ]
42 | }
43 | end
44 |
45 | describe '.new' do
46 | it 'initializes with SendGrid::Client' do
47 | expect(stats).to be_a SendGrid::EmailStats
48 | end
49 | end
50 |
51 | describe 'successful response' do
52 | before do
53 | allow_any_instance_of(SendGrid::Response).to receive(:body) { sample_response.to_json }
54 | end
55 |
56 | describe '#by_day' do
57 | it 'fetches data aggregated by day' do
58 | day_stats = stats.by_day('2017-10-01', '2017-10-02')
59 | day_metrics = day_stats.metrics.first
60 |
61 | expect(day_metrics).to be_a SendGrid::Metrics
62 | expect(day_metrics.date.to_s).to eq('2017-10-01')
63 | expect(day_metrics.requests).to eq(110)
64 | expect(day_metrics.clicks).to eq(104)
65 | expect(day_metrics.bounces).to eq(103)
66 | expect(day_metrics.opens).to eq(108)
67 | end
68 | end
69 |
70 | describe '#by_week' do
71 | it 'fetches data aggregated by week' do
72 | day_stats = stats.by_week('2017-10-01', '2017-10-12')
73 | day_metrics = day_stats.metrics.first
74 |
75 | expect(day_metrics).to be_a SendGrid::Metrics
76 | expect(day_metrics.date.to_s).to eq('2017-10-01')
77 | expect(day_metrics.requests).to eq(110)
78 | expect(day_metrics.clicks).to eq(104)
79 | expect(day_metrics.bounces).to eq(103)
80 | expect(day_metrics.opens).to eq(108)
81 | end
82 | end
83 |
84 | describe '#by_month' do
85 | it 'fetches data aggregated by month' do
86 | day_stats = stats.by_month('2017-10-01', '2017-11-01')
87 | day_metrics = day_stats.metrics.first
88 |
89 | expect(day_metrics).to be_a SendGrid::Metrics
90 | expect(day_metrics.date.to_s).to eq('2017-10-01')
91 | expect(day_metrics.requests).to eq(110)
92 | expect(day_metrics.clicks).to eq(104)
93 | expect(day_metrics.bounces).to eq(103)
94 | expect(day_metrics.opens).to eq(108)
95 | end
96 | end
97 | end
98 |
99 | describe 'error response' do
100 | before do
101 | allow_any_instance_of(SendGrid::Response).to receive(:body) { error_response.to_json }
102 | end
103 |
104 | it 'fetches data aggregated by month' do
105 | day_stats = stats.by_month('2017-10-01', '2017-10-02')
106 |
107 | expect(day_stats.errors).to include('end_date should be a YYYY-MM-DD formatted date')
108 | expect(day_stats.error?).to be_truthy
109 | end
110 | end
111 | end
112 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/stats/metrics_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::Metrics do
4 | let(:params) do
5 | {
6 | 'date' => '2017-10-01',
7 | 'blocks' => 101,
8 | 'bounce_drops' => 102,
9 | 'bounces' => 103,
10 | 'clicks' => 104,
11 | 'deferred' => 105,
12 | 'delivered' => 106,
13 | 'invalid_emails' => 107,
14 | 'opens' => 108,
15 | 'processed' => 109,
16 | 'requests' => 110,
17 | 'spam_report_drops' => 111,
18 | 'spam_reports' => 112,
19 | 'unique_clicks' => 113,
20 | 'unique_opens' => 114,
21 | 'unsubscribe_drops' => 115,
22 | 'unsubscribes' => 116
23 | }
24 | end
25 |
26 | subject { described_class.new(params) }
27 |
28 | it 'initializes with metric parameters' do
29 | expect(subject).to be_a SendGrid::Metrics
30 | end
31 |
32 | it 'returns date as object' do
33 | expect(subject.date).to be_a Date
34 | end
35 |
36 | %w[
37 | blocks bounce_drops bounces clicks deferred delivered invalid_emails
38 | opens processed requests spam_report_drops spam_reports unique_clicks
39 | unique_opens unsubscribe_drops unsubscribes
40 | ].each do |attribute|
41 | it "responds to #{attribute}" do
42 | expect(subject).to respond_to(attribute.to_sym)
43 | end
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/spec/sendgrid/helpers/stats/stats_response_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::StatsResponse do
4 | let(:params) do
5 | [{
6 | 'date' => '2017-10-01',
7 | 'stats' => [
8 | { 'metrics' =>
9 | {
10 | 'blocks' => 101,
11 | 'bounce_drops' => 102,
12 | 'bounces' => 103,
13 | 'clicks' => 104,
14 | 'deferred' => 105,
15 | 'delivered' => 106,
16 | 'invalid_emails' => 107,
17 | 'opens' => 108,
18 | 'processed' => 109,
19 | 'requests' => 110,
20 | 'spam_report_drops' => 111,
21 | 'spam_reports' => 112,
22 | 'unique_clicks' => 113,
23 | 'unique_opens' => 114,
24 | 'unsubscribe_drops' => 115,
25 | 'unsubscribes' => 116
26 | } }
27 | ]
28 | }]
29 | end
30 |
31 | subject { described_class.new(params) }
32 |
33 | it 'initialized with JSON response body' do
34 | expect(subject).to be_a SendGrid::StatsResponse
35 | end
36 |
37 | describe '#metrics' do
38 | it 'returns an array of metrics' do
39 | metric = subject.metrics.first
40 |
41 | expect(subject.metrics).to be_a Array
42 | expect(metric.date.to_s).to eq('2017-10-01')
43 | expect(metric.requests).to eq(110)
44 | expect(metric.clicks).to eq(104)
45 | expect(metric.bounces).to eq(103)
46 | expect(metric.opens).to eq(108)
47 | end
48 | end
49 |
50 | context 'errors' do
51 | let(:error_params) do
52 | {
53 | 'errors' => [
54 | {
55 | 'message' => 'end_date should be a YYYY-MM-DD formatted date'
56 | }
57 | ]
58 | }
59 | end
60 |
61 | subject { described_class.new(error_params) }
62 |
63 | describe '#errors' do
64 | it 'shows a list of errors' do
65 | expect(subject.errors).to include('end_date should be a YYYY-MM-DD formatted date')
66 | end
67 | end
68 |
69 | describe '#error?' do
70 | it 'returns true if there is an error' do
71 | expect(subject.error?).to be_truthy
72 | end
73 | end
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/spec/sendgrid/sendgrid_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SendGrid::API do
4 | describe '.new' do
5 | it 'initializes correctly' do
6 | mail_client = SendGrid::API.new(api_key: 'fake_key')
7 | expect(mail_client.request_headers['Authorization']).to eq('Bearer fake_key')
8 | expect(mail_client.host).to eq('https://api.sendgrid.com')
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/sendgrid/twilio_email_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe TwilioEmail::API do
4 | describe '.new' do
5 | it 'initializes correctly' do
6 | mail_client = TwilioEmail::API.new(username: 'username', password: 'password')
7 | expect(mail_client.request_headers['Authorization']).to eq('Basic dXNlcm5hbWU6cGFzc3dvcmQ=')
8 | expect(mail_client.host).to eq('https://email.twilio.com')
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'simplecov'
2 | SimpleCov.start
3 | require 'rubygems'
4 | require 'bundler/setup'
5 | require 'pry'
6 | require 'faker'
7 |
8 | RSpec.configure do |config|
9 | Dir["#{File.dirname(__FILE__)}/../lib/sendgrid-ruby.rb"].sort.each { |ext| require ext }
10 |
11 | config.color = true
12 | end
13 |
--------------------------------------------------------------------------------
/static/img/github-fork.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sendgrid/sendgrid-ruby/02b6a2a46dbf38c53a6dd8469f5da69a55c78a47/static/img/github-fork.png
--------------------------------------------------------------------------------
/static/img/github-sign-up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sendgrid/sendgrid-ruby/02b6a2a46dbf38c53a6dd8469f5da69a55c78a47/static/img/github-sign-up.png
--------------------------------------------------------------------------------
/test/sendgrid/helpers/mail/test_attachment.rb:
--------------------------------------------------------------------------------
1 | require_relative "../../../../lib/sendgrid/helpers/mail/attachment"
2 | include SendGrid
3 | require "json"
4 | require "minitest/autorun"
5 |
6 | class TestAttachment < Minitest::Test
7 | SAMPLE_INPUT = "Es blüht so grün wie Blüten blüh'n im Frühling
8 | Es blüht so grün wie Blüten blüh'n im Frühling
9 | Es blüht so grün wie Blüten blüh'n im Frühling
10 | Es blüht so grün wie Blüten blüh'n im Frühling
11 | Es blüht so grün wie Blüten blüh'n im Frühling
12 | ".force_encoding('UTF-8').encode
13 |
14 | def setup; end
15 |
16 | def test_io_enocding
17 | attachment = Attachment.new
18 | attachment.content = StringIO.new(SAMPLE_INPUT)
19 |
20 | expected = {
21 | "content" => "RXMgYmzDvGh0IHNvIGdyw7xuIHdpZSBCbMO8dGVuIGJsw7xoJ24gaW0gRnLD\nvGhsaW5nCkVzIGJsw7xodCBzbyBncsO8biB3aWUgQmzDvHRlbiBibMO8aCdu\nIGltIEZyw7xobGluZwpFcyBibMO8aHQgc28gZ3LDvG4gd2llIEJsw7x0ZW4g\nYmzDvGgnbiBpbSBGcsO8aGxpbmcKRXMgYmzDvGh0IHNvIGdyw7xuIHdpZSBC\nbMO8dGVuIGJsw7xoJ24gaW0gRnLDvGhsaW5nCkVzIGJsw7xodCBzbyBncsO8\nbiB3aWUgQmzDvHRlbiBibMO8aCduIGltIEZyw7xobGluZwo=\n"
22 | }
23 |
24 | json = attachment.to_json
25 |
26 | # Double check that the decoded json matches original input.
27 | decoded = Base64.decode64(json["content"]).force_encoding('UTF-8').encode
28 |
29 | assert_equal(decoded, SAMPLE_INPUT)
30 |
31 | assert_equal(json, expected)
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/test/sendgrid/helpers/mail/test_category.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../../../lib/sendgrid/helpers/mail/mail'
2 | require 'minitest/autorun'
3 |
4 | class TestCategory < Minitest::Test
5 | include SendGrid
6 |
7 | def setup
8 | @category = Category.new(name: 'foo')
9 | end
10 |
11 | def test_aliases
12 | assert_equal @category.method(:name), @category.method(:category)
13 | end
14 |
15 | def test_name
16 | assert_equal @category.name, 'foo'
17 | end
18 |
19 | def test_to_json
20 | expected_json = {
21 | 'category' => 'foo'
22 | }
23 | assert_equal @category.to_json, expected_json
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/test/sendgrid/helpers/mail/test_data_residency.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../../../lib/sendgrid-ruby'
2 | require 'minitest/autorun'
3 |
4 | class TestDataResidency < Minitest::Test
5 | include SendGrid
6 |
7 | def setup
8 | @global_email = 'https://api.sendgrid.com'
9 | @eu_email = 'https://api.eu.sendgrid.com'
10 | end
11 |
12 | def test_with_global_data_residency
13 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
14 | sg.sendgrid_data_residency(region: 'global')
15 | assert_equal @global_email, sg.host
16 | end
17 |
18 | def test_with_global_eu_residency
19 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
20 | sg.sendgrid_data_residency(region: 'eu')
21 | assert_equal @eu_email, sg.host
22 | end
23 |
24 | def test_with_global_nil_residency
25 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
26 | assert_raises(ArgumentError) do
27 | sg.sendgrid_data_residency(region: nil)
28 | end
29 | end
30 |
31 | def test_with_global_invalid_residency
32 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
33 | assert_raises(ArgumentError) do
34 | sg.sendgrid_data_residency(region: "abc")
35 | end
36 | end
37 |
38 | def test_with_global_empty_residency
39 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
40 | assert_raises(ArgumentError) do
41 | sg.sendgrid_data_residency(region: "")
42 | end
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/test/sendgrid/helpers/mail/test_email.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../../../lib/sendgrid/helpers/mail/email'
2 | require 'minitest/autorun'
3 |
4 | class TestEmail < Minitest::Test
5 | include SendGrid
6 |
7 | def test_split_email_full_email
8 | @email = Email.new(email: 'Example User ')
9 | expected_json = {
10 | 'email' => 'test1@example.com',
11 | 'name' => 'Example User'
12 | }
13 | assert_equal @email.to_json, expected_json
14 | end
15 |
16 | def test_split_email_only_email
17 | @email = Email.new(email: 'test1@example.com')
18 | expected_json = {
19 | 'email' => 'test1@example.com'
20 | }
21 | assert_equal @email.to_json, expected_json
22 | end
23 |
24 | def test_split_email_name_and_email
25 | @email = Email.new(name: 'Example User', email: 'test1@example.com')
26 | expected_json = {
27 | 'email' => 'test1@example.com',
28 | 'name' => 'Example User'
29 | }
30 | assert_equal @email.to_json, expected_json
31 | end
32 |
33 | def test_mandatory_email_missing
34 | assert_raises(ArgumentError) { Email.new(email: nil) }
35 | assert_raises(ArgumentError) { Email.new(email: "") }
36 | end
37 |
38 | def test_invalid_email
39 | assert_raises(ArgumentError) { Email.new(email: "some-invalid-string") }
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/test/sendgrid/helpers/mail/test_personalizations.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../../../lib/sendgrid/helpers/mail/personalization'
2 | require 'minitest/autorun'
3 |
4 | class TestPersonalization < Minitest::Test
5 | include SendGrid
6 |
7 | def test_add_to
8 | @personalization = Personalization.new
9 | @personalization.add_to(Email.new(email: 'test1@example.com', name: 'Example User'))
10 | @personalization.add_to(Email.new(email: 'test2@example.com', name: 'Example User 2'))
11 | expected_json = {
12 | 'to' => [
13 | {
14 | 'email' => 'test1@example.com',
15 | 'name' => 'Example User'
16 | },
17 | {
18 | 'email' => 'test2@example.com',
19 | 'name' => 'Example User 2'
20 | }
21 | ]
22 | }
23 | assert_equal @personalization.to_json, expected_json
24 | end
25 |
26 | def test_duplicate_add_to
27 | @personalization = Personalization.new
28 | @personalization.add_to(Email.new(email: 'test1@example.com', name: 'Example User'))
29 | @personalization.add_to(Email.new(email: 'TEST2@EXAMPLE.COM', name: 'Example User 2'))
30 |
31 | assert_raises(DuplicatePersonalizationError) do
32 | @personalization.add_to(Email.new(email: 'test1@example.com', name: 'Duplicate User'))
33 | end
34 |
35 | assert_raises(DuplicatePersonalizationError) do
36 | @personalization.add_to(Email.new(email: 'TEST1@EXAMPLE.COM', name: 'Duplicate User'))
37 | end
38 |
39 | assert_raises(DuplicatePersonalizationError) do
40 | @personalization.add_to(Email.new(email: 'test2@example.com', name: 'Duplicate User 2'))
41 | end
42 |
43 | assert_raises(DuplicatePersonalizationError) do
44 | @personalization.add_to(Email.new(email: 'TEST2@EXAMPLE.COM', name: 'Duplicate User 2'))
45 | end
46 | end
47 |
48 | def test_add_from
49 | @personalization = Personalization.new
50 | @personalization.add_from(Email.new(email: 'from1@example.com', name: 'Example Sender'))
51 | expected_json = {
52 | 'from' => {
53 | 'email' => 'from1@example.com',
54 | 'name' => 'Example Sender'
55 | }
56 | }
57 |
58 | assert_equal @personalization.to_json, expected_json
59 | end
60 |
61 | def test_add_cc
62 | @personalization = Personalization.new
63 | @personalization.add_cc(Email.new(email: 'test1@example.com', name: 'Example User'))
64 | @personalization.add_cc(Email.new(email: 'test2@example.com', name: 'Example User 2'))
65 | expected_json = {
66 | 'cc' => [
67 | {
68 | 'email' => 'test1@example.com',
69 | 'name' => 'Example User'
70 | },
71 | {
72 | 'email' => 'test2@example.com',
73 | 'name' => 'Example User 2'
74 | }
75 | ]
76 | }
77 | assert_equal @personalization.to_json, expected_json
78 | end
79 |
80 | def test_duplicate_add_cc
81 | @personalization = Personalization.new
82 | @personalization.add_cc(Email.new(email: 'test1@example.com', name: 'Example User'))
83 | @personalization.add_cc(Email.new(email: 'TEST2@EXAMPLE.COM', name: 'Example User 2'))
84 |
85 | assert_raises(DuplicatePersonalizationError) do
86 | @personalization.add_cc(Email.new(email: 'test1@example.com', name: 'Duplicate User'))
87 | end
88 |
89 | assert_raises(DuplicatePersonalizationError) do
90 | @personalization.add_cc(Email.new(email: 'TEST1@EXAMPLE.COM', name: 'Duplicate User'))
91 | end
92 |
93 | assert_raises(DuplicatePersonalizationError) do
94 | @personalization.add_cc(Email.new(email: 'test2@example.com', name: 'Duplicate User 2'))
95 | end
96 |
97 | assert_raises(DuplicatePersonalizationError) do
98 | @personalization.add_cc(Email.new(email: 'TEST2@EXAMPLE.COM', name: 'Duplicate User 2'))
99 | end
100 | end
101 |
102 | def test_add_bcc
103 | @personalization = Personalization.new
104 | @personalization.add_bcc(Email.new(email: 'test1@example.com', name: 'Example User'))
105 | @personalization.add_bcc(Email.new(email: 'test2@example.com', name: 'Example User 2'))
106 | expected_json = {
107 | 'bcc' => [
108 | {
109 | 'email' => 'test1@example.com',
110 | 'name' => 'Example User'
111 | },
112 | {
113 | 'email' => 'test2@example.com',
114 | 'name' => 'Example User 2'
115 | }
116 | ]
117 | }
118 | assert_equal @personalization.to_json, expected_json
119 | end
120 |
121 | def test_duplicate_add_bcc
122 | @personalization = Personalization.new
123 | @personalization.add_bcc(Email.new(email: 'test1@example.com', name: 'Example User'))
124 | @personalization.add_bcc(Email.new(email: 'TEST2@EXAMPLE.COM', name: 'Example User 2'))
125 |
126 | assert_raises(DuplicatePersonalizationError) do
127 | @personalization.add_bcc(Email.new(email: 'test1@example.com', name: 'Duplicate User'))
128 | end
129 |
130 | assert_raises(DuplicatePersonalizationError) do
131 | @personalization.add_bcc(Email.new(email: 'TEST1@EXAMPLE.COM', name: 'Duplicate User'))
132 | end
133 |
134 | assert_raises(DuplicatePersonalizationError) do
135 | @personalization.add_bcc(Email.new(email: 'test2@example.com', name: 'Duplicate User 2'))
136 | end
137 |
138 | assert_raises(DuplicatePersonalizationError) do
139 | @personalization.add_bcc(Email.new(email: 'TEST2@EXAMPLE.COM', name: 'Duplicate User 2'))
140 | end
141 | end
142 |
143 | def test_add_header
144 | @personalization = Personalization.new
145 | @personalization.add_header(Header.new(key: 'X-Test', value: 'True'))
146 | expected_json = {
147 | 'headers' => {
148 | 'X-Test' => 'True'
149 | }
150 | }
151 | assert_equal @personalization.to_json, expected_json
152 | @personalization.add_header(Header.new(key: 'X-Test 1', value: 'False'))
153 | expected_json = {
154 | 'headers' => {
155 | 'X-Test' => 'True',
156 | 'X-Test 1' => 'False'
157 | }
158 | }
159 | assert_equal @personalization.to_json, expected_json
160 | end
161 |
162 | def test_add_substitution
163 | @personalization = Personalization.new
164 | @personalization.add_substitution(Substitution.new(key: '%name%', value: 'Example User'))
165 | expected_json = {
166 | 'substitutions' => {
167 | '%name%' => 'Example User'
168 | }
169 | }
170 | assert_equal @personalization.to_json, expected_json
171 | @personalization.add_substitution(Substitution.new(key: '%name 1%', value: 'Example User 1'))
172 | expected_json = {
173 | 'substitutions' => {
174 | '%name%' => 'Example User',
175 | '%name 1%' => 'Example User 1'
176 | }
177 | }
178 | assert_equal @personalization.to_json, expected_json
179 | end
180 |
181 | def test_add_custom_arg
182 | @personalization = Personalization.new
183 | @personalization.add_custom_arg(CustomArg.new(key: 'user_id', value: '343'))
184 | expected_json = {
185 | 'custom_args' => {
186 | 'user_id' => '343'
187 | }
188 | }
189 | assert_equal @personalization.to_json, expected_json
190 | @personalization.add_custom_arg(CustomArg.new(key: 'city', value: 'denver'))
191 | expected_json = {
192 | 'custom_args' => {
193 | 'user_id' => '343',
194 | 'city' => 'denver'
195 | }
196 | }
197 | assert_equal @personalization.to_json, expected_json
198 | end
199 |
200 | def test_add_dynamic_template_data
201 | @personalization = Personalization.new
202 | @personalization.add_dynamic_template_data(
203 | 'name' => 'Example User',
204 | 'city' => 'Denver'
205 | )
206 | expected_json = {
207 | 'dynamic_template_data' => {
208 | 'name' => 'Example User',
209 | 'city' => 'Denver'
210 | }
211 | }
212 | assert_equal @personalization.to_json, expected_json
213 | end
214 | end
215 |
--------------------------------------------------------------------------------
/test/sendgrid/permissions/test_scopes.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../../lib/sendgrid/helpers/permissions/scope'
2 | require 'minitest/autorun'
3 |
4 | class TestCategory < Minitest::Test
5 | include SendGrid
6 |
7 | # usecases
8 | # 1. test admin scopes
9 | # 2. test read only scopes
10 | # 3. test read only and full access scopes for a method by hardcoding
11 | # 4. test read only and full access scopes by loading scopes.yaml
12 |
13 | def setup
14 | @scopes_from_yaml = YAML.load_file("#{File.dirname(__FILE__)}/../../../lib/sendgrid/helpers/permissions/scopes.yml").freeze
15 | end
16 |
17 | def test_admin_scopes
18 | assert_equal Scope.admin_permissions, @scopes_from_yaml.values.map(&:values).flatten
19 | end
20 |
21 | def test_read_only_scopes
22 | assert_equal Scope.read_only_permissions, @scopes_from_yaml.map { |_, v| v[:read] }.flatten
23 | end
24 |
25 | def test_read_only_and_full_access_for_mail_hardcoded
26 | assert_equal Scope.mail_read_only_permissions, ["mail.batch.read"]
27 | assert_equal Scope.mail_full_access_permissions, ["mail.send", "mail.batch.create", "mail.batch.delete", "mail.batch.read", "mail.batch.update"]
28 | end
29 |
30 | def test_read_only_and_full_access_from_file
31 | @scopes_from_yaml.each_key do |endpoint|
32 | assert_equal Scope.send("#{endpoint}_read_only_permissions"), @scopes_from_yaml[endpoint][:read]
33 | assert_equal Scope.send("#{endpoint}_full_access_permissions"), @scopes_from_yaml[endpoint].values.flatten
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/twilio_sendgrid_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sendgrid/sendgrid-ruby/02b6a2a46dbf38c53a6dd8469f5da69a55c78a47/twilio_sendgrid_logo.png
--------------------------------------------------------------------------------
/use-cases/README.md:
--------------------------------------------------------------------------------
1 | This directory provides examples for specific use cases.
2 |
3 | Please [open an issue](https://github.com/sendgrid/sendgrid-ruby/issues) or [make a pull request](https://github.com/sendgrid/sendgrid-ruby/pulls) for any use cases you would like us to document here. Thank you!
4 |
5 | # Email Use Cases
6 | * [Transactional Templates](transactional-templates.md)
7 | * [Legacy Templates](legacy-templates.md)
8 | * [Personalizations](personalizations.md)
9 |
10 | # Twilio Use Cases
11 | * [Twilio Setup](twilio-setup.md)
12 | * [Send an Email With Twilio Email (Pilot)](twilio-email.md)
13 | * [Send an SMS Message](sms.md)
14 |
15 | # Non-Email Use Cases
16 | * [How to Set up a Domain Authentication](domain-authentication.md)
17 | * [How to View Email Statistics](email-statistics.md)
18 |
--------------------------------------------------------------------------------
/use-cases/domain-authentication.md:
--------------------------------------------------------------------------------
1 | # How to Setup a Domain Authentication
2 |
3 | You can find documentation for how to setup a domain authentication via the UI [here](https://sendgrid.com/docs/ui/account-and-settings/how-to-set-up-domain-authentication/) and via API [here](../USAGE.md#sender-authentication).
4 |
5 | Find more information about all of Twilio SendGrid's authentication related documentation [here](https://sendgrid.com/docs/ui/account-and-settings/).
6 |
--------------------------------------------------------------------------------
/use-cases/email-statistics.md:
--------------------------------------------------------------------------------
1 | # How to View Email Statistics
2 |
3 | You can find documentation for how to view your email statistics via the UI [here](https://app.sendgrid.com/statistics) and via API [here](../USAGE.md#stats).
4 |
5 | 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 Twilio SendGrid processes your email.
6 |
7 | You can also use the email statistics helper to make it easier to interact with the API.
8 |
9 | ```ruby
10 | require 'sendgrid-ruby'
11 | require 'date'
12 |
13 | include SendGrid
14 |
15 | sg_client = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY']).client
16 | stats = SendGrid::EmailStats.new(sendgrid_client: sg_client)
17 |
18 | # Fetch stats by day, between 2 dates
19 | from = Date.new(2017, 10, 01)
20 | to = Date.new(2017, 10, 12)
21 |
22 | email_stats = stats.by_day(from, to)
23 |
24 | email_stats.metrics
25 |
26 | if !email_stats.error?
27 | email_stats.metrics.each do |metric|
28 | puts "Date - #{metric.date}"
29 | puts "Number of Requests - #{metric.requests}"
30 | puts "Bounces - #{metric.bounces}"
31 | puts "Opens - #{metric.opens}"
32 | puts "Clicks - #{metric.clicks}"
33 | end
34 | end
35 |
36 | # Fetch stats by week, between 2 dates for a category
37 | from = Date.new(2017, 10, 01)
38 | to = Date.new(2017, 10, 12)
39 | category = 'abcd'
40 |
41 | email_stats = stats.by_week(from, to, category)
42 |
43 | if !email_stats.error?
44 | email_stats.metrics.each do |metric|
45 | puts "Date - #{metric.date}"
46 | puts "Number of Requests - #{metric.requests}"
47 | puts "Bounces - #{metric.bounces}"
48 | puts "Opens - #{metric.opens}"
49 | puts "Clicks - #{metric.clicks}"
50 | end
51 | end
52 | ```
53 |
--------------------------------------------------------------------------------
/use-cases/legacy-templates.md:
--------------------------------------------------------------------------------
1 | # Legacy Templates
2 |
3 | For this example, we assume you have created a [legacy transactional template](https://sendgrid.com/docs/User_Guide/Transactional_Templates/index.html) in the UI or via the API. Following is the template content we used for testing.
4 |
5 | Template ID (replace with your own):
6 | ```text
7 | 13b8f94f-bcae-4ec6-b752-70d6cb59f932
8 | ```
9 |
10 | Email Subject:
11 | ```text
12 | <%subject%>
13 | ```
14 |
15 | Template Body:
16 | ```html
17 |
18 |
19 |
20 |
21 |
22 | Hello -name-,
23 |
24 | I'm glad you are trying out the template feature!
25 |
26 | <%body%>
27 |
28 | I hope you are having a great day in -city- :)
29 |
30 |
31 |
32 | ```
33 |
34 | ## With Mail Helper Class
35 |
36 | ```ruby
37 | require 'sendgrid-ruby'
38 | include SendGrid
39 |
40 | mail = SendGrid::Mail.new
41 | mail.from = Email.new(email: 'test@example.com')
42 | mail.subject = 'I\'m replacing the subject tag'
43 | personalization = Personalization.new
44 | personalization.add_to(Email.new(email: 'test@example.com'))
45 | personalization.add_substitution(Substitution.new(key: '-name-', value: 'Example User'))
46 | personalization.add_substitution(Substitution.new(key: '-city-', value: 'Denver'))
47 | mail.add_personalization(personalization)
48 | mail.template_id = '13b8f94f-bcae-4ec6-b752-70d6cb59f932'
49 |
50 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
51 | begin
52 | response = sg.client.mail._("send").post(request_body: mail.to_json)
53 | rescue Exception => e
54 | puts e.message
55 | end
56 | puts response.status_code
57 | puts response.body
58 | puts response.parsed_body
59 | puts response.headers
60 | ```
61 |
62 | ## Without Mail Helper Class
63 |
64 | ```ruby
65 | require 'sendgrid-ruby'
66 | include SendGrid
67 |
68 | data = JSON.parse('{
69 | "personalizations": [
70 | {
71 | "to": [
72 | {
73 | "email": "test@example.com"
74 | }
75 | ],
76 | "substitutions": {
77 | "-name-": "Example User",
78 | "-city-": "Denver"
79 | },
80 | "subject": "I\'m replacing the subject tag"
81 | }
82 | ],
83 | "from": {
84 | "email": "test@example.com"
85 | },
86 | "template_id": "13b8f94f-bcae-4ec6-b752-70d6cb59f932"
87 | }')
88 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
89 | begin
90 | response = sg.client.mail._("send").post(request_body: data)
91 | rescue Exception => e
92 | puts e.message
93 | end
94 | puts response.status_code
95 | puts response.body
96 | puts response.parsed_body
97 | puts response.headers
98 | ```
99 |
--------------------------------------------------------------------------------
/use-cases/personalizations.md:
--------------------------------------------------------------------------------
1 | # Personalizations
2 |
3 | This example demonstrates how to send multiple emails with personalizations. For further documentation, refer to [the SendGrid docs](https://docs.sendgrid.com/for-developers/sending-email/personalizations).
4 |
5 | ```ruby
6 | require 'sendgrid-ruby'
7 | include SendGrid
8 |
9 | # Note that the domain for all From addresses must match
10 | mail = Mail.new
11 | mail.from = Email.new(email: 'test@example.com')
12 | mail.add_content(Content.new(type: 'text/plain', value: 'Some test text'))
13 | mail.subject = 'Personalized Test Email'
14 |
15 | personalization = Personalization.new
16 | personalization.add_to(Email.new(email: 'test1@example.com'))
17 | mail.add_personalization(personalization)
18 |
19 | personalization2 = Personalization.new
20 | personalization2.add_to(Email.new(email: 'test2@example.com'))
21 | personalization2.add_from(Email.new(email: 'test3@example.com'))
22 | mail.add_personalization(personalization2)
23 |
24 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
25 | begin
26 | response = sg.client.mail._("send").post(request_body: mail.to_json)
27 | rescue Exception => e
28 | puts e.message
29 | end
30 |
31 | puts response.status_code
32 | puts response.body
33 | puts response.headers
34 | ```
--------------------------------------------------------------------------------
/use-cases/sms.md:
--------------------------------------------------------------------------------
1 | First, follow the [Twilio Setup](twilio-setup.md) guide for creating a Twilio account and setting up environment variables with the proper credentials.
2 |
3 | Then, install the Twilio Helper Library. Add this line to your application's Gemfile:
4 |
5 | ```bash
6 | gem 'twilio-ruby'
7 | ```
8 |
9 | And then execute:
10 |
11 | ```bash
12 | bundle
13 | ```
14 |
15 | Or install it yourself using:
16 |
17 | ```bash
18 | gem install twilio-ruby
19 | ```
20 |
21 | Finally, send a message.
22 |
23 | ```ruby
24 | require 'twilio-ruby'
25 |
26 | # put your own credentials here
27 | account_sid = ENV['TWILIO_ACCOUNT_SID']
28 | auth_token = ENV['TWILIO_AUTH_TOKEN']
29 |
30 | # set up a client to talk to the Twilio REST API
31 | @client = Twilio::REST::Client.new account_sid, auth_token
32 | @client.api.account.messages.create(
33 | from: '+14159341234',
34 | to: '+16105557069',
35 | body: 'Hey there!'
36 | )
37 | ```
38 |
39 | For more information, please visit the [Twilio SMS Ruby documentation](https://www.twilio.com/docs/sms/quickstart/ruby).
40 |
--------------------------------------------------------------------------------
/use-cases/transactional-templates.md:
--------------------------------------------------------------------------------
1 | # Transactional Templates
2 |
3 | For this example, we assume you have created a [dynamic transactional template](https://sendgrid.com/docs/ui/sending-email/how-to-send-an-email-with-dynamic-transactional-templates/) in the UI or via the API. Following is the template content we used for testing.
4 |
5 | Template ID (replace with your own):
6 | ```text
7 | d-2c214ac919e84170b21855cc129b4a5f
8 | ```
9 |
10 | Email Subject:
11 | ```text
12 | {{subject}}
13 | ```
14 |
15 | Template Body:
16 | ```html
17 |
18 |
19 |
20 |
21 |
22 | Hello {{name}},
23 |
24 | I'm glad you are trying out the template feature!
25 |
26 | I hope you are having a great day in {{city}} :)
27 |
28 |
29 |
30 | ```
31 |
32 | ## With Mail Helper Class
33 | ```ruby
34 | require 'sendgrid-ruby'
35 | include SendGrid
36 |
37 | mail = Mail.new
38 | mail.from = Email.new(email: 'test@example.com')
39 | personalization = Personalization.new
40 | personalization.add_to(Email.new(email: 'test@example.com'))
41 | personalization.add_dynamic_template_data({
42 | "subject" => "Testing Templates",
43 | "name" => "Example User",
44 | "city" => "Denver"
45 | })
46 | mail.add_personalization(personalization)
47 | mail.template_id = 'd-2c214ac919e84170b21855cc129b4a5f'
48 |
49 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
50 | begin
51 | response = sg.client.mail._("send").post(request_body: mail.to_json)
52 | rescue Exception => e
53 | puts e.message
54 | end
55 | puts response.status_code
56 | puts response.body
57 | puts response.parsed_body
58 | puts response.headers
59 | ```
60 |
61 | ## Without Mail Helper Class
62 |
63 | ```ruby
64 | require 'sendgrid-ruby'
65 | include SendGrid
66 |
67 | data = JSON.parse('{
68 | "personalizations": [
69 | {
70 | "to": [
71 | {
72 | "email": "test@example.com"
73 | }
74 | ],
75 | "dynamic_template_data": {
76 | "subject": "Testing Templates",
77 | "name": "Example User",
78 | "city": "Denver"
79 | }
80 | }
81 | ],
82 | "from": {
83 | "email": "test@example.com"
84 | },
85 | "template_id": "d-2c214ac919e84170b21855cc129b4a5f"
86 | }')
87 | sg = SendGrid::API.new(api_key: ENV['SENDGRID_API_KEY'])
88 | begin
89 | response = sg.client.mail._("send").post(request_body: data)
90 | rescue Exception => e
91 | puts e.message
92 | end
93 | puts response.status_code
94 | puts response.body
95 | puts response.parsed_body
96 | puts response.headers
97 | ```
98 |
99 | ## Adding Attachments
100 |
101 | ```ruby
102 | attachment = Attachment.new
103 | attachment.content = Base64.strict_encode64(File.open(fpath, 'rb').read)
104 | attachment.type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
105 | attachment.filename = fname
106 | attachment.disposition = 'attachment'
107 | attachment.content_id = 'Reports Sheet'
108 | mail.add_attachment(attachment)
109 | ```
110 |
111 | Attachments must be base64 encoded, using Base64's strict_encode64 where no line feeds are added.
112 |
--------------------------------------------------------------------------------
/use-cases/twilio-email.md:
--------------------------------------------------------------------------------
1 | First, follow the [Twilio Setup](twilio-setup.md) guide for creating a Twilio account and setting up environment variables with the proper credentials.
2 |
3 | Then, initialize the Twilio Email Client.
4 |
5 | ```ruby
6 | mail_client = TwilioEmail::API(username: ENV['TWILIO_API_KEY'], password: ENV['TWILIO_API_SECRET'])
7 |
8 | # or
9 |
10 | mail_client = TwilioEmail::API(username: ENV['TWILIO_ACCOUNT_SID'], password: ENV['TWILIO_AUTH_TOKEN'])
11 | ```
12 |
13 | This client has the same interface as the `SendGrid::API` client.
14 |
--------------------------------------------------------------------------------
/use-cases/twilio-setup.md:
--------------------------------------------------------------------------------
1 | ## 1. Obtain a Free Twilio Account
2 |
3 | Sign up for a free Twilio account [here](https://www.twilio.com/try-twilio?source=sendgrid-ruby).
4 |
5 | ## 2. Set Up Your Environment Variables
6 |
7 | The Twilio API allows for authentication using with either an API key/secret or your Account SID/Auth Token. You can create an API key [here](https://twil.io/get-api-key) or obtain your Account SID and Auth Token [here](https://twil.io/console).
8 |
9 | Once you have those, follow the steps below based on your operating system.
10 |
11 | ### Linux/Mac
12 |
13 | ```bash
14 | echo "export TWILIO_API_KEY='YOUR_TWILIO_API_KEY'" > twilio.env
15 | echo "export TWILIO_API_SECRET='YOUR_TWILIO_API_SECRET'" >> twilio.env
16 |
17 | # or
18 |
19 | echo "export TWILIO_ACCOUNT_SID='YOUR_TWILIO_ACCOUNT_SID'" > twilio.env
20 | echo "export TWILIO_AUTH_TOKEN='YOUR_TWILIO_AUTH_TOKEN'" >> twilio.env
21 | ```
22 |
23 | Then:
24 |
25 | ```bash
26 | echo "twilio.env" >> .gitignore
27 | source ./twilio.env
28 | ```
29 |
30 | ### Windows
31 |
32 | Temporarily set the environment variable (accessible only during the current CLI session):
33 |
34 | ```bash
35 | set TWILIO_API_KEY=YOUR_TWILIO_API_KEY
36 | set TWILIO_API_SECRET=YOUR_TWILIO_API_SECRET
37 |
38 | : or
39 |
40 | set TWILIO_ACCOUNT_SID=YOUR_TWILIO_ACCOUNT_SID
41 | set TWILIO_AUTH_TOKEN=YOUR_TWILIO_AUTH_TOKEN
42 | ```
43 |
44 | Or permanently set the environment variable (accessible in all subsequent CLI sessions):
45 |
46 | ```bash
47 | setx TWILIO_API_KEY "YOUR_TWILIO_API_KEY"
48 | setx TWILIO_API_SECRET "YOUR_TWILIO_API_SECRET"
49 |
50 | : or
51 |
52 | setx TWILIO_ACCOUNT_SID "YOUR_TWILIO_ACCOUNT_SID"
53 | setx TWILIO_AUTH_TOKEN "YOUR_TWILIO_AUTH_TOKEN"
54 | ```
55 |
--------------------------------------------------------------------------------