sparkpost 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc6408b4b46931661f45f43c8b1f37e0492ea4ba
4
- data.tar.gz: 8836156574c1979033b5b3638c3ec348c3519608
3
+ metadata.gz: 796669253fea19aa5100d4947812dcd522c5b740
4
+ data.tar.gz: 1ef22cf099b5f094ff1d4fe947f45e27bd3c6ae8
5
5
  SHA512:
6
- metadata.gz: ebdcdd2123e18efc025c971ca8333bda26c691bed4d27f1cb8ec2c2d6db55cc0413efaa54543747a7e15316da343e41c5af83550d51878ef561d4312976089c9
7
- data.tar.gz: 59b664eb000246a06381800f952d0d16a674f670ed1e93f539aef52ec319035e9c9d1dd30be86486552ca9c32725b8ae2b5cf2e799344bf84751f584e278b52d
6
+ metadata.gz: 3d8ebe367055686b7d287464754e8b868b9c25d228f8e96ccb3ff9ddafcf13be99555994badb816a63fc15a47fd7a7377d180c3083445473f9cf45863b8483a7
7
+ data.tar.gz: 6e5a7ff2c7532b778c5e87534a5d15d0e73bee8c53ed9bd452b2e3834e4730c0f8d74f5c18d0a13942b1094d7448a460d003bab998da0ec3b682f9efd78f22c5
data/.gitignore CHANGED
@@ -19,3 +19,5 @@ tmp
19
19
  .idea
20
20
  .ruby-gemset
21
21
  coverage
22
+ _examples
23
+ .byebug_history
data/.rubocop.yml ADDED
@@ -0,0 +1,13 @@
1
+ Style/FirstParameterIndentation:
2
+ Enabled: false
3
+ Documentation:
4
+ Enabled: false
5
+ Metrics/MethodLength:
6
+ Enabled: false
7
+
8
+ Metrics/LineLength:
9
+ Exclude:
10
+ - spec/**/*
11
+ AllCops:
12
+ Exclude:
13
+ - _examples/**/*
data/.travis.yml CHANGED
@@ -3,6 +3,7 @@ rvm:
3
3
  - 2.0.0
4
4
  - 2.1.2
5
5
  - 2.2.4
6
+ - 2.3.0
6
7
  notifications:
7
8
  slack:
8
9
  secure: VNIwgvrbcwj0b2gfYSOeTyK7rkV62/belwhYthasHmN+DoTsEJF4+HFVtzOykS72LM/f5Id5zieWtxYG+soy+yEOc1iZizXRpRJORtTYfZJB9RCffavosl322BcpoTX99cGyiZjWjOFH70UWlFMB3zT0jS+9icuTfk7ZqBX/zDA=
data/README.md CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  # SparkPost Ruby API Client
6
6
 
7
- [![Travis CI](https://travis-ci.org/SparkPost/ruby-sparkpost.svg?branch=master)](https://travis-ci.org/SparkPost/ruby-sparkpost) [![Coverage Status](https://coveralls.io/repos/SparkPost/ruby-sparkpost/badge.svg?branch=master&service=github)](https://coveralls.io/github/SparkPost/ruby-sparkpost?branch=master)
7
+ [![Travis CI](https://travis-ci.org/SparkPost/ruby-sparkpost.svg?branch=master)](https://travis-ci.org/SparkPost/ruby-sparkpost) [![Coverage Status](https://coveralls.io/repos/SparkPost/ruby-sparkpost/badge.svg?branch=master&service=github)](https://coveralls.io/github/SparkPost/ruby-sparkpost?branch=master) [![Slack Status](http://slack.sparkpost.com/badge.svg)](http://slack.sparkpost.com)
8
8
 
9
- The official Ruby client library for Sparkpost
9
+ The official Ruby client library for SparkPost
10
10
 
11
11
  ## Installation
12
12
 
@@ -22,9 +22,59 @@ Or install it yourself as:
22
22
 
23
23
  $ gem install sparkpost
24
24
 
25
+ **Important: Implementations may change frequently until we reach v1.0.0**
26
+
25
27
  ## Usage
26
28
 
27
- Check [examples/transmission.rb](examples/transmission.rb)
29
+ **Send an email**
30
+
31
+ ```ruby
32
+ require 'sparkpost'
33
+
34
+ sp = SparkPost::Client.new() # api key was set in ENV through ENV['SPARKPOST_API_KEY']
35
+ response = sp.transmission.send_message('RECIPIENT_EMAIL', 'SENDER_EMAIL', 'test email', '<h1>HTML message</h1>')
36
+ puts response
37
+
38
+ # {"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"123456789123456789"}
39
+ ```
40
+
41
+ **Send email with substitution data**
42
+
43
+ ```ruby
44
+ require 'sparkpost'
45
+
46
+ values = { substitution_data: { name: 'Sparky'}}
47
+ sp = SparkPost::Client.new() # pass api key or get api key from ENV
48
+ response = sp.transmission.send_message('RECIPIENT_EMAIL', 'SENDER_EMAIL', 'testemail', '<h1>HTML message from {{name}}</h1>', values)
49
+ puts response
50
+
51
+ # {"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"123456789123456789"}
52
+ ```
53
+
54
+ **Send email with attachment**
55
+
56
+ *You need to base64 encode of your attachment contents.*
57
+
58
+ ```ruby
59
+ require 'sparkpost'
60
+
61
+ # assuming there is a file named attachment.txt in the same directory
62
+ attachment = Base64.encode64(File.open(File.expand_path('../attachment.txt', __FILE__), 'r') { |f| f.read })
63
+
64
+ # prepare attachment data to pass to send_message method
65
+ values = {
66
+ attachments: [{
67
+ name: 'attachment.txt',
68
+ type: 'text/plain',
69
+ data: attachment
70
+ }]
71
+ }
72
+
73
+ sp = SparkPost::Client.new() # pass api key or get api key from ENV
74
+ sp.transmission.send_message('RECIPIENT_EMAIL', 'SENDER_EMAIL', 'testemail', '<h1>Email with an attachment</h1>', values)
75
+ ```
76
+
77
+ See: [examples](examples)
28
78
 
29
79
  ## Development
30
80
 
data/Rakefile CHANGED
@@ -1,7 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
3
4
 
4
5
  RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
5
7
 
6
- task :default => :spec
7
-
8
+ task default: [:rubocop, :spec]
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "sparkpost"
3
+ require 'bundler/setup'
4
+ require 'sparkpost'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "sparkpost"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../lib/sparkpost'
4
+
5
+ sp = SparkPost::Client.new # api key was set in ENV
6
+ templates = sp.template.list
7
+
8
+ puts templates
@@ -0,0 +1 @@
1
+ This attachment contains just this!
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../lib/sparkpost'
4
+
5
+ sp = SparkPost::Client.new # api key was set in ENV
6
+ response = sp.transmission.send_message(
7
+ 'RECIPIENT_EMAIL',
8
+ 'SENDER_EMAIL',
9
+ 'test email',
10
+ '<h1>HTML message</h1>')
11
+
12
+ puts response
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'base64'
4
+ require_relative '../../lib/sparkpost'
5
+
6
+ # read file and base64 encoding
7
+ attachment = Base64.encode64(
8
+ File.open(File.expand_path('../attachment.txt', __FILE__), 'r', &:read))
9
+
10
+ # prepare attachment data to pass to send_message method
11
+ options = {
12
+ attachments: [{
13
+ name: 'Sparky.txt',
14
+ type: 'text/plain',
15
+ data: attachment
16
+ }]
17
+ }
18
+
19
+ sp = SparkPost::Client.new # pass api key or get api key from ENV
20
+
21
+ # send message with attachment
22
+ response = sp.transmission.send_message(
23
+ 'RECIPIENT_EMAIL',
24
+ 'SENDER_EMAIL',
25
+ 'test email',
26
+ '<h1>Message with attachment</h1>',
27
+ options)
28
+
29
+ puts response
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../lib/sparkpost'
4
+
5
+ values = { substitution_data: { name: 'Sparky' } }
6
+ sp = SparkPost::Client.new # pass api key or get api key from ENV
7
+ response = sp.transmission.send_message(
8
+ 'RECIPIENT_EMAIL',
9
+ 'SENDER_EMAIL',
10
+ 'test email',
11
+ '<h1>HTML message from {{name}}</h1>',
12
+ values)
13
+
14
+ puts response
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../../lib/sparkpost'
4
+
5
+ # prepare the payload as required by SparkPost API endpoint
6
+ payload = {
7
+ recipients: [{ address: { email: 'RECIPIENT_EMAIL' } }],
8
+ content: {
9
+ from: 'SENDER_EMAIL',
10
+ subject: 'test email',
11
+ template_id: 'YOUR_TEMPLATE_ID'
12
+ }
13
+ }
14
+
15
+ sp = SparkPost::Client.new # api key was set in ENV
16
+ response = sp.transmission.send_payload(payload)
17
+
18
+ puts response
data/lib/sparkpost.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  require_relative 'sparkpost/version'
2
2
  require_relative 'sparkpost/transmission'
3
- require_relative 'sparkpost/client'
3
+ require_relative 'sparkpost/client'
4
+ require_relative 'sparkpost/template'
@@ -1,23 +1,26 @@
1
1
  module SparkPost
2
- class Client
3
- attr_reader :transmission
4
-
5
- def initialize(api_key = nil, api_host = 'https://api.sparkpost.com')
6
- @api_key = (api_key || ENV['SPARKPOST_API_KEY']).to_s
7
- @api_host = (api_host || ENV['SPARKPOST_API_HOST']).to_s
2
+ class Client
3
+ attr_reader :transmission
4
+ attr_reader :template
5
+ def initialize(api_key = nil, api_host = 'https://api.sparkpost.com')
6
+ @api_key = (api_key || ENV['SPARKPOST_API_KEY']).to_s
7
+ @api_host = (api_host || ENV['SPARKPOST_API_HOST']).to_s
8
8
 
9
- if @api_key.blank?
10
- fail ArgumentError, 'No API key is provided. Either provide api_key with constructor or set SPARKPOST_API_KEY environment variable'
11
- end
9
+ raise ArgumentError, 'No API key is provided. Either provide
10
+ api_key with constructor or set SPARKPOST_API_KEY environment
11
+ variable' if @api_key.blank?
12
12
 
13
+ raise ArgumentError, 'No API host is provided. Either provide
14
+ api_host with constructor or set SPARKPOST_API_HOST environment
15
+ variable' if @api_host.blank?
16
+ end
13
17
 
14
- if @api_host.blank?
15
- fail ArgumentError, 'No API host is provided. Either provide api_host with constructor or set SPARKPOST_API_HOST environment variable'
16
- end
17
- end
18
+ def transmission
19
+ @transmission ||= Transmission.new(@api_key, @api_host)
20
+ end
18
21
 
19
- def transmission
20
- @transmission ||= Transmission.new(@api_key, @api_host)
21
- end
22
+ def template
23
+ @template ||= Template.new(@api_key, @api_host)
22
24
  end
23
- end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require_relative '../core_extensions/object'
2
+
3
+ module SparkPost
4
+ module Helpers
5
+ def copy_value(src_hash, src_key, dst_hash, dst_key)
6
+ dst_hash[dst_key] = src_hash[src_key] if src_hash.key?(src_key)
7
+ end
8
+
9
+ def deep_merge(source_hash, other_hash)
10
+ source_hash.merge(other_hash) do |_key, oldval, newval|
11
+ if newval.respond_to?(:blank?) && newval.blank?
12
+ oldval
13
+ elsif oldval.is_a?(Hash) && newval.is_a?(Hash)
14
+ deep_merge(oldval, newval)
15
+ else
16
+ newval
17
+ end
18
+ end
19
+ end
20
+
21
+ module_function :copy_value, :deep_merge
22
+ end
23
+ end
@@ -6,31 +6,63 @@ require_relative 'exceptions'
6
6
 
7
7
  module SparkPost
8
8
  module Request
9
-
10
- def request(url, api_key, data)
9
+ def request(url, api_key, data, verb = 'POST')
11
10
  uri = URI.parse(url)
12
- http = Net::HTTP.new(uri.host, uri.port)
13
- http.use_ssl = true
11
+ http = configure_http(uri)
14
12
  headers = {
15
- 'User-Agent' => 'ruby-sparkpost/' + VERSION,
16
- 'Content-Type' => 'application/json',
17
- 'Authorization' => api_key
13
+ 'User-Agent' => 'ruby-sparkpost/' + VERSION,
14
+ 'Content-Type' => 'application/json',
15
+ 'Authorization' => api_key
18
16
  }
19
- req = Net::HTTP::Post.new(uri.path, initheader=headers)
20
- req.body = data.to_json
17
+ req = configure_request(uri, headers, data, verb)
18
+ process_response(http.request(req))
19
+ end
20
+
21
+ def endpoint(subpath = nil, params = {})
22
+ url = String.new(@base_endpoint)
23
+ if subpath
24
+ url << '/' unless subpath.start_with?('/')
25
+ url << subpath
26
+ end
27
+ if params && params.any?
28
+ url << '?'
29
+ url << params.to_a.map { |x| "#{x[0]}=#{x[1]}" }.join('&')
30
+ end
31
+ url
32
+ end
21
33
 
22
- process_response(http.request(req));
34
+ def configure_http(uri)
35
+ http = Net::HTTP.new(uri.host, uri.port)
36
+ http.use_ssl = true
37
+ http
38
+ end
39
+
40
+ def configure_request(uri, headers, data, verb)
41
+ req = case verb
42
+ when 'GET'
43
+ Net::HTTP::Get.new(uri.path, headers)
44
+ when 'PUT'
45
+ Net::HTTP::Put.new(uri.path, headers)
46
+ when 'DELETE'
47
+ Net::HTTP::Delete.new(uri.path, headers)
48
+ else
49
+ Net::HTTP::Post.new(uri.path, headers)
50
+ end
51
+
52
+ req.body = JSON.generate(data) if data.present?
53
+ req
23
54
  end
24
55
 
25
56
  def process_response(response)
26
57
  response = JSON.parse(response.body)
27
58
  if response['errors']
28
- fail SparkPost::DeliveryException, response['errors']
59
+ raise SparkPost::DeliveryException, response['errors']
29
60
  else
30
61
  response['results']
31
62
  end
32
- end
63
+ end
33
64
 
34
- module_function :request, :process_response
65
+ module_function :request, :configure_http, :configure_request,
66
+ :process_response
35
67
  end
36
68
  end
@@ -0,0 +1,112 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require_relative 'request'
4
+ require_relative 'helpers'
5
+ require_relative 'exceptions'
6
+
7
+ module SparkPost
8
+ class Template
9
+ include Request
10
+ include Helpers
11
+
12
+ def initialize(api_key, api_host)
13
+ @api_key = api_key
14
+ @api_host = api_host
15
+ @base_endpoint = "#{@api_host}/api/v1/templates"
16
+ end
17
+
18
+ def create(id, from = nil, subject = nil, html = nil, **options)
19
+ data = deep_merge(
20
+ payload_from_args(id, from, subject, html),
21
+ payload_from_options(options)
22
+ )
23
+ request(endpoint, @api_key, data, 'POST')
24
+ end
25
+
26
+ def update(id, from = nil, subject = nil, html = nil, **options)
27
+ params = {}
28
+ copy_value(options, :update_published, params, :update_published)
29
+ data = deep_merge(
30
+ payload_from_args(nil, from, subject, html),
31
+ payload_from_options(options)
32
+ )
33
+ request(endpoint(id, params), @api_key, data, 'PUT')
34
+ end
35
+
36
+ def delete(id)
37
+ request(endpoint(id), @api_key, nil, 'DELETE')
38
+ end
39
+
40
+ def get(id, draft = nil)
41
+ params = {}
42
+ params[:draft] = draft unless draft.nil?
43
+ request(endpoint(id, params), @api_key, nil, 'GET')
44
+ end
45
+
46
+ def list
47
+ request(endpoint, @api_key, nil, 'GET')
48
+ end
49
+
50
+ def preview(id, substitution_data, draft = nil)
51
+ params = {}
52
+ params[:draft] = draft unless draft.nil?
53
+ request(
54
+ endpoint("#{id}/preview", params),
55
+ @api_key,
56
+ { substitution_data: substitution_data },
57
+ 'POST'
58
+ )
59
+ end
60
+
61
+ private
62
+
63
+ def payload_from_args(id, from, subject, html)
64
+ model = { content: {}, options: {} }
65
+
66
+ model[:id] = id unless id.nil?
67
+ model[:content][:from] = from unless from.nil?
68
+ model[:content][:subject] = subject unless subject.nil?
69
+ model[:content][:html] = html unless html.nil?
70
+
71
+ model
72
+ end
73
+
74
+ def payload_from_options(**options)
75
+ model = { content: { from: {} }, options: {} }
76
+
77
+ # Mapping optional arguments to root
78
+ [
79
+ [:name, :name],
80
+ [:id, :id],
81
+ [:description, :description],
82
+ [:published, :published]
83
+ ].each { |skey, dkey| copy_value(options, skey, model, dkey) }
84
+
85
+ # Mapping optional arguments to options
86
+ [
87
+ [:track_opens, :open_tracking],
88
+ [:track_clicks, :click_tracking],
89
+ [:is_transactional, :transactional]
90
+ ].each { |skey, dkey| copy_value(options, skey, model[:options], dkey) }
91
+
92
+ # Mapping optional arguments to content
93
+ [
94
+ [:html, :html],
95
+ [:text, :text],
96
+ [:subject, :subject],
97
+ [:reply_to, :reply_to],
98
+ [:custom_headers, :headers]
99
+ ].each { |skey, dkey| copy_value(options, skey, model[:content], dkey) }
100
+
101
+ # Mapping optional arguments to sender information
102
+ [
103
+ [:from_email, :email],
104
+ [:from_name, :name]
105
+ ].each do |skey, dkey|
106
+ copy_value(options, skey, model[:content][:from], dkey)
107
+ end
108
+
109
+ model
110
+ end
111
+ end
112
+ end