simple_spark 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ module SimpleSpark
2
+ module Endpoints
3
+ # Provides access to the /message-events endpoint
4
+ # @note See: https://developers.sparkpost.com/api/#/reference/message-events
5
+ class MessageEvents
6
+ attr_accessor :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ # Returns sample message_events
13
+ # @param events [String] Event types for which to get a sample payload, use the Webhooks Events endpoint to list the
14
+ # available event types, defaults to all event types
15
+ # @return [Array] a list of sample MessageEvent hash objects
16
+ # @note See: https://developers.sparkpost.com/api/#/reference/message-events/events-samples
17
+ def samples(events = nil)
18
+ query_params = events.nil? ? {} : { events: events }
19
+ @client.call(:get, 'message-events/events/samples', {}, query_params)
20
+ end
21
+
22
+ # Perform a filtered search for message event data. The response is sorted by descending timestamp.
23
+ # @param params [String] Params to use in the search
24
+ # @return [Array] a list of MessageEvent hash objects
25
+ # @note See: https://developers.sparkpost.com/api/#/reference/message-events/search-for-message-events
26
+ def search(params = {})
27
+ @client.call(:get, 'message-events', {}, params)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,74 @@
1
+ module SimpleSpark
2
+ module Endpoints
3
+ # Provides access to the /sending-domains endpoint
4
+ # @note Example sending domain
5
+ # { "domain": "example1.com", "tracking_domain": "click.example1.com",
6
+ # "status": { "ownership_verified": true, "spf_status": "valid", "abuse_at_status": "valid",
7
+ # "abuse_at_status": "valid", "dkim_status": "valid", "compliance_status": "valid", "postmaster_at_status": "valid" } }
8
+ # @note See: https://developers.sparkpost.com/api/#/reference/sending-domains
9
+ class SendingDomains
10
+ attr_accessor :client
11
+
12
+ def initialize(client)
13
+ @client = client
14
+ end
15
+
16
+ # Lists your sending domains
17
+ # @return [Array] a list of Sending Domain hash objects
18
+ # @note See: https://developers.sparkpost.com/api/#/reference/sending-domains/create-and-list/list-all-sending-domains
19
+ def list
20
+ @client.call(:get, 'sending-domains')
21
+ end
22
+
23
+ # Create a sending domain
24
+ # @param domain_name [String] the domain name to create
25
+ # @param tracking_domain [String] the domain name to track this domain against
26
+ # @note See: https://developers.sparkpost.com/api/#/reference/sending-domains/create-and-list
27
+ def create(domain_name, tracking_domain)
28
+ @client.call(:post, 'sending-domains', domain: domain_name, tracking_domain: tracking_domain)
29
+ end
30
+
31
+ # Retrieve a sending domain
32
+ # @param domain_name [String] the domain name to retrieve
33
+ # @return [Hash] an Sending Domain hash object
34
+ # @note See: https://developers.sparkpost.com/api/#/reference/sending-domains/retrieve-update-and-delete
35
+ def retrieve(domain_name)
36
+ domain_name = @client.url_encode(domain_name)
37
+ @client.call(:get, "sending-domains/#{domain_name}")
38
+ end
39
+
40
+ # Update a Sending Domain by its domain name
41
+ # @param domain_name [String] the domain to update
42
+ # @param values [Hash] the values to update the sending domain with
43
+ #
44
+ # @note See: https://developers.sparkpost.com/api/#/reference/sending-domains/retrieve-update-and-delete
45
+ def update(domain_name, values)
46
+ domain_name = @client.url_encode(domain_name)
47
+ @client.call(:put, "sending-domains/#{domain_name}", values)
48
+ end
49
+
50
+ # Verify a Sending Domain by its domain name
51
+ # @param domain_name [String] the domain to verify
52
+ # @param values [Hash] the values specifying how to verify the domain
53
+ # Including the fields "dkim_verify" and/or "spf_verify" in the request initiates a check against the associated DNS record
54
+ # type for the specified sending domain.Including the fields "postmaster_at_verify" and/or "abuse_at_verify" in the request
55
+ # results in an email sent to the specified sending domain's postmaster@ and/or abuse@ mailbox where a verification link can
56
+ # be clicked.Including the fields "postmaster_at_token" and/or "abuse_at_token" in the request initiates a check of the provided
57
+ # token(s) against the stored token(s) for the specified sending domain.
58
+ #
59
+ # @note See: https://developers.sparkpost.com/api/#/reference/sending-domains/verify
60
+ def verify(domain_name, values)
61
+ domain_name = @client.url_encode(domain_name)
62
+ @client.call(:post, "sending-domains/#{domain_name}", values)
63
+ end
64
+
65
+ # Delete a sending domain
66
+ # @param domain_name [String] the domain name to delete
67
+ # @note See: https://developers.sparkpost.com/api/#/reference/sending-domains/retrieve-update-and-delete
68
+ def delete(domain_name)
69
+ domain_name = @client.url_encode(domain_name)
70
+ @client.call(:delete, "sending-domains/#{domain_name}")
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,80 @@
1
+ module SimpleSpark
2
+ module Endpoints
3
+ # Provides access to the /templates endpoint
4
+ # @note See: https://developers.sparkpost.com/api/#/reference/templates
5
+ # @note Sample Template
6
+ # { "id"=>"102293692714480130", "name"=>"Summer Sale!", "description"=>"", "published"=>false, "options"=>{},
7
+ # "last_update_time"=>"2016-03-02T22:49:23+00:00",
8
+ # "content"=>{"from"=>"marketing@neekme.com", "subject"=>"Summer deals", "html"=>"<b>Check out these deals!</b>"} }
9
+ class Templates
10
+ attr_accessor :client
11
+
12
+ def initialize(client)
13
+ @client = client
14
+ end
15
+
16
+ # Lists the most recent version of each template in your account.
17
+ # @return [Array] a list of Template hash objects
18
+ # @note See: https://developers.sparkpost.com/api/#/reference/templates/create-and-list
19
+ def list
20
+ @client.call(:get, 'templates')
21
+ end
22
+
23
+ # Create a template by providing values for the template object.
24
+ # @param values [Hash] containing the properties. At a minimum, the "name" and "content"
25
+ # fields are required, where content must contain the "from", "subject", and at
26
+ # least one of "html" or "text" fields.
27
+ # @return [boolean] true if success
28
+ # @note See: https://developers.sparkpost.com/api/#/reference/templates/create-and-list
29
+ def create(values)
30
+ @client.call(:post, 'templates', values)
31
+ end
32
+
33
+ # Retrieve a Template by its ID
34
+ # @param id [String] the Unique Template ID to retrieve
35
+ # @param draft [boolean] If true, returns the most recent draft template.
36
+ # If false, returns the most recent published template.
37
+ # If not provided, returns the most recent template version regardless of draft or published.
38
+ # @return [Hash] the Template object
39
+ # @note https://developers.sparkpost.com/api/#/reference/templates/retrieve
40
+ def retrieve(id, draft = nil)
41
+ path = "templates/#{id}"
42
+ query_params = draft.nil? ? {} : { draft: draft }
43
+ @client.call(:get, path, {}, query_params)
44
+ end
45
+
46
+ # Update a Template by its ID
47
+ # @param id [String] the Unique Template ID to update
48
+ # @param values [Hash] the values to update the template with
49
+ # @param update_published [boolean] If true, directly overwrite the existing published template. If false, create a new draft.
50
+ # If this template isn't yet published, setting to 'true' will result in a NotFound error
51
+ #
52
+ # @note See: https://developers.sparkpost.com/api/#/reference/templates/update
53
+ def update(id, values, update_published = false)
54
+ @client.call(:put, "templates/#{id}", values, update_published: update_published)
55
+ end
56
+
57
+ # Preview a Template by its ID
58
+ # @param id [String] the Unique Template ID to preview
59
+ # @param substitutions [Hash] the values to update the template with. Must contain a key 'substitution_data'
60
+ # { "substitution_data" => { "name" => "Natalie", "age" => 35, "member" => true }
61
+ # @param draft [boolean] If true, returns the most recent draft template.
62
+ # If false, returns the most recent published template.
63
+ # If not provided, returns the most recent template version regardless of draft or published.
64
+ #
65
+ # @note See: https://developers.sparkpost.com/api/#/reference/templates/preview
66
+ def preview(id, substitutions, draft = nil)
67
+ query_params = draft.nil? ? {} : { draft: draft }
68
+ @client.call(:post, "templates/#{id}/preview", substitutions, query_params)
69
+ end
70
+
71
+ # Delete a Template by its ID
72
+ # @param id [String] the Unique Template ID to delete
73
+ #
74
+ # @note See: https://developers.sparkpost.com/api/#/reference/templates/delete
75
+ def delete(id)
76
+ @client.call(:delete, "templates/#{id}")
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,60 @@
1
+ module SimpleSpark
2
+ module Endpoints
3
+ # Provides access to the /transmissions endpoint
4
+ # See: https://developers.sparkpost.com/api/#/reference/transmissions
5
+ class Transmissions
6
+ attr_accessor :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ # Sends an email message
13
+ # @param values [Hash] the values to send with. This can be a complex object depending on the options chosen.
14
+ # @param num_rcpt_errors [Integer] limit the number of recipient errors returned. Will default to all
15
+ # @returns { results: { total_rejected_recipients: 0, total_accepted_recipients: 1, id: "11668787484950529" } }
16
+ # @note See: https://developers.sparkpost.com/api/#/reference/transmissions/create
17
+ # @note Example:
18
+ # properties = {
19
+ # options: { open_tracking: true, click_tracking: true },
20
+ # campaign_id: 'christmas_campaign',
21
+ # return_path: 'bounces-christmas-campaign@sp.neekme.com',
22
+ # metadata: {user_type: 'students'},
23
+ # substitution_data: { sender: 'Big Store Team' },
24
+ # recipients: [
25
+ # { address: { email: 'yourcustomer@theirdomain.com', name: 'Your Customer' },
26
+ # tags: ['greeting', 'sales'],
27
+ # metadata: { place: 'Earth' }, substitution_data: { address: '123 Their Road' } }
28
+ # ],
29
+ # content:
30
+ # { from: { name: 'Your Name', email: 'you@yourdomain.com' },
31
+ # subject: 'I am a test email',
32
+ # reply_to: 'Sales <sales@yourdomain.com>',
33
+ # headers: { 'X-Customer-CampaignID' => 'christmas_campaign' },
34
+ # text: 'Hi from {{sender}} ... this is a test, and here is your address {{address}}',
35
+ # html: '<p>Hi from {{sender}}</p<p>This is a test</p>'
36
+ # }
37
+ # }
38
+ def create(values, num_rcpt_errors = nil)
39
+ query_params = num_rcpt_errors.nil? ? {} : { num_rcpt_errors: num_rcpt_errors }
40
+ @client.call(:post, 'transmissions', values, query_params)
41
+ end
42
+
43
+ # Sends an email message
44
+ # @param campaign_id [String] limit results to this Campaign ID
45
+ # @param template_id [String] limit results to this Template ID
46
+ # @returns [ { "content": { "template_id": "winter_sale" }, "id": "11713562166689858",
47
+ # "campaign_id": "thanksgiving", "description": "", "state": "submitted" } ]
48
+ # @note See: https://developers.sparkpost.com/api/#/reference/transmissions/list
49
+ def list(campaign_id = nil, template_id = nil)
50
+ query_params = {}
51
+ query_params[:campaign_id] = campaign_id if campaign_id
52
+ query_params[:template_id] = template_id if template_id
53
+ @client.call(:get, 'transmissions', {}, query_params)
54
+ end
55
+
56
+ # send_message to be reserved as a 'quick' helper method to avoid using hash for Create
57
+ # alias_method :send_message, :create
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,77 @@
1
+ module SimpleSpark
2
+ module Endpoints
3
+ # Provides access to the /webhooks endpoint
4
+ # @note Example webhook
5
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks
6
+ class Webhooks
7
+ attr_accessor :client
8
+
9
+ def initialize(client)
10
+ @client = client
11
+ end
12
+
13
+ # List currently extant webhooks
14
+ # @return [Array] a list of Webhook hash objects
15
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/list
16
+ def list(timezone = nil)
17
+ query_params = timezone.nil? ? {} : { timezone: timezone }
18
+ @client.call(:get, 'webhooks', {}, query_params)
19
+ end
20
+
21
+ # Create a webhook
22
+ # @param values [Hash] the values to create the webhook with
23
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/create
24
+ def create(values)
25
+ @client.call(:post, 'webhooks', values)
26
+ end
27
+
28
+ # Retrieve details about a webhook by specifying its id
29
+ # @param id [String] the ID of the webhook
30
+ # @return [Hash] an Webhook hash object
31
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/retrieve
32
+ def retrieve(id)
33
+ @client.call(:get, "webhooks/#{id}")
34
+ end
35
+
36
+ # Update a Webhook by its ID
37
+ # @param id [String] the ID of the webhook
38
+ # @param values [Hash] the values to update the webhook with
39
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/update-and-delete
40
+ def update(id, values)
41
+ @client.call(:put, "webhooks/#{id}", values)
42
+ end
43
+
44
+ # Validates a Webhook by sending an example message event batch from the Webhooks API to the target URL
45
+ # @param id [String] the ID of the webhook
46
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/validate
47
+ def validate(id)
48
+ @client.call(:post, "webhooks/#{id}/validate")
49
+ end
50
+
51
+ # Batch status information
52
+ # @param id [String] the ID of the webhook
53
+ # @return [Array] a list of status hash objects
54
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/batch-status
55
+ def batch_status(id, limit = nil)
56
+ query_params = limit.nil? ? {} : { limit: limit }
57
+ @client.call(:get, "webhooks/#{id}/batch-status", {}, query_params)
58
+ end
59
+
60
+ # Returns sample event data
61
+ # @param events [String] Event types for which to get a sample payload
62
+ # @return [Array] a list of sample event hash objects
63
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/events-samples
64
+ def samples(events = nil)
65
+ query_params = events.nil? ? {} : { events: events }
66
+ @client.call(:get, 'webhooks/events/samples', {}, query_params)
67
+ end
68
+
69
+ # Delete a webhook
70
+ # @param id [String] the ID
71
+ # @note See: https://developers.sparkpost.com/api/#/reference/webhooks/update-and-delete
72
+ def delete(id)
73
+ @client.call(:delete, "webhooks/#{id}")
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,39 @@
1
+ module SimpleSpark
2
+ module Exceptions
3
+ # Adding an object to the exception to pass errors back
4
+ # begin
5
+ # raise Error.new({ id: '1' }), "a message"
6
+ # rescue Error => e
7
+ # puts e.message # => "a message"
8
+ # puts e.object # => { id: '1' }
9
+ # end
10
+ class Error < StandardError
11
+ attr_reader :object
12
+
13
+ def initialize(object = nil)
14
+ @object = object
15
+ end
16
+
17
+ def self.fail_with_exception_for_status(status, errors)
18
+ exception = status_codes[status.to_s] || status_codes['default']
19
+ fail exception.new(errors), errors.map { |e| "#{e['message']}" + (e['description'] ? ": #{e['description']}" : '') }.join(', ')
20
+ end
21
+
22
+ def self.status_codes
23
+ {
24
+ 'default' => Exceptions::UnprocessableEntity,
25
+ '400' => Exceptions::BadRequest,
26
+ '404' => Exceptions::NotFound,
27
+ '422' => Exceptions::UnprocessableEntity,
28
+ '420' => Exceptions::ThrottleLimitExceeded
29
+ }
30
+ end
31
+ end
32
+
33
+ class InvalidConfiguration < Error; end
34
+ class BadRequest < Error; end
35
+ class NotFound < Error; end
36
+ class UnprocessableEntity < Error; end
37
+ class ThrottleLimitExceeded < Error; end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module SimpleSpark
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'simple_spark/version'
2
+ require 'simple_spark/client'
3
+ require 'simple_spark/exceptions'
4
+ require 'simple_spark/endpoints/transmissions'
5
+ require 'simple_spark/endpoints/templates'
6
+ require 'simple_spark/endpoints/inbound_domains'
7
+ require 'simple_spark/endpoints/sending_domains'
8
+ require 'simple_spark/endpoints/message_events'
9
+ require 'simple_spark/endpoints/webhooks'
10
+
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'simple_spark/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'simple_spark'
8
+ spec.version = SimpleSpark::VERSION
9
+ spec.authors = ['Jak Charlton']
10
+ spec.email = ['jakcharlton@gmail.com']
11
+ spec.summary = 'A library for accessing the SparkPost REST API http://www.sparkpost.com'
12
+ spec.description = 'An alternative to the official SparkPost Ruby gem'
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.6'
22
+ spec.add_development_dependency 'rake', '~> 0.9.6'
23
+
24
+ spec.add_development_dependency 'rspec', '~> 3.4.0'
25
+ spec.add_development_dependency 'rspec-nc', '~> 0'
26
+ spec.add_development_dependency 'guard', '~> 2.13'
27
+ spec.add_development_dependency 'guard-rspec', '~> 4.6.4'
28
+ spec.add_development_dependency 'pry', '~> 0'
29
+ spec.add_development_dependency 'pry-remote', '~> 0'
30
+ spec.add_development_dependency 'pry-nav', '~> 0'
31
+ spec.add_development_dependency 'climate_control', '~> 0'
32
+
33
+ spec.add_dependency 'json', '>= 1.7.7', '< 2.0'
34
+ spec.add_dependency 'excon', '>= 0.16.0', '< 1.0'
35
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleSpark::Client do
4
+ describe :initialize do
5
+ it 'will raise when no API key provided' do
6
+ expect { SimpleSpark::Client.new }.to raise_error(SimpleSpark::Exceptions::InvalidConfiguration, 'You must provide a SparkPost API key')
7
+ end
8
+
9
+ context 'defaults' do
10
+ let(:client) { SimpleSpark::Client.new('mykey') }
11
+ specify { expect(client.instance_variable_get(:@api_key)).to eq('mykey') }
12
+ specify { expect(client.instance_variable_get(:@api_host)).to eq('https://api.sparkpost.com') }
13
+ specify { expect(client.instance_variable_get(:@base_path)).to eq('/api/v1/') }
14
+ specify { expect(client.instance_variable_get(:@session).class).to eq(Excon::Connection) }
15
+ specify { expect(client.instance_variable_get(:@debug)).to eq(false) }
16
+ end
17
+
18
+ it 'will use the API key from the ENV var' do
19
+ with_modified_env SPARKPOST_API_KEY: 'mykey' do
20
+ expect(SimpleSpark::Client.new.instance_variable_get(:@api_key)).to eq('mykey')
21
+ end
22
+ end
23
+
24
+ it 'will use the base_path provided' do
25
+ expect(SimpleSpark::Client.new('mykey', nil, 'base').instance_variable_get(:@base_path)).to eq('base')
26
+ end
27
+
28
+ it 'will use the debug option provided' do
29
+ expect(SimpleSpark::Client.new('mykey', nil, nil, true).instance_variable_get(:@debug)).to eq(true)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,7 @@
1
+ require 'pry'
2
+ require 'simple_spark'
3
+ require 'climate_control'
4
+
5
+ def with_modified_env(options, &block)
6
+ ClimateControl.modify(options, &block)
7
+ end