knowtify 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e7fd8df5495b4a47cb7d73d672be7283ae7e30a6
4
+ data.tar.gz: 3af370340767f44fc7bb7b96df97dff3b023321f
5
+ SHA512:
6
+ metadata.gz: 9a8393daac5214815e6c4e79071eb2764adb9f46f064d62807cba9598818821648dfb61e76554349c53bac6ba29afad02617fbc9f3ca78c3498fb5f5beefb560
7
+ data.tar.gz: 08cb1455787f0799e1d6347355b290b6d74370235e78aa1f1638e495bb13f78ab85142ea420b1ede1ae947d6ef3110d3c1f1590de6f37fad2034ad9ce6a0eee2
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in knowtify.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Joshua Mckinney
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,55 @@
1
+ # Knowtify
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'knowtify'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install knowtify
20
+
21
+ ## Usage
22
+
23
+ require 'knowtify'
24
+
25
+ ENV['KNOWTIFY_API_TOKEN'] = 'MySuperSecretKey'
26
+
27
+ new_contacts = [{
28
+ "name" => "John",
29
+ "email" => "john@test.com",
30
+ "data" => {
31
+ "category" => "sports",
32
+ "followers" => 300
33
+ }
34
+ },
35
+ {
36
+ "name" => "Samuel",
37
+ "email" => "sam@test.com",
38
+ "data" => {
39
+ "category" => "sports",
40
+ "followers" => 32,
41
+ "comments" => 54,
42
+ "role" => "Editor"
43
+ }
44
+ }]
45
+ client = Knowtify::Client.new
46
+ resp = client.contacts_upsert(new_contacts) # <Knowtify::Response:0x007fdb629e5c10>
47
+ resp.successful? # true
48
+
49
+ ## Contributing
50
+
51
+ 1. Fork it ( https://github.com/[my-github-username]/knowtify/fork )
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'knowtify/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "knowtify"
8
+ spec.version = Knowtify::VERSION
9
+ spec.authors = ["Joshua Mckinney","Dane Lyons"]
10
+ spec.email = ["joshmckin@gmail.com","dane@knowtify.io"]
11
+ spec.summary = "Smart emails to engage your users"
12
+ spec.description = "Knowtify helps you design and deliver transactional, behavioral and digest emails to engage your users."
13
+ spec.homepage = "http://www.knowtify.io"
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_runtime_dependency "excon"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "rspec-autotest"
27
+ spec.add_development_dependency "autotest"
28
+ end
@@ -0,0 +1,16 @@
1
+ require "knowtify/version"
2
+ require "knowtify/handlers/excon_handler"
3
+ require "knowtify/config"
4
+ require "knowtify/client"
5
+ require "knowtify/request"
6
+ require "knowtify/response"
7
+
8
+
9
+ module Knowtify
10
+ # Your code goes here...
11
+ class << self
12
+ def config
13
+ @config ||= Knowtify::Config.new
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,115 @@
1
+ module Knowtify
2
+ class Client
3
+ attr_accessor :handler
4
+
5
+ # TODO: Refactor to separate classes for each method
6
+ def initialize
7
+ @handler = config.handler.new
8
+ end
9
+
10
+ # POST /contacts/upsert
11
+ # Sends a request to create or update
12
+ # contacts with the supplied data.
13
+ # Example contacts:
14
+ # [
15
+ # {
16
+ # "name":"John",
17
+ # "email":"john@test.com",
18
+ # "data":{
19
+ # "category":"sports",
20
+ # "followers":300
21
+ # }
22
+ # },
23
+ # {
24
+ # "name":"Samuel",
25
+ # "email":"sam@test.com",
26
+ # "data":{
27
+ # "category":"sports",
28
+ # "followers":32,
29
+ # "comments":54,
30
+ # "role":"Editor"
31
+ # }
32
+ # }
33
+ # ]
34
+ def contacts_upsert(contacts=[],request_options={},api_key=nil)
35
+ options = {
36
+ :path => "#{config.base_path}/contacts/upsert",
37
+ :params => {:contacts => contacts},
38
+ :request_options => request_options,
39
+ :api_key => api_key
40
+ }
41
+ request = Knowtify::Request.new(options)
42
+ handler.post(request)
43
+ end
44
+
45
+ # POST /contacts/delete
46
+ # Sends a request to delete contacts whose
47
+ # emails match those provided.
48
+ # Example contacts:
49
+ # [
50
+ # "john@test.com",
51
+ # "sam@test.com",
52
+ # "sarah@test.com",
53
+ # "mike@test.com",
54
+ # "jill@test.com",
55
+ # "ashley@test.com",
56
+ # "frank@test.com",
57
+ # "bill@test.com"
58
+ # ]
59
+ def contacts_delete(contacts=[],http_request_options={},api_key=nil)
60
+ options = {
61
+ :path => "#{config.base_path}/contacts/delete",
62
+ :params => {:contacts => contacts},
63
+ :http_request_options => http_request_options,
64
+ :api_key => api_key
65
+ }
66
+ request = Knowtify::Request.new(options)
67
+ handler.post(request)
68
+ end
69
+
70
+ # POST /data/edit
71
+ # Updates global data based on the data provided
72
+ # Example data:
73
+ # {
74
+ # "users":890,
75
+ # "comments":994,
76
+ # "top_story_url":"test.com/story",
77
+ # "top_story_title":"Article!"
78
+ # }
79
+ def global_edit(data={},http_request_options={},api_key=nil)
80
+ options = {
81
+ :path => "#{config.base_path}/data/edit",
82
+ :params => {:data => data},
83
+ :http_request_options => http_request_options,
84
+ :api_key => api_key
85
+ }
86
+ request = Knowtify::Request.new(options)
87
+ handler.post(request)
88
+ end
89
+
90
+ # POST contacts/upsert
91
+ # Sends a transaction email with the event and contacts provided
92
+ # {
93
+ # "event":"purchase",
94
+ # "contacts": [
95
+ # {
96
+ # "email":"dane@knowtify.io"
97
+ # }
98
+ # ]
99
+ # }
100
+ def transactional_email(event, contacts=[],http_request_options={},api_key=nil)
101
+ options = {
102
+ :path => "#{config.base_path}/data/edit",
103
+ :params => {:data => contacts},
104
+ :http_request_options => http_request_options,
105
+ :api_key => api_key
106
+ }
107
+ request = Knowtify::Request.new(options)
108
+ handler.post(request)
109
+ end
110
+
111
+ def config
112
+ Knowtify.config
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,39 @@
1
+ module Knowtify
2
+ class Config
3
+ attr_accessor :api_key, # String - API key to override ENV['KNOWTIFY_API_TOKEN']
4
+ :base_url, # String - Base url to build requests from
5
+ :api_version, # String - API version uses for requests
6
+ :max_retries, # FixNum - number of times to retry requests
7
+ :http_client_options, # Hash - Additional options to pass to the HTTP client
8
+ :debug, # Boolean - Default is false
9
+ :handler # Symbol - Default is :excon
10
+
11
+
12
+ HANDLERS = {
13
+ :excon => Knowtify::ExconHandler
14
+ }.freeze
15
+
16
+ def initialize
17
+ @api_key = ENV['KNOWTIFY_API_TOKEN']
18
+ @base_url = "http://www.knowtify.io"
19
+ @api_version = "v1"
20
+ @http_client_options = {}
21
+ @max_retries = 2
22
+ @debug = false
23
+ @handler = :excon
24
+ end
25
+
26
+ def base_path
27
+ "/api/#{@api_version}"
28
+ end
29
+
30
+ def debug?
31
+ @debug == true
32
+ end
33
+
34
+ # Until there are more handler options just return Excon
35
+ def handler
36
+ HANDLERS[@handler]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ require 'excon'
2
+ require 'json'
3
+ module Knowtify
4
+ class ExconHandler
5
+ attr_accessor :http_client
6
+
7
+ def initialize
8
+ opts = {
9
+ :idempotent => true,
10
+ :retry_limit => config.max_retries
11
+ }.merge(config.http_client_options)
12
+ opts[:instrumentor] = Excon::StandardInstrumentor if config.debug? # output full request data if debugging
13
+ @http_client = Excon.new(config.base_url,opts)
14
+ end
15
+
16
+ def request_options(request)
17
+ {:path => request.path,
18
+ :body => request.params.to_json,
19
+ :headers => request.headers}.merge(request.http_request_options)
20
+ end
21
+
22
+ def post(request,count=0)
23
+ resp = Knowtify::Response.new(count)
24
+ resp.raw_response = http_client.post(request_options(request))
25
+ resp.body = resp.raw_response.body
26
+ resp.http_code = resp.raw_response.status
27
+ if resp.retry?
28
+ post(request,count + 1)
29
+ else
30
+ resp
31
+ end
32
+ end
33
+
34
+ def config
35
+ Knowtify.config
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ module Knowtify
2
+ # A generic request object to be passed to handlers
3
+ class Request
4
+ attr_accessor :api_key, # API key for request; defaults to config.api_key
5
+ :path, # Path for HTTP HTTP request
6
+ :params, # Parameters for HTTP request
7
+ :http_request_options # Additional options pass to HTTP client during the request action
8
+
9
+ def initialize(options={})
10
+ @api_key = options[:api_key] || config.api_key
11
+ @path = options[:path]
12
+ @params = options[:params]
13
+ @http_request_options = options[:http_request_options] || {}
14
+ end
15
+
16
+ def headers
17
+ {"Content-Type" => "application/json",
18
+ 'Authorization' => "Token token=\"#{api_key}\""}
19
+ end
20
+
21
+ def config
22
+ Knowtify.config
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ module Knowtify
2
+ class Response
3
+ attr_accessor :body, :http_code, :raw_response, :count
4
+
5
+ ERROR_HTTP_CODES = [500,501,502,503,504,505,429,0]
6
+
7
+ def initialize(count=0)
8
+ @count = count || 0
9
+ end
10
+
11
+ def retry?
12
+ (((count + 1) <= Knowtify.config.max_retries) && ERROR_HTTP_CODES.include?(http_code))
13
+ end
14
+
15
+ def retried?
16
+ count != 0
17
+ end
18
+
19
+ def successful?
20
+ http_code == 200
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Knowtify
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,58 @@
1
+ require 'spec_helper'
2
+
3
+ describe Knowtify::Client do
4
+
5
+ let(:client) {Knowtify::Client.new}
6
+
7
+ it { expect(client.handler).to be_a(Knowtify::ExconHandler) }
8
+
9
+ context "integration tests" do
10
+ # tests assume ENV['KNOWTIFY_API_TOKEN'] is valid
11
+ describe '#contacts_upsert' do
12
+
13
+ it "should work" do
14
+ resp = client.contacts_upsert([{
15
+ "name" => "John",
16
+ "email" => "john@test.com",
17
+ "data" => {
18
+ "category" => "sports",
19
+ "followers" => 300
20
+ }
21
+ },
22
+ {
23
+ "name" => "Samuel",
24
+ "email" => "sam@test.com",
25
+ "data" => {
26
+ "category" => "sports",
27
+ "followers" => 32,
28
+ "comments" => 54,
29
+ "role" => "Editor"
30
+ }
31
+ }])
32
+ expect(resp.body).to eql("{\"status\":\"received\",\"contacts\":2,\"successes\":2,\"errors\":0}")
33
+ end
34
+
35
+ end
36
+
37
+ describe '#contacts_delete' do
38
+
39
+ it "should work" do
40
+ resp = client.contacts_delete(["john@test.com",
41
+ "sam@test.com"
42
+ ])
43
+ expect(resp.body).to eql("{\"status\":\"received\",\"contacts\":2,\"successes\":2,\"errors\":0}")
44
+ end
45
+
46
+ end
47
+
48
+ describe '#global_edit' do
49
+
50
+ it "should work" do
51
+ resp = client.global_edit({"users"=>890, "comments"=>994, "top_story_url"=>"test.com/story", "top_story_title"=>"Article!"})
52
+ expect(resp.body).to eql("{\"status\":\"received\",\"success\":true}")
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+ describe Knowtify::Config do
3
+
4
+ describe '#api_key' do
5
+
6
+ context "default to ENV['KNOWTIFY_API_TOKEN']" do
7
+
8
+ it "should work" do
9
+ ENV['KNOWTIFY_API_TOKEN'] ||= "TEST API KEY"
10
+ config = Knowtify::Config.new
11
+ expect(config.api_key).to eql(ENV['KNOWTIFY_API_TOKEN'])
12
+ end
13
+
14
+ end
15
+
16
+ end
17
+
18
+ describe '#handler' do
19
+
20
+ it {expect(Knowtify::Config.new.handler).to eql(Knowtify::ExconHandler)}
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Knowtify do
4
+ describe '#config' do
5
+ it { expect(Knowtify.config).to be_a(Knowtify::Config) }
6
+ end
7
+ end
@@ -0,0 +1,93 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'rspec/autotest'
4
+ require 'knowtify'
5
+ # This file was generated by the `rspec --init` command. Conventionally, all
6
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
7
+ # The generated `.rspec` file contains `--require spec_helper` which will cause this
8
+ # file to always be loaded, without a need to explicitly require it in any files.
9
+ #
10
+ # Given that it is always loaded, you are encouraged to keep this file as
11
+ # light-weight as possible. Requiring heavyweight dependencies from this file
12
+ # will add to the boot time of your test suite on EVERY test run, even for an
13
+ # individual file that may not need all of that loaded. Instead, consider making
14
+ # a separate helper file that requires the additional dependencies and performs
15
+ # the additional setup, and require it from the spec files that actually need it.
16
+ #
17
+ # The `.rspec` file also contains a few flags that are not defaults but that
18
+ # users commonly want.
19
+ #
20
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
21
+ RSpec.configure do |config|
22
+ # rspec-expectations config goes here. You can use an alternate
23
+ # assertion/expectation library such as wrong or the stdlib/minitest
24
+ # assertions if you prefer.
25
+ config.expect_with :rspec do |expectations|
26
+ # This option will default to `true` in RSpec 4. It makes the `description`
27
+ # and `failure_message` of custom matchers include text for helper methods
28
+ # defined using `chain`, e.g.:
29
+ # be_bigger_than(2).and_smaller_than(4).description
30
+ # # => "be bigger than 2 and smaller than 4"
31
+ # ...rather than:
32
+ # # => "be bigger than 2"
33
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
34
+ end
35
+
36
+ # rspec-mocks config goes here. You can use an alternate test double
37
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
38
+ config.mock_with :rspec do |mocks|
39
+ # Prevents you from mocking or stubbing a method that does not exist on
40
+ # a real object. This is generally recommended, and will default to
41
+ # `true` in RSpec 4.
42
+ mocks.verify_partial_doubles = true
43
+ end
44
+
45
+ # The settings below are suggested to provide a good initial experience
46
+ # with RSpec, but feel free to customize to your heart's content.
47
+ =begin
48
+ # These two settings work together to allow you to limit a spec run
49
+ # to individual examples or groups you care about by tagging them with
50
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
51
+ # get run.
52
+ config.filter_run :focus
53
+ config.run_all_when_everything_filtered = true
54
+
55
+ # Limits the available syntax to the non-monkey patched syntax that is recommended.
56
+ # For more details, see:
57
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
58
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
59
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
60
+ config.disable_monkey_patching!
61
+
62
+ # This setting enables warnings. It's recommended, but in some cases may
63
+ # be too noisy due to issues in dependencies.
64
+ config.warnings = true
65
+
66
+ # Many RSpec users commonly either run the entire suite or an individual
67
+ # file, and it's useful to allow more verbose output when running an
68
+ # individual spec file.
69
+ if config.files_to_run.one?
70
+ # Use the documentation formatter for detailed output,
71
+ # unless a formatter has already been configured
72
+ # (e.g. via a command-line flag).
73
+ config.default_formatter = 'doc'
74
+ end
75
+
76
+ # Print the 10 slowest examples and example groups at the
77
+ # end of the spec run, to help surface which specs are running
78
+ # particularly slow.
79
+ config.profile_examples = 10
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ config.order = :random
86
+
87
+ # Seed global randomization in this process using the `--seed` CLI option.
88
+ # Setting this allows you to use `--seed` to deterministically reproduce
89
+ # test failures related to randomization by passing the same `--seed` value
90
+ # as the one that triggered the failure.
91
+ Kernel.srand config.seed
92
+ =end
93
+ end
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: knowtify
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Mckinney
8
+ - Dane Lyons
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-01-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: excon
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: bundler
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: '1.7'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: '1.7'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rspec-autotest
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: autotest
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ description: Knowtify helps you design and deliver transactional, behavioral and digest
99
+ emails to engage your users.
100
+ email:
101
+ - joshmckin@gmail.com
102
+ - dane@knowtify.io
103
+ executables: []
104
+ extensions: []
105
+ extra_rdoc_files: []
106
+ files:
107
+ - .gitignore
108
+ - .rspec
109
+ - Gemfile
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - knowtify.gemspec
114
+ - lib/knowtify.rb
115
+ - lib/knowtify/client.rb
116
+ - lib/knowtify/config.rb
117
+ - lib/knowtify/handlers/excon_handler.rb
118
+ - lib/knowtify/request.rb
119
+ - lib/knowtify/response.rb
120
+ - lib/knowtify/version.rb
121
+ - spec/lib/knowtify/client_spec.rb
122
+ - spec/lib/knowtify/config_spec.rb
123
+ - spec/lib/knowtify_spec.rb
124
+ - spec/spec_helper.rb
125
+ homepage: http://www.knowtify.io
126
+ licenses:
127
+ - MIT
128
+ metadata: {}
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ required_rubygems_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ requirements: []
144
+ rubyforge_project:
145
+ rubygems_version: 2.2.2
146
+ signing_key:
147
+ specification_version: 4
148
+ summary: Smart emails to engage your users
149
+ test_files:
150
+ - spec/lib/knowtify/client_spec.rb
151
+ - spec/lib/knowtify/config_spec.rb
152
+ - spec/lib/knowtify_spec.rb
153
+ - spec/spec_helper.rb