promoter 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +1 -0
- data/lib/promoter.rb +15 -0
- data/lib/promoter/campaign.rb +39 -0
- data/lib/promoter/contact.rb +53 -0
- data/lib/promoter/contact_list.rb +31 -0
- data/lib/promoter/errors.rb +50 -0
- data/lib/promoter/feedback.rb +54 -0
- data/lib/promoter/metric.rb +21 -0
- data/lib/promoter/request.rb +57 -0
- data/lib/promoter/version.rb +3 -0
- data/promoter.gemspec +29 -0
- metadata +159 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 95792b0b464ff9072200693024cf2cf5d115ef39
|
4
|
+
data.tar.gz: a5d4acfaaa3381413c4fe093167f35453c4df479
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 38f0998be10fee79e559bfa8303a52a155034e1e7a60eadfa8aaa20a08c544f3fd91cb1f972f475b0ac6b3f1bb18e2d9172e2309c60857515f0acc86f0141ed0
|
7
|
+
data.tar.gz: 8cde91e251abc021b76eb4c4e8d387cce2c16fa9bb42198db60e83db2d8a5766ba2c0f3a1fb0a1ddc672ebce7e09df01c4d4356bf87840bb4adc8a0255b2c2b1
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Chris O'Sullivan
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Promoter
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/promoter`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'promoter'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install promoter
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
1. Fork it ( https://github.com/[my-github-username]/promoter/fork )
|
36
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
37
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
38
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
39
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/lib/promoter.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "promoter/version"
|
2
|
+
require "promoter/errors"
|
3
|
+
require "promoter/request"
|
4
|
+
require "promoter/campaign"
|
5
|
+
require "promoter/contact"
|
6
|
+
require "promoter/contact_list"
|
7
|
+
require "promoter/feedback"
|
8
|
+
require "promoter/metric"
|
9
|
+
|
10
|
+
module Promoter
|
11
|
+
class << self
|
12
|
+
attr_accessor :api_key
|
13
|
+
attr_accessor :debug
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Promoter
|
2
|
+
|
3
|
+
class Campaign
|
4
|
+
|
5
|
+
API_URL = "https://app.promoter.io/api/campaigns"
|
6
|
+
|
7
|
+
attr_reader :id, :name, :drip_duration, :contact_count, :eligible_count,
|
8
|
+
:last_surveyed_date, :launch_date
|
9
|
+
|
10
|
+
def initialize(attrs)
|
11
|
+
@id = attrs["id"]
|
12
|
+
@name = attrs["name"]
|
13
|
+
@drip_duration = attrs["drip_duration"]
|
14
|
+
@contact_count = attrs["all_count"]
|
15
|
+
@eligible_count = attrs["eligible_count"]
|
16
|
+
@last_surveyed_date = Time.parse(attrs["last_surveyed_date"]) if attrs["last_surveyed_date"]
|
17
|
+
@launch_date = Time.parse(attrs["launch_date"]) if attrs["launch_date"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.all(page=1)
|
21
|
+
response = Request.get("#{API_URL}/?page=#{page}")
|
22
|
+
response['results'].map {|attrs| new(attrs)}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Parameter Optional? Description
|
26
|
+
# all_contacts yes Can be set to true,false
|
27
|
+
# If set to true, the call will send surveys to all
|
28
|
+
# contacts in your specified contact list.
|
29
|
+
# If set to false, the call will send surveys to
|
30
|
+
# contacts who have been added or updated since you
|
31
|
+
# last sent surveys. The default behavior is when
|
32
|
+
# all_contacts is set to false.
|
33
|
+
def self.send_surveys(campaign_id, all_contacts=false)
|
34
|
+
response = Request.post("#{API_URL}/#{campaign_id}/send-surveys/",
|
35
|
+
{ all_contacts: all_contacts, response_format: :plain })
|
36
|
+
response.match /Success\, surveys sent\./
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Promoter
|
2
|
+
|
3
|
+
class Contact
|
4
|
+
|
5
|
+
attr_reader :id, :email, :first_name, :last_name, :created_date, :attributes
|
6
|
+
|
7
|
+
API_URL = "https://app.promoter.io/api/contacts"
|
8
|
+
|
9
|
+
def initialize(attrs)
|
10
|
+
@id = attrs["id"]
|
11
|
+
@email = attrs["email"]
|
12
|
+
@first_name = attrs["first_name"]
|
13
|
+
@last_name = attrs["last_name"]
|
14
|
+
@created_date = Time.parse(attrs["created_date"]) if attrs["created_date"]
|
15
|
+
@attributes = attrs["attributes"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.all(page=1)
|
19
|
+
response = Request.get("#{API_URL}/?page=#{page}")
|
20
|
+
response['results'].map {|attrs| new(attrs)}
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.find(id)
|
24
|
+
response = Request.get("#{API_URL}/#{id}")
|
25
|
+
new(response)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Contact Params
|
29
|
+
# Parameter Optional? Description
|
30
|
+
# email no The email of the contact to add to the organization.
|
31
|
+
# first_name yes The first name of the contact to add to the organization.
|
32
|
+
# last_name yes The last name of the contact to add to the organization.
|
33
|
+
# contact_list yes A list of Contact List Id’s to associate a contact to.
|
34
|
+
# If one is not provided the contact will be
|
35
|
+
# associated to a default generated contact list.
|
36
|
+
# attributes yes A dictionary of key value pairs of custom
|
37
|
+
# attributes that will be associated with the
|
38
|
+
# contact and contact list.
|
39
|
+
# send yes A boolean value set to true in order to express
|
40
|
+
# intent to survey this contact for a given campaign.
|
41
|
+
# campaign yes The campaign id you would like to associate the
|
42
|
+
# contact to. Note: Campaign must have a contact
|
43
|
+
# list associated to it in order for the contact to
|
44
|
+
# be added correctly. Otherwise, the contact will
|
45
|
+
# be associated to a default generated contact list
|
46
|
+
# for your given organization.
|
47
|
+
def self.create(attributes)
|
48
|
+
response = Request.post(API_URL + "/", attributes)
|
49
|
+
new(response)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Promoter
|
2
|
+
|
3
|
+
class ContactList
|
4
|
+
|
5
|
+
attr_reader :id, :name
|
6
|
+
|
7
|
+
API_URL = "https://app.promoter.io/api/lists"
|
8
|
+
|
9
|
+
def initialize(attrs)
|
10
|
+
@id = attrs['id']
|
11
|
+
@name = attrs['name']
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.all(page=1)
|
15
|
+
response = Request.get("#{API_URL}/?page=#{page}")
|
16
|
+
response['results'].map {|attrs| new(attrs)}
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.contact_ids_for(contact_list_id)
|
20
|
+
response = Request.get("#{API_URL}/#{contact_list_id}/contacts")
|
21
|
+
response['results'].map {|attrs| attrs["id"]}
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.remove_contact(params={})
|
25
|
+
contact_list_id = params[:contact_list_id]
|
26
|
+
contact_id = params[:contact_id]
|
27
|
+
Request.delete("#{API_URL}/#{contact_list_id}/contacts/#{contact_id}")
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Promoter
|
2
|
+
module Errors
|
3
|
+
class BadRequest < StandardError; end
|
4
|
+
class Unauthorized < StandardError; end
|
5
|
+
class Forbidden < StandardError; end
|
6
|
+
class NotFound < StandardError; end
|
7
|
+
class MethodNotAllowed < StandardError; end
|
8
|
+
class NotAcceptable < StandardError; end
|
9
|
+
class Gone < StandardError; end
|
10
|
+
class TooManyRequests < StandardError; end
|
11
|
+
class InternalServerError < StandardError; end
|
12
|
+
class ServiceUnavailable < StandardError; end
|
13
|
+
|
14
|
+
# Error Code Meaning
|
15
|
+
# 400 Bad Request – Something is wrong with your request
|
16
|
+
# 401 Unauthorized – Your API key is incorrect or invalid
|
17
|
+
# 403 Forbidden – The resource requested is hidden for administrators only
|
18
|
+
# 404 Not Found – The specified resource could not be found
|
19
|
+
# 405 Method Not Allowed – You tried to access a resource with an invalid method
|
20
|
+
# 406 Not Acceptable – You requested a format that isn’t json
|
21
|
+
# 410 Gone – The resource requested has been removed from our servers
|
22
|
+
# 429 Too Many Requests – You’re requesting too much! Slown down!
|
23
|
+
# 500 Internal Server Error – We had a problem with our server. Try again later.
|
24
|
+
# 503 Service Unavailable – We’re temporarially offline for maintanance. Please try again later.
|
25
|
+
def check_for_error(status_code)
|
26
|
+
case status_code.to_i
|
27
|
+
when 400
|
28
|
+
raise BadRequest.new("Something is wrong with your request")
|
29
|
+
when 401
|
30
|
+
raise Unauthorized.new("Your API key is incorrect or invalid")
|
31
|
+
when 403
|
32
|
+
raise Forbidden.new("The resource requested is hidden for administrators only")
|
33
|
+
when 404
|
34
|
+
raise NotFound.new("The specified resource could not be found")
|
35
|
+
when 405
|
36
|
+
raise MethodNotAllowed.new("You tried to access a resource with an invalid method")
|
37
|
+
when 406
|
38
|
+
raise NotAcceptable.new("You requested a format that isn’t json")
|
39
|
+
when 410
|
40
|
+
raise Gone.new("The resource requested has been removed from our servers")
|
41
|
+
when 429
|
42
|
+
raise TooManyRequests.new("You’re requesting too much! Slown down!")
|
43
|
+
when 500
|
44
|
+
raise InternalServerError.new("We had a problem with our server. Try again later.")
|
45
|
+
when 503
|
46
|
+
raise ServiceUnavailable.new("We’re temporarially offline for maintanance. Please try again later.")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Promoter
|
2
|
+
|
3
|
+
class Feedback
|
4
|
+
|
5
|
+
attr_reader :id, :contact, :score, :score_type, :posted_date, :comment, :follow_up_url, :url
|
6
|
+
|
7
|
+
API_URL = "https://app.promoter.io/api/feedback"
|
8
|
+
|
9
|
+
def initialize(attrs)
|
10
|
+
@id = attrs["id"]
|
11
|
+
@contact = Contact.new(attrs["contact"])
|
12
|
+
@score = attrs["score"]
|
13
|
+
@score_type = attrs["score_type"]
|
14
|
+
@posted_date = Time.parse(attrs["posted_date"])
|
15
|
+
@comment = attrs["comment"]
|
16
|
+
@follow_up_url = attrs["followup_href"]
|
17
|
+
@follow_up_href = attrs["href"]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Parameter Required Description
|
21
|
+
# score false Filtering by score can be achieved with
|
22
|
+
# a range 0-10
|
23
|
+
# score_type false Filtering by score type can be achieved
|
24
|
+
# with a list of values promoter,
|
25
|
+
# detractor, passive
|
26
|
+
# survey__campaign false Filtering by campaign can be achieved
|
27
|
+
# by the given id of your campaign id
|
28
|
+
# survey__campaign__status false Filtering by campaign status can be
|
29
|
+
# achieved by providing one of the
|
30
|
+
# campaign status values: ACTIVE, COMPLETE.
|
31
|
+
# NOTE: This url parameter does not require quotes around the value.
|
32
|
+
# e.g. (<api-url>?survey__campaign__status=ACTIVE)
|
33
|
+
def self.all(attrs={})
|
34
|
+
response = Request.get("#{API_URL}/?#{query_string(attrs)}")
|
35
|
+
response['results'].map {|attrs| new(attrs)}
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.find(id)
|
39
|
+
response = Request.get("#{API_URL}/#{id}")
|
40
|
+
new(response)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def self.query_string(attrs)
|
46
|
+
# campaign_id is preferable to survey_campaign (which is what promoter expects)
|
47
|
+
if attrs.has_key?(:campaign_id)
|
48
|
+
attrs[:survey_campaign] = attrs.delete(:campaign_id)
|
49
|
+
end
|
50
|
+
URI.encode_www_form(attrs)
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Promoter
|
2
|
+
|
3
|
+
class Metric
|
4
|
+
|
5
|
+
attr_accessor :campaign_name, :nps, :organization_nps
|
6
|
+
|
7
|
+
API_URL = "https://app.promoter.io/api/metrics"
|
8
|
+
|
9
|
+
def initialize(attrs)
|
10
|
+
@campaign_name = attrs["campaign"]
|
11
|
+
@nps = attrs["nps"].to_f
|
12
|
+
@organization_nps = attrs["organization_nps"].to_f
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.all(page=1)
|
16
|
+
response = Request.get("#{API_URL}/?page=#{page}")
|
17
|
+
response['results'].map {|attrs| new(attrs)}
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Promoter
|
5
|
+
|
6
|
+
class Request
|
7
|
+
|
8
|
+
include HTTParty
|
9
|
+
extend Errors
|
10
|
+
|
11
|
+
def self.get(url)
|
12
|
+
response = HTTParty.get(url, headers: auth_header)
|
13
|
+
parse_response(response)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.post(url, params)
|
17
|
+
response_format = params.delete(:response_format) || :json
|
18
|
+
response = HTTParty.post(url, body: params.to_json, headers: auth_header)
|
19
|
+
parse_response(response, response_format)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.delete(url)
|
23
|
+
response = HTTParty.delete(url, headers: auth_header)
|
24
|
+
parse_response(response)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.parse_response(response, response_format=:json)
|
30
|
+
check_for_error(response.response.code)
|
31
|
+
display_debug(response.body)
|
32
|
+
if response_format == :json
|
33
|
+
JSON.parse(response.body.to_s)
|
34
|
+
else
|
35
|
+
response.body.to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.display_debug(response)
|
40
|
+
if Promoter.debug
|
41
|
+
puts "-" * 20 + " DEBUG " + "-" * 20
|
42
|
+
puts response
|
43
|
+
puts "-" * 18 + " END DEBUG " + "-" * 18
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.auth_header
|
48
|
+
if Promoter.api_key.empty?
|
49
|
+
raise Unauthorized.new("You need to set your promoter api key. You can register for a Promoter API key with a Promoter.io Account.")
|
50
|
+
end
|
51
|
+
{ "Authorization" => "Token #{Promoter.api_key}",
|
52
|
+
'Content-Type' => 'application/json' }
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/promoter.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'promoter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "promoter"
|
8
|
+
spec.version = Promoter::VERSION
|
9
|
+
spec.authors = ["Chris O'Sullivan"]
|
10
|
+
spec.email = ["thechrisoshow@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{promoter is a wrapper for the promoter.io REST API}
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
21
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
22
|
+
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "webmock"
|
25
|
+
spec.add_development_dependency "byebug"
|
26
|
+
|
27
|
+
spec.add_dependency "httparty"
|
28
|
+
spec.add_dependency "json"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: promoter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chris O'Sullivan
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: webmock
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: httparty
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: json
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description:
|
112
|
+
email:
|
113
|
+
- thechrisoshow@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- ".rspec"
|
120
|
+
- ".travis.yml"
|
121
|
+
- Gemfile
|
122
|
+
- LICENSE.txt
|
123
|
+
- README.md
|
124
|
+
- Rakefile
|
125
|
+
- lib/promoter.rb
|
126
|
+
- lib/promoter/campaign.rb
|
127
|
+
- lib/promoter/contact.rb
|
128
|
+
- lib/promoter/contact_list.rb
|
129
|
+
- lib/promoter/errors.rb
|
130
|
+
- lib/promoter/feedback.rb
|
131
|
+
- lib/promoter/metric.rb
|
132
|
+
- lib/promoter/request.rb
|
133
|
+
- lib/promoter/version.rb
|
134
|
+
- promoter.gemspec
|
135
|
+
homepage:
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - ">="
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project:
|
155
|
+
rubygems_version: 2.4.8
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: promoter is a wrapper for the promoter.io REST API
|
159
|
+
test_files: []
|