sendgrid-ruby 0.0.3 → 1.0.0.alpha.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +35 -17
- data/.rspec +2 -0
- data/.rubocop.yml +30 -0
- data/.travis.yml +20 -0
- data/Guardfile +7 -9
- data/README.md +11 -2
- data/Rakefile +5 -5
- data/lib/sendgrid/client.rb +63 -0
- data/lib/sendgrid/mail.rb +114 -34
- data/lib/sendgrid/response.rb +14 -0
- data/lib/sendgrid/version.rb +1 -1
- data/lib/sendgrid_ruby.rb +5 -0
- data/sendgrid-ruby.gemspec +7 -3
- data/spec/lib/sendgrid/client_spec.rb +83 -0
- data/spec/lib/sendgrid/mail_spec.rb +123 -0
- data/spec/lib/sendgrid_spec.rb +7 -0
- data/spec/spec_helper.rb +1 -0
- metadata +85 -16
- data/lib/sendgrid-ruby.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 151bbef80094a16705ac90105265586a3b297f72
|
4
|
+
data.tar.gz: 978bc5da9b1f788440e1e7e55cb821a0864571da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6445b8feda2318bb755c4a0a448f3456610d2de94982ae223acee641e1c5a1ea4ac6177e94fd89fd46323434f71512221528f904a967738f5aed176c0634e6c7
|
7
|
+
data.tar.gz: 379ae309fb47ad14331bc2747b226f016a865c8671d45567ab725eef5f2fdb8db4daf305ffba6143d3070b99302472863017484f860282b052b5d32116b18f6d
|
data/.gitignore
CHANGED
@@ -1,21 +1,39 @@
|
|
1
|
+
# Created by https://www.gitignore.io
|
2
|
+
|
3
|
+
### Ruby ###
|
1
4
|
*.gem
|
2
5
|
*.rbc
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
+
/.config
|
7
|
+
/coverage/
|
8
|
+
/InstalledFiles
|
9
|
+
/pkg/
|
10
|
+
/spec/reports/
|
11
|
+
/test/tmp/
|
12
|
+
/test/version_tmp/
|
13
|
+
/tmp/
|
14
|
+
|
15
|
+
## Specific to RubyMotion:
|
16
|
+
.dat*
|
17
|
+
.repl_history
|
18
|
+
build/
|
19
|
+
|
20
|
+
## Documentation cache and generated files:
|
21
|
+
/.yardoc/
|
22
|
+
/_yardoc/
|
23
|
+
/doc/
|
24
|
+
/rdoc/
|
25
|
+
|
26
|
+
## Environment normalisation:
|
27
|
+
/.bundle/
|
28
|
+
/vendor/bundle
|
29
|
+
/lib/bundler/man/
|
30
|
+
|
31
|
+
# for a library or gem, you might want to ignore these files since the code is
|
32
|
+
# intended to run in multiple environments; otherwise, check them in:
|
6
33
|
Gemfile.lock
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
pkg
|
13
|
-
rdoc
|
34
|
+
.ruby-version
|
35
|
+
.ruby-gemset
|
36
|
+
|
37
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
38
|
+
.rvmrc
|
14
39
|
|
15
|
-
tmp
|
16
|
-
*.bundle
|
17
|
-
*.so
|
18
|
-
*.o
|
19
|
-
*.a
|
20
|
-
mkmf.log
|
21
|
-
.DS_Store
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Metrics/AbcSize:
|
2
|
+
Max: 37
|
3
|
+
|
4
|
+
# Configuration parameters: CountComments.
|
5
|
+
Metrics/ClassLength:
|
6
|
+
Max: 109
|
7
|
+
|
8
|
+
Metrics/CyclomaticComplexity:
|
9
|
+
Max: 7
|
10
|
+
|
11
|
+
# Configuration parameters: AllowURI, URISchemes.
|
12
|
+
Metrics/LineLength:
|
13
|
+
Max: 132
|
14
|
+
|
15
|
+
# Configuration parameters: CountComments.
|
16
|
+
Metrics/MethodLength:
|
17
|
+
Max: 22
|
18
|
+
|
19
|
+
Style/Documentation:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
# Cop supports --auto-correct.
|
23
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters.
|
24
|
+
Style/SpaceInsideBlockBraces:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
# Cop supports --auto-correct.
|
28
|
+
# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles.
|
29
|
+
Style/SpaceInsideHashLiteralBraces:
|
30
|
+
Enabled: false
|
data/.travis.yml
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.2
|
4
|
+
- 2.0
|
5
|
+
- 1.9.3
|
6
|
+
notifications:
|
7
|
+
hipchat:
|
8
|
+
rooms:
|
9
|
+
secure: gYBEwOGBTxHE2nrxsHQqp2UdjRtCX04wVLYEimeT9RG/0LClS4nzJF7DaXLWlAwgLPmk+KV2+nXuLO5oausBr9ODmWhho8G0F90RPR47NupcvT1RM+I2ZbxSjHCUICL22mdnZd8ye/mrk/YtFWYmgmH7ILRK3BuYovXFoKoRnLg=
|
10
|
+
template:
|
11
|
+
- '<a href="https://travis-ci.org/%{repository}/builds/%{build_id}">%{repository}
|
12
|
+
Build %{build_number}</a> on branch <i>%{branch}</i> by %{author}: <strong>%{message}</strong>
|
13
|
+
<a href="https://github.com/sendgrid/docs/commits/%{commit}">View on GitHub</a>'
|
14
|
+
format: html
|
15
|
+
notify: true
|
16
|
+
before_script:
|
17
|
+
- bundle install
|
18
|
+
script:
|
19
|
+
- rubocop --fail-level=W
|
20
|
+
- rake
|
data/Guardfile
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
notification :gntp
|
2
|
-
guard 'rspec' do
|
3
|
-
|
4
|
-
watch(%r{^lib/(.+)
|
5
|
-
|
6
|
-
|
2
|
+
guard :rspec, cmd: 'rspec' do
|
3
|
+
watch(%r{^spec/.+_spec\.rb$})
|
4
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
5
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
6
|
+
end
|
7
7
|
|
8
|
-
|
9
|
-
watch(%r{^
|
10
|
-
"spec/#{m[1]}.rb"
|
11
|
-
end
|
8
|
+
guard :rubocop, all_on_start: false do
|
9
|
+
watch(%r{^lib/(.+)\.rb$})
|
12
10
|
end
|
data/README.md
CHANGED
@@ -4,6 +4,8 @@ This Gem allows you to quickly and easily send emails through SendGrid's Web API
|
|
4
4
|
|
5
5
|
You can read our official documentation on the Web API's Mail feature [here](https://sendgrid.com/docs/API_Reference/Web_API/mail.html).
|
6
6
|
|
7
|
+
[![BuildStatus](https://travis-ci.org/sendgrid/sendgrid-ruby.svg?branch=master)](https://travis-ci.org/sendgrid/sendgrid-ruby)
|
8
|
+
|
7
9
|
|
8
10
|
## Installation
|
9
11
|
|
@@ -49,11 +51,18 @@ puts client.send(mail)
|
|
49
51
|
# {"message":"success"}
|
50
52
|
```
|
51
53
|
|
52
|
-
You can also create a mail object with a hash
|
54
|
+
You can also create a mail object with a hash:
|
53
55
|
```ruby
|
54
56
|
client.send(SendGrid::Mail.new(to: 'example@example.com', from: 'taco@cat.limo', subject: 'Hello world!', text: 'Hi there!', html: '<b>Hi there!</b>'))
|
55
57
|
|
56
|
-
|
58
|
+
# {"message":"success"}
|
59
|
+
```
|
60
|
+
|
61
|
+
#### Attachments
|
62
|
+
|
63
|
+
Attachments can be added to a mail object with the `add_attachment` method. The first parameter is the path to the file, the second (optional) parameter is the desired name of the file. If a file name is not provided, it will use the original filename.
|
64
|
+
```ruby
|
65
|
+
mail.add_attachment('/tmp/report.pdf', 'july_report.pdf')
|
57
66
|
```
|
58
67
|
|
59
68
|
#### Available Params
|
data/Rakefile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'rspec/core/rake_task'
|
2
1
|
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
3
5
|
|
4
|
-
|
5
|
-
task.rspec_opts = ['--color', '--format', 'nested']
|
6
|
-
end
|
6
|
+
task test: :spec
|
7
7
|
|
8
|
-
task default: :
|
8
|
+
task default: :test
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module SendGrid
|
4
|
+
class Client
|
5
|
+
attr_accessor :api_user, :api_key, :protocol, :host, :port, :url, :endpoint,
|
6
|
+
:user_agent
|
7
|
+
attr_writer :adapter, :conn, :raise_exceptions
|
8
|
+
|
9
|
+
def initialize(params = {})
|
10
|
+
self.api_user = params.fetch(:api_user, nil)
|
11
|
+
self.api_key = params.fetch(:api_key, nil)
|
12
|
+
self.protocol = params.fetch(:protocol, 'https')
|
13
|
+
self.host = params.fetch(:host, 'api.sendgrid.com')
|
14
|
+
self.port = params.fetch(:port, nil)
|
15
|
+
self.url = params.fetch(:url, protocol + '://' + host + (port ? ":#{port}" : ''))
|
16
|
+
self.endpoint = params.fetch(:endpoint, '/api/mail.send.json')
|
17
|
+
self.adapter = params.fetch(:adapter, adapter)
|
18
|
+
self.conn = params.fetch(:conn, conn)
|
19
|
+
self.user_agent = params.fetch(:user_agent, "sendgrid/#{SendGrid::VERSION};ruby")
|
20
|
+
self.raise_exceptions = params.fetch(:raise_exceptions, true)
|
21
|
+
yield self if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
def send(mail)
|
25
|
+
res = conn.post do |req|
|
26
|
+
payload = mail.to_h
|
27
|
+
|
28
|
+
req.url(endpoint)
|
29
|
+
|
30
|
+
# Check if using username + password or API key
|
31
|
+
if api_user
|
32
|
+
# Username + password
|
33
|
+
payload = payload.merge(api_user: api_user, api_key: api_key)
|
34
|
+
else
|
35
|
+
# API key
|
36
|
+
req.headers['Authorization'] = "Bearer #{api_key}"
|
37
|
+
end
|
38
|
+
|
39
|
+
req.body = payload
|
40
|
+
end
|
41
|
+
|
42
|
+
fail SendGrid::Exception, res.body if raise_exceptions? && res.status != 200
|
43
|
+
|
44
|
+
SendGrid::Response.new(code: res.status, headers: res.headers, body: res.body)
|
45
|
+
end
|
46
|
+
|
47
|
+
def conn
|
48
|
+
@conn ||= Faraday.new(url: url) do |conn|
|
49
|
+
conn.request :multipart
|
50
|
+
conn.request :url_encoded
|
51
|
+
conn.adapter adapter
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def adapter
|
56
|
+
@adapter ||= Faraday.default_adapter
|
57
|
+
end
|
58
|
+
|
59
|
+
def raise_exceptions?
|
60
|
+
@raise_exceptions
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/sendgrid/mail.rb
CHANGED
@@ -3,58 +3,138 @@ require 'smtpapi'
|
|
3
3
|
|
4
4
|
module SendGrid
|
5
5
|
class Mail
|
6
|
-
attr_accessor :to, :to_name, :from, :from_name, :subject, :text, :html, :cc,
|
7
|
-
|
6
|
+
attr_accessor :to, :to_name, :from, :from_name, :subject, :text, :html, :cc,
|
7
|
+
:bcc, :reply_to, :date, :smtpapi, :attachments
|
8
8
|
|
9
9
|
def initialize(params = {})
|
10
10
|
params.each do |k, v|
|
11
|
-
|
11
|
+
send(:"#{k}=", v) unless v.nil?
|
12
12
|
end
|
13
|
-
@headers ||= {}
|
14
|
-
@attachments ||= []
|
15
|
-
@smtpapi ||= Smtpapi::Header.new
|
16
13
|
yield self if block_given?
|
17
14
|
end
|
18
15
|
|
19
|
-
def add_to(
|
20
|
-
|
16
|
+
def add_to(email, name = nil)
|
17
|
+
if email.is_a?(Array)
|
18
|
+
to.concat(email)
|
19
|
+
else
|
20
|
+
to << email
|
21
|
+
end
|
22
|
+
add_to_name(name) if name
|
23
|
+
end
|
24
|
+
|
25
|
+
def to
|
26
|
+
@to ||= []
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_name
|
30
|
+
@to_name ||= []
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_to_name(name)
|
34
|
+
if name.is_a?(Array)
|
35
|
+
to_name.concat(name)
|
36
|
+
else
|
37
|
+
to_name << name
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def cc
|
42
|
+
@cc ||= []
|
43
|
+
end
|
44
|
+
|
45
|
+
def cc_name
|
46
|
+
@cc_name ||= []
|
47
|
+
end
|
48
|
+
|
49
|
+
def add_cc(email, name = nil)
|
50
|
+
if email.is_a?(Array)
|
51
|
+
cc.concat(email)
|
52
|
+
else
|
53
|
+
cc << email
|
54
|
+
end
|
55
|
+
add_cc_name(name) if name
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_cc_name(name)
|
59
|
+
if name.is_a?(Array)
|
60
|
+
cc_name.concat(name)
|
61
|
+
else
|
62
|
+
cc_name << name
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def bcc
|
67
|
+
@bcc ||= []
|
68
|
+
end
|
69
|
+
|
70
|
+
def bcc_name
|
71
|
+
@bcc_name ||= []
|
72
|
+
end
|
73
|
+
|
74
|
+
def add_bcc(email, name = nil)
|
75
|
+
if email.is_a?(Array)
|
76
|
+
bcc.concat(email)
|
77
|
+
else
|
78
|
+
bcc << email
|
79
|
+
end
|
80
|
+
add_bcc_name(name)
|
81
|
+
end
|
82
|
+
|
83
|
+
def add_bcc_name(name)
|
84
|
+
if name.is_a?(Array)
|
85
|
+
bcc_name.concat(name)
|
86
|
+
else
|
87
|
+
bcc_name << name
|
88
|
+
end
|
21
89
|
end
|
22
90
|
|
23
91
|
def add_attachment(path, name = nil)
|
24
92
|
file = File.new(path)
|
25
93
|
name ||= File.basename(file)
|
26
|
-
|
94
|
+
attachments << {file: file, name: name}
|
95
|
+
end
|
96
|
+
|
97
|
+
def headers
|
98
|
+
@headers ||= {}
|
27
99
|
end
|
28
100
|
|
101
|
+
def attachments
|
102
|
+
@attachments ||= []
|
103
|
+
end
|
104
|
+
|
105
|
+
def smtpapi
|
106
|
+
@smtpapi ||= Smtpapi::Header.new
|
107
|
+
end
|
108
|
+
|
109
|
+
# rubocop:disable Style/HashSyntax
|
29
110
|
def to_h
|
30
111
|
payload = {
|
31
|
-
:from
|
32
|
-
:fromname
|
33
|
-
:subject
|
34
|
-
:to
|
35
|
-
:toname
|
36
|
-
:date
|
37
|
-
:replyto
|
38
|
-
:cc
|
39
|
-
:bcc
|
40
|
-
:text
|
41
|
-
:html
|
42
|
-
:'x-smtpapi' =>
|
43
|
-
:files
|
44
|
-
}.reject {|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
unless @attachments.empty?
|
52
|
-
@attachments.each do |file|
|
53
|
-
payload[:files][file[:name]] = file[:file]
|
54
|
-
end
|
55
|
-
end
|
112
|
+
:from => from,
|
113
|
+
:fromname => from_name,
|
114
|
+
:subject => subject,
|
115
|
+
:to => to,
|
116
|
+
:toname => to_name,
|
117
|
+
:date => date,
|
118
|
+
:replyto => reply_to,
|
119
|
+
:cc => cc,
|
120
|
+
:bcc => bcc,
|
121
|
+
:text => text,
|
122
|
+
:html => html,
|
123
|
+
:'x-smtpapi' => smtpapi.to_json,
|
124
|
+
:files => ({} unless attachments.empty?)
|
125
|
+
}.reject {|_, v| v.nil? || v.empty?}
|
126
|
+
|
127
|
+
payload.delete(:'x-smtpapi') if payload[:'x-smtpapi'] == '{}'
|
128
|
+
|
129
|
+
payload[:to] = payload[:from] unless payload[:to].nil? && smtpapi.to.empty?
|
56
130
|
|
131
|
+
return payload if attachments.empty?
|
132
|
+
|
133
|
+
attachments.each do |file|
|
134
|
+
payload[:files][file[:name]] = file[:file]
|
135
|
+
end
|
57
136
|
payload
|
58
137
|
end
|
138
|
+
# rubocop:enable Style/HashSyntax
|
59
139
|
end
|
60
140
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module SendGrid
|
4
|
+
class Response
|
5
|
+
attr_reader :code, :headers, :body, :raw_body
|
6
|
+
|
7
|
+
def initialize(params)
|
8
|
+
@code = params[:code]
|
9
|
+
@headers = params[:headers]
|
10
|
+
@body = JSON.parse(params[:body])
|
11
|
+
@raw_body = params[:body]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/sendgrid/version.rb
CHANGED
data/sendgrid-ruby.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['Robin Johnson', 'Eddie Zaneski']
|
10
10
|
spec.email = 'community@sendgrid.com'
|
11
11
|
spec.summary = 'Official SendGrid Gem'
|
12
|
-
spec.description = 'Interact with SendGrids API in
|
12
|
+
spec.description = 'Interact with SendGrids API in native Ruby'
|
13
13
|
spec.homepage = 'http://github.com/sendgrid/sendgrid-ruby'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
@@ -18,12 +18,16 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(/^(test|spec|features)/)
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency 'smtpapi'
|
22
|
-
spec.add_dependency '
|
21
|
+
spec.add_dependency 'smtpapi', '~> 0.1'
|
22
|
+
spec.add_dependency 'faraday', '~> 0.9'
|
23
23
|
spec.add_development_dependency 'rake'
|
24
24
|
spec.add_development_dependency 'rspec'
|
25
25
|
spec.add_development_dependency 'rspec-nc'
|
26
|
+
spec.add_development_dependency 'webmock'
|
26
27
|
spec.add_development_dependency 'guard'
|
27
28
|
spec.add_development_dependency 'guard-rspec'
|
29
|
+
spec.add_development_dependency 'rubocop'
|
30
|
+
spec.add_development_dependency 'guard-rubocop'
|
31
|
+
spec.add_development_dependency 'ruby_gntp'
|
28
32
|
spec.add_development_dependency 'bundler', '~> 1.6'
|
29
33
|
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'webmock/rspec'
|
4
|
+
|
5
|
+
describe 'SendGrid::Client' do
|
6
|
+
it 'should accept a username and password' do
|
7
|
+
expect(SendGrid::Client.new(api_user: 'test', api_key: 'test')).to be_an_instance_of(SendGrid::Client)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should accept an api key' do
|
11
|
+
expect(SendGrid::Client.new(api_key: 'sendgrid_123')).to be_an_instance_of(SendGrid::Client)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should build the default url' do
|
15
|
+
expect(SendGrid::Client.new.url).to eq('https://api.sendgrid.com')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should build a custom url' do
|
19
|
+
expect(SendGrid::Client.new(port: 3000, host: 'foo.sendgrid.com', protocol: 'tacos').url).to eq('tacos://foo.sendgrid.com:3000')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should use the default endpoint' do
|
23
|
+
expect(SendGrid::Client.new.endpoint).to eq('/api/mail.send.json')
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ':send' do
|
27
|
+
it 'should make a request to sendgrid' do
|
28
|
+
stub_request(:any, 'https://api.sendgrid.com/api/mail.send.json')
|
29
|
+
.to_return(body: {message: 'success'}.to_json, status: 200, headers: {'X-TEST' => 'yes'})
|
30
|
+
|
31
|
+
client = SendGrid::Client.new(api_key: 'abc123')
|
32
|
+
mail = SendGrid::Mail.new
|
33
|
+
res = client.send(mail)
|
34
|
+
expect(res.code).to eq(200)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should have an auth header when using an api key' do
|
38
|
+
stub_request(:any, 'https://api.sendgrid.com/api/mail.send.json')
|
39
|
+
.to_return(body: {message: 'success'}.to_json, status: 200, headers: {'X-TEST' => 'yes'})
|
40
|
+
|
41
|
+
client = SendGrid::Client.new(api_key: 'abc123')
|
42
|
+
mail = SendGrid::Mail.new
|
43
|
+
|
44
|
+
client.send(mail)
|
45
|
+
|
46
|
+
expect(WebMock).to have_requested(:post, 'https://api.sendgrid.com/api/mail.send.json')
|
47
|
+
.with(headers: {'Authorization' => 'Bearer abc123'})
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should have a username + password when using them' do
|
51
|
+
stub_request(:any, 'https://api.sendgrid.com/api/mail.send.json')
|
52
|
+
.to_return(body: {message: 'success'}.to_json, status: 200, headers: {'X-TEST' => 'yes'})
|
53
|
+
|
54
|
+
client = SendGrid::Client.new(api_user: 'foobar', api_key: 'abc123')
|
55
|
+
mail = SendGrid::Mail.new
|
56
|
+
|
57
|
+
client.send(mail)
|
58
|
+
|
59
|
+
expect(WebMock).to have_requested(:post, 'https://api.sendgrid.com/api/mail.send.json')
|
60
|
+
.with(body: 'api_key=abc123&api_user=foobar')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should raise a SendGrid::Exception if status is not 200' do
|
64
|
+
stub_request(:any, 'https://api.sendgrid.com/api/mail.send.json')
|
65
|
+
.to_return(body: {message: 'error', errors: ['Bad username / password']}.to_json, status: 400, headers: {'X-TEST' => 'yes'})
|
66
|
+
|
67
|
+
client = SendGrid::Client.new(api_user: 'foobar', api_key: 'abc123')
|
68
|
+
mail = SendGrid::Mail.new
|
69
|
+
|
70
|
+
expect {client.send(mail)}.to raise_error(SendGrid::Exception)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should not raise a SendGrid::Exception if raise_exceptions is disabled' do
|
74
|
+
stub_request(:any, 'https://api.sendgrid.com/api/mail.send.json')
|
75
|
+
.to_return(body: {message: 'error', errors: ['Bad username / password']}.to_json, status: 400, headers: {'X-TEST' => 'yes'})
|
76
|
+
|
77
|
+
client = SendGrid::Client.new(api_user: 'foobar', api_key: 'abc123', raise_exceptions: false)
|
78
|
+
mail = SendGrid::Mail.new
|
79
|
+
|
80
|
+
expect {client.send(mail)}.not_to raise_error
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'SendGrid::Mail' do
|
4
|
+
before(:each) do
|
5
|
+
@mail = SendGrid::Mail.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should create an instance' do
|
9
|
+
expect(SendGrid::Mail.new).to be_an_instance_of(SendGrid::Mail)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'add_to_name' do
|
13
|
+
it 'should accept a name' do
|
14
|
+
@mail.add_to_name('Frank Foo')
|
15
|
+
expect(@mail.to_name).to eq(['Frank Foo'])
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should accept an array of names' do
|
19
|
+
@mail.add_to_name(['Frank Foo', 'Bob Bar'])
|
20
|
+
expect(@mail.to_name).to eq(['Frank Foo', 'Bob Bar'])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'add_to' do
|
25
|
+
it 'should accept an email' do
|
26
|
+
@mail.add_to('foo@example.com')
|
27
|
+
expect(@mail.to).to eq(['foo@example.com'])
|
28
|
+
|
29
|
+
@mail.add_to('bar@example.com')
|
30
|
+
expect(@mail.to).to eq(['foo@example.com', 'bar@example.com'])
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should accept an email and name' do
|
34
|
+
@mail.add_to('foo@example.com', 'Frank Foo')
|
35
|
+
expect(@mail.to).to eq(['foo@example.com'])
|
36
|
+
expect(@mail.to_name).to eq(['Frank Foo'])
|
37
|
+
|
38
|
+
@mail.add_to('bar@example.com', 'Bob Bar')
|
39
|
+
expect(@mail.to).to eq(['foo@example.com', 'bar@example.com'])
|
40
|
+
expect(@mail.to_name).to eq(['Frank Foo', 'Bob Bar'])
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should accept an array of emails' do
|
44
|
+
@mail.add_to(['foo@example.com', 'bar@example.com'])
|
45
|
+
expect(@mail.to).to eq(['foo@example.com', 'bar@example.com'])
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should accept an array of emails and names' do
|
49
|
+
@mail.add_to(['foo@example.com', 'bar@example.com'], ['Frank Foo', 'Bob Bar'])
|
50
|
+
expect(@mail.to).to eq(['foo@example.com', 'bar@example.com'])
|
51
|
+
expect(@mail.to_name).to eq(['Frank Foo', 'Bob Bar'])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'add_cc' do
|
56
|
+
it 'should accept an email' do
|
57
|
+
@mail.add_cc('foo@example.com')
|
58
|
+
expect(@mail.cc).to eq(['foo@example.com'])
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should accept an email and a name' do
|
62
|
+
@mail.add_cc('foo@example.com', 'Frank Foo')
|
63
|
+
expect(@mail.cc).to eq(['foo@example.com'])
|
64
|
+
expect(@mail.cc_name).to eq(['Frank Foo'])
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should accept an array of emails' do
|
68
|
+
@mail.add_cc(['foo@example.com', 'bar@example.com'])
|
69
|
+
expect(@mail.cc).to eq(['foo@example.com', 'bar@example.com'])
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should accept an array of emails and names' do
|
73
|
+
@mail.add_cc(['foo@example.com', 'bar@example.com'], ['Frank Foo', 'Bob Bar'])
|
74
|
+
expect(@mail.cc).to eq(['foo@example.com', 'bar@example.com'])
|
75
|
+
expect(@mail.cc_name).to eq(['Frank Foo', 'Bob Bar'])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'add_bcc' do
|
80
|
+
it 'should accept an email' do
|
81
|
+
@mail.add_bcc('foo@example.com')
|
82
|
+
expect(@mail.bcc).to eq(['foo@example.com'])
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should accept an email and a name' do
|
86
|
+
@mail.add_bcc('foo@example.com', 'Frank Foo')
|
87
|
+
expect(@mail.bcc).to eq(['foo@example.com'])
|
88
|
+
expect(@mail.bcc_name).to eq(['Frank Foo'])
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should accept an array of emails' do
|
92
|
+
@mail.add_bcc(['foo@example.com', 'bar@example.com'])
|
93
|
+
expect(@mail.bcc).to eq(['foo@example.com', 'bar@example.com'])
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should accept an array of emails and names' do
|
97
|
+
@mail.add_bcc(['foo@example.com', 'bar@example.com'], ['Frank Foo', 'Bob Bar'])
|
98
|
+
expect(@mail.bcc).to eq(['foo@example.com', 'bar@example.com'])
|
99
|
+
expect(@mail.bcc_name).to eq(['Frank Foo', 'Bob Bar'])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe 'to' do
|
104
|
+
it 'should be set' do
|
105
|
+
@mail.to = 'foo@example.com'
|
106
|
+
expect(@mail.to).to eq('foo@example.com')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'from_name' do
|
111
|
+
it 'should be set' do
|
112
|
+
@mail.from_name = 'Frank Foo'
|
113
|
+
expect(@mail.from_name).to eq('Frank Foo')
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe 'reply_to' do
|
118
|
+
it 'should be set' do
|
119
|
+
@mail.reply_to = 'foo@example.com'
|
120
|
+
expect(@mail.reply_to).to eq('foo@example.com')
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative '../lib/sendgrid_ruby'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sendgrid-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 1.0.0.alpha.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robin Johnson
|
@@ -9,16 +9,44 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-06-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: smtpapi
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0.1'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0.1'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: faraday
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0.9'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0.9'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
16
44
|
requirement: !ruby/object:Gem::Requirement
|
17
45
|
requirements:
|
18
46
|
- - ">="
|
19
47
|
- !ruby/object:Gem::Version
|
20
48
|
version: '0'
|
21
|
-
type: :
|
49
|
+
type: :development
|
22
50
|
prerelease: false
|
23
51
|
version_requirements: !ruby/object:Gem::Requirement
|
24
52
|
requirements:
|
@@ -26,13 +54,13 @@ dependencies:
|
|
26
54
|
- !ruby/object:Gem::Version
|
27
55
|
version: '0'
|
28
56
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
57
|
+
name: rspec
|
30
58
|
requirement: !ruby/object:Gem::Requirement
|
31
59
|
requirements:
|
32
60
|
- - ">="
|
33
61
|
- !ruby/object:Gem::Version
|
34
62
|
version: '0'
|
35
|
-
type: :
|
63
|
+
type: :development
|
36
64
|
prerelease: false
|
37
65
|
version_requirements: !ruby/object:Gem::Requirement
|
38
66
|
requirements:
|
@@ -40,7 +68,7 @@ dependencies:
|
|
40
68
|
- !ruby/object:Gem::Version
|
41
69
|
version: '0'
|
42
70
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
71
|
+
name: rspec-nc
|
44
72
|
requirement: !ruby/object:Gem::Requirement
|
45
73
|
requirements:
|
46
74
|
- - ">="
|
@@ -54,7 +82,7 @@ dependencies:
|
|
54
82
|
- !ruby/object:Gem::Version
|
55
83
|
version: '0'
|
56
84
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
85
|
+
name: webmock
|
58
86
|
requirement: !ruby/object:Gem::Requirement
|
59
87
|
requirements:
|
60
88
|
- - ">="
|
@@ -68,7 +96,7 @@ dependencies:
|
|
68
96
|
- !ruby/object:Gem::Version
|
69
97
|
version: '0'
|
70
98
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
99
|
+
name: guard
|
72
100
|
requirement: !ruby/object:Gem::Requirement
|
73
101
|
requirements:
|
74
102
|
- - ">="
|
@@ -82,7 +110,7 @@ dependencies:
|
|
82
110
|
- !ruby/object:Gem::Version
|
83
111
|
version: '0'
|
84
112
|
- !ruby/object:Gem::Dependency
|
85
|
-
name: guard
|
113
|
+
name: guard-rspec
|
86
114
|
requirement: !ruby/object:Gem::Requirement
|
87
115
|
requirements:
|
88
116
|
- - ">="
|
@@ -96,7 +124,35 @@ dependencies:
|
|
96
124
|
- !ruby/object:Gem::Version
|
97
125
|
version: '0'
|
98
126
|
- !ruby/object:Gem::Dependency
|
99
|
-
name:
|
127
|
+
name: rubocop
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: guard-rubocop
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: ruby_gntp
|
100
156
|
requirement: !ruby/object:Gem::Requirement
|
101
157
|
requirements:
|
102
158
|
- - ">="
|
@@ -123,23 +179,32 @@ dependencies:
|
|
123
179
|
- - "~>"
|
124
180
|
- !ruby/object:Gem::Version
|
125
181
|
version: '1.6'
|
126
|
-
description: Interact with SendGrids API in
|
182
|
+
description: Interact with SendGrids API in native Ruby
|
127
183
|
email: community@sendgrid.com
|
128
184
|
executables: []
|
129
185
|
extensions: []
|
130
186
|
extra_rdoc_files: []
|
131
187
|
files:
|
132
188
|
- ".gitignore"
|
189
|
+
- ".rspec"
|
190
|
+
- ".rubocop.yml"
|
191
|
+
- ".travis.yml"
|
133
192
|
- Gemfile
|
134
193
|
- Guardfile
|
135
194
|
- LICENSE.txt
|
136
195
|
- README.md
|
137
196
|
- Rakefile
|
138
|
-
- lib/sendgrid
|
197
|
+
- lib/sendgrid/client.rb
|
139
198
|
- lib/sendgrid/exceptions.rb
|
140
199
|
- lib/sendgrid/mail.rb
|
200
|
+
- lib/sendgrid/response.rb
|
141
201
|
- lib/sendgrid/version.rb
|
202
|
+
- lib/sendgrid_ruby.rb
|
142
203
|
- sendgrid-ruby.gemspec
|
204
|
+
- spec/lib/sendgrid/client_spec.rb
|
205
|
+
- spec/lib/sendgrid/mail_spec.rb
|
206
|
+
- spec/lib/sendgrid_spec.rb
|
207
|
+
- spec/spec_helper.rb
|
143
208
|
homepage: http://github.com/sendgrid/sendgrid-ruby
|
144
209
|
licenses:
|
145
210
|
- MIT
|
@@ -155,13 +220,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
220
|
version: '0'
|
156
221
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
222
|
requirements:
|
158
|
-
- - "
|
223
|
+
- - ">"
|
159
224
|
- !ruby/object:Gem::Version
|
160
|
-
version:
|
225
|
+
version: 1.3.1
|
161
226
|
requirements: []
|
162
227
|
rubyforge_project:
|
163
|
-
rubygems_version: 2.4.
|
228
|
+
rubygems_version: 2.4.5
|
164
229
|
signing_key:
|
165
230
|
specification_version: 4
|
166
231
|
summary: Official SendGrid Gem
|
167
|
-
test_files:
|
232
|
+
test_files:
|
233
|
+
- spec/lib/sendgrid/client_spec.rb
|
234
|
+
- spec/lib/sendgrid/mail_spec.rb
|
235
|
+
- spec/lib/sendgrid_spec.rb
|
236
|
+
- spec/spec_helper.rb
|
data/lib/sendgrid-ruby.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require_relative 'sendgrid/exceptions'
|
2
|
-
require_relative 'sendgrid/mail'
|
3
|
-
require_relative 'sendgrid/version'
|
4
|
-
|
5
|
-
require 'rest-client'
|
6
|
-
|
7
|
-
module SendGrid
|
8
|
-
class Client
|
9
|
-
attr_accessor :api_user, :api_key, :host, :endpoint
|
10
|
-
|
11
|
-
def initialize(params = {})
|
12
|
-
@api_user = params.fetch(:api_user, nil)
|
13
|
-
@api_key = params.fetch(:api_key, nil)
|
14
|
-
@host = params.fetch(:host, 'https://api.sendgrid.com')
|
15
|
-
@endpoint = params.fetch(:endpoint, '/api/mail.send.json')
|
16
|
-
@conn = params.fetch(:conn, create_conn)
|
17
|
-
@user_agent = params.fetch(:user_agent, 'sendgrid/' + SendGrid::VERSION + ';ruby')
|
18
|
-
yield self if block_given?
|
19
|
-
raise SendGrid::Exception.new('api_user and api_key are required') unless @api_user && @api_key
|
20
|
-
end
|
21
|
-
|
22
|
-
def send(mail)
|
23
|
-
payload = mail.to_h.merge({api_user: @api_user, api_key: @api_key})
|
24
|
-
@conn[@endpoint].post(payload, {user_agent: @user_agent}) do |response, request, result|
|
25
|
-
case response.code.to_s
|
26
|
-
when /2\d\d/
|
27
|
-
response
|
28
|
-
when /4\d\d|5\d\d/
|
29
|
-
raise SendGrid::Exception.new(response)
|
30
|
-
else
|
31
|
-
# TODO: What will reach this?
|
32
|
-
"DEFAULT #{response.code} #{response}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
|
39
|
-
def create_conn
|
40
|
-
@conn = RestClient::Resource.new(@host)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|