marketo_chef 1.0.2
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/.env.example +4 -0
- data/.gitignore +9 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +3 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile +6 -0
- data/README.md +85 -0
- data/Rakefile +20 -0
- data/bin/console +16 -0
- data/bin/setup +8 -0
- data/lib/marketo_chef.rb +131 -0
- data/lib/marketo_chef/client.rb +92 -0
- data/lib/marketo_chef/configuration.rb +32 -0
- data/lib/marketo_chef/version.rb +5 -0
- data/marketo_chef.gemspec +51 -0
- metadata +171 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4c36b0fb24e96ea385f40fa34880052e0d01908f
|
4
|
+
data.tar.gz: 9dcf3329d2f194cdf092713d783475c0d543adcc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bb2b0184f2497951fb2ab25ee12f619eaca6b120bf31fb61af55c428de5f15d85a78cf557e6d1a3bcb7c9993d8f4272642daa6a053f2b20ce7abbd08ebca5d1a
|
7
|
+
data.tar.gz: 67a90747de4831b81b40f11f4d1da75fbd514ba2998d90799a130196fcbd90e648f51e006a1f3906d1065a9251a9a07a8dd061f882798c4b1eaf7a2077cbcc3d
|
data/.env.example
ADDED
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
marketo_chef
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.1
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
|
+
|
7
|
+
## [1.0.2] - 2017.07.06
|
8
|
+
### Changed
|
9
|
+
- Marketo error codes are declared as Strings
|
10
|
+
- Pass the `reasons` array from the response to `handle_skipped`
|
11
|
+
|
12
|
+
## [1.0.1] - 2017.06.27
|
13
|
+
### Added
|
14
|
+
- Release history via CHANGELOG.md
|
15
|
+
- Documentation via README.md
|
16
|
+
- Checking response for communication failure (2d9f5c822a95187968944420998dc741fb8f2024)
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
- Error handling around response-level errors
|
20
|
+
- Lower required Faraday version due to transitive dependencies in client
|
21
|
+
applications (ce4109847c3569c1f2b442d32a530e32b8ae74bd)
|
22
|
+
|
23
|
+
## [0.1.0] - 2017.05.05
|
24
|
+
### Added
|
25
|
+
- Method to add lead, assign to campaign
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# MarketoChef
|
2
|
+
|
3
|
+
This gem defines a Marketo API client providing a simple interface to our
|
4
|
+
single common use case: adding a lead to the Marketo database and assigning it
|
5
|
+
to a specific campaign.
|
6
|
+
|
7
|
+
[](https://travis-ci.com/chef/marketo_chef)
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby gem 'marketo_chef' ```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install marketo_chef
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
The gem expects client code to configure it before use. Like so:
|
26
|
+
```ruby
|
27
|
+
MarketoChef.configure do |c|
|
28
|
+
c.host = ENV['MARKETO_HOST']
|
29
|
+
c.client_id = ENV['MARKETO_CLIENT_ID']
|
30
|
+
c.client_secret = ENV['MARKETO_CLIENT_SECRET']
|
31
|
+
c.campaign_id = ENV['MARKETO_CAMPAIGN_ID']
|
32
|
+
end
|
33
|
+
```
|
34
|
+
Conventionally this would be added to an initializer in Rails or Hanami, for
|
35
|
+
example in a file `config/initializers/01_marketo_chef.rb`, with Rails. This
|
36
|
+
ensures the application will attempt to configure the gem at start time rather
|
37
|
+
than later, when discovering that configuration values aren't available
|
38
|
+
(perhaps an environment variable name is incorrect) will generate unexpected
|
39
|
+
errors.
|
40
|
+
|
41
|
+
Required environment variables, with bogus example values:
|
42
|
+
```shell
|
43
|
+
MARKETO_HOST="123-ABC-456.mktorest.com"
|
44
|
+
MARKETO_CLIENT_ID="c4206ec5-be87-465c-a0cc-99486a4c4e1b"
|
45
|
+
MARKETO_CLIENT_SECRET="Z5bzTySMrFdgcFZkSNvBywMuUen9ah7Q"
|
46
|
+
MARKETO_CAMPAIGN_ID="1234"
|
47
|
+
```
|
48
|
+
|
49
|
+
The gem exposes a single method for lead tracking, which accepts a hash of lead
|
50
|
+
data, creates or updates the lead in Marketo, and adds it to the specified
|
51
|
+
campaign.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
MarketoChef.add_lead(
|
55
|
+
'formname': 'Some Form',
|
56
|
+
'product-interest': 'some-interest',
|
57
|
+
'firstName': 'Jane',
|
58
|
+
'lastName': 'Doe',
|
59
|
+
'email': 'jdoe@example.com',
|
60
|
+
'company': 'ExampleCo'
|
61
|
+
)
|
62
|
+
```
|
63
|
+
|
64
|
+
## Development
|
65
|
+
|
66
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
67
|
+
`rake test` to run the tests. You can also run `bin/console` for an interactive
|
68
|
+
prompt that will allow you to experiment.
|
69
|
+
|
70
|
+
You can also run `rubocop` to verify style guide adherence. It happens along
|
71
|
+
with the tests in CI, but better to catch those problems before committing and
|
72
|
+
pushing and so on.
|
73
|
+
|
74
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
75
|
+
|
76
|
+
To release a new version, update the version number in `version.rb`, then
|
77
|
+
create a git tag for the version, and update CHANGELOG.md to document the
|
78
|
+
release. Finally, push git commits and tags to GitHub.
|
79
|
+
|
80
|
+
This gem is not public and should not be published to rubygems.org.
|
81
|
+
|
82
|
+
## Contributing
|
83
|
+
|
84
|
+
Bug reports and pull requests are welcome on GitHub at
|
85
|
+
https://github.com/chef/marketo_chef.
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rake/testtask'
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << 'test'
|
8
|
+
t.libs << 'lib'
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'continuous integration tasks'
|
13
|
+
task ci: %i[test rubocop] do
|
14
|
+
end
|
15
|
+
|
16
|
+
task :rubocop do
|
17
|
+
sh 'rubocop'
|
18
|
+
end
|
19
|
+
|
20
|
+
task default: :ci
|
data/bin/console
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require 'bundler/setup'
|
6
|
+
require 'marketo_chef'
|
7
|
+
|
8
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
9
|
+
# with your gem easier. You can also use a different console, if you like.
|
10
|
+
|
11
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
12
|
+
# require "pry"
|
13
|
+
# Pry.start
|
14
|
+
|
15
|
+
require 'irb'
|
16
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/marketo_chef.rb
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
require 'marketo_chef/client'
|
6
|
+
require 'marketo_chef/configuration'
|
7
|
+
require 'marketo_chef/version'
|
8
|
+
|
9
|
+
# Common usage of the Marketo API for our web properties
|
10
|
+
module MarketoChef
|
11
|
+
# http://developers.marketo.com/rest-api/error-codes/#response_level_errors
|
12
|
+
# 607: Daily API Request Limit Reached
|
13
|
+
# 611: System Error (generic unhandled exception)
|
14
|
+
RESPONSE_ERROR_CODES = %w[607 611].freeze
|
15
|
+
|
16
|
+
# http://developers.marketo.com/rest-api/error-codes/#record_level_errors
|
17
|
+
# 1001: Invalid value '%s'. Required of type '%s'
|
18
|
+
# 1002: Missing value for required parameter '%s'
|
19
|
+
# 1003: Invalid data
|
20
|
+
# 1006: Field '%s' not found
|
21
|
+
# 1007: Multiple leads match the lookup criteria
|
22
|
+
# ...these are the only ones we might need to care about currently
|
23
|
+
MAYBE_OUR_FAULT_CODES = %w[1003 1006].freeze
|
24
|
+
MAYBE_THEIR_FAULT_CODES = %w[1001 1002].freeze
|
25
|
+
|
26
|
+
class << self
|
27
|
+
extend Forwardable
|
28
|
+
|
29
|
+
def_delegators :configuration,
|
30
|
+
:campaign_id, :client_id, :client_secret, :host
|
31
|
+
|
32
|
+
def configuration
|
33
|
+
@configuration ||= Configuration.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def configure
|
37
|
+
yield(configuration)
|
38
|
+
|
39
|
+
configuration.validate
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_lead(lead)
|
43
|
+
result = sync(lead)
|
44
|
+
|
45
|
+
return unless result
|
46
|
+
|
47
|
+
handle_skipped(lead, result['reasons']) if result['status'] == 'skipped'
|
48
|
+
|
49
|
+
trigger_campaign(campaign_id, result['id']) if result.key?('id')
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def sync(lead)
|
55
|
+
response = Client.instance.sync_lead(lead)
|
56
|
+
|
57
|
+
if response.key?('errors')
|
58
|
+
handle_response_err(response)
|
59
|
+
else
|
60
|
+
response['result']&.first
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def trigger_campaign(campaign_id, lead_id)
|
65
|
+
response = Client.instance.trigger_campaign(campaign_id, lead_id)
|
66
|
+
|
67
|
+
campaign_error(campaign_id, lead_id, response) if response.key?('errors')
|
68
|
+
|
69
|
+
response
|
70
|
+
end
|
71
|
+
|
72
|
+
def capture_error(message)
|
73
|
+
puts message
|
74
|
+
Raven.capture_exception(Exception.new(message))
|
75
|
+
end
|
76
|
+
|
77
|
+
def handle_response_err(response)
|
78
|
+
codes = ->(c) { c['code'] }
|
79
|
+
known = ->(c) { RESPONSE_ERROR_CODES.include?(c) }
|
80
|
+
feedback = ->(r) { "#{r['code']}: #{r['message']}" }
|
81
|
+
|
82
|
+
return if reasons.collect(&codes).any?(&known)
|
83
|
+
|
84
|
+
response_error(response.reject(&known).collect(&feedback))
|
85
|
+
end
|
86
|
+
|
87
|
+
def handle_skipped(lead, reasons)
|
88
|
+
codes = ->(c) { c['code'] }
|
89
|
+
reportable = ->(c) { MAYBE_OUR_FAULT_CODES.include?(c) }
|
90
|
+
feedback = ->(r) { "#{r['code']}: #{r['message']}" }
|
91
|
+
|
92
|
+
return unless reasons.collect(&codes).any?(&reportable)
|
93
|
+
|
94
|
+
skipped_lead_error(lead, reasons.collect(&feedback))
|
95
|
+
rescue TypeError => error
|
96
|
+
skipped_lead_type_error(lead, reasons, error)
|
97
|
+
end
|
98
|
+
|
99
|
+
def response_error(reasons)
|
100
|
+
capture_error <<~ERR
|
101
|
+
Response Error:\n
|
102
|
+
\t#{reasons.join("\n\t")}
|
103
|
+
ERR
|
104
|
+
end
|
105
|
+
|
106
|
+
def campaign_error(campaign_id, lead, errors)
|
107
|
+
capture_error <<~ERR
|
108
|
+
Campaign Triggering Error: #{errors}\n
|
109
|
+
\tcampaign id: #{campaign_id}\n
|
110
|
+
\tlead: #{lead}
|
111
|
+
ERR
|
112
|
+
end
|
113
|
+
|
114
|
+
def skipped_lead_error(lead, reasons)
|
115
|
+
capture_error <<~ERR
|
116
|
+
Lead Submission Skipped:\n
|
117
|
+
\tinput: #{lead}\n
|
118
|
+
\t#{reasons.join("\n\t")}
|
119
|
+
ERR
|
120
|
+
end
|
121
|
+
|
122
|
+
def skipped_lead_type_error(lead, reasons, error)
|
123
|
+
capture_error <<~ERR
|
124
|
+
Something went wrong trying to parse this skipped lead response:\n
|
125
|
+
\tLead: #{lead}\n
|
126
|
+
\tReasons: #{reasons}\n
|
127
|
+
\tError: #{error}
|
128
|
+
ERR
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
require 'faraday'
|
7
|
+
require 'faraday_middleware'
|
8
|
+
|
9
|
+
module MarketoChef
|
10
|
+
# Faraday wrapper to handle communication with Marketo API
|
11
|
+
class Client
|
12
|
+
include Singleton
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
def_delegators :MarketoChef, :client_id, :client_secret, :host
|
16
|
+
|
17
|
+
def sync_lead(lead)
|
18
|
+
authenticate!
|
19
|
+
|
20
|
+
connection.post do |req|
|
21
|
+
req.url '/rest/v1/leads.json'
|
22
|
+
req.headers[:authorization] = "Bearer #{@token}"
|
23
|
+
req.body = { action: 'createOrUpdate', input: [lead] }
|
24
|
+
end.body
|
25
|
+
end
|
26
|
+
|
27
|
+
def trigger_campaign(campaign_id, lead_id)
|
28
|
+
authenticate!
|
29
|
+
|
30
|
+
connection.post do |req|
|
31
|
+
req.url "/rest/v1/campaigns/#{campaign_id}/trigger.json"
|
32
|
+
req.headers[:authorization] = "Bearer #{@token}"
|
33
|
+
req.body = { input: { leads: [{ id: lead_id }] } }
|
34
|
+
end.body
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def connection
|
40
|
+
@connection ||= Faraday.new(url: "https://#{host}") do |conn|
|
41
|
+
conn.request :multipart
|
42
|
+
conn.request :json
|
43
|
+
conn.response :json, content_type: /\bjson$/
|
44
|
+
conn.adapter Faraday.default_adapter
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def authenticate!
|
49
|
+
authenticate unless authenticated?
|
50
|
+
end
|
51
|
+
|
52
|
+
def authenticated?
|
53
|
+
@token && valid_token?
|
54
|
+
end
|
55
|
+
|
56
|
+
def valid_token?
|
57
|
+
return false unless defined?(@valid_until)
|
58
|
+
|
59
|
+
Time.now < @valid_until
|
60
|
+
end
|
61
|
+
|
62
|
+
def authenticate
|
63
|
+
connection.get('/identity/oauth/token', auth_params).tap do |res|
|
64
|
+
inspect_auth_response(res.body)
|
65
|
+
|
66
|
+
save_authentication(res.body)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def inspect_auth_response(body)
|
71
|
+
# res.body may be an HTML string, "The document has moved" message,
|
72
|
+
# which occurs if the host is mktoapi.com instead of mktorest.com.
|
73
|
+
raise body if body.is_a?(String)
|
74
|
+
raise body['errors'][0]['message'] if body.key?('errors')
|
75
|
+
end
|
76
|
+
|
77
|
+
def auth_params
|
78
|
+
{
|
79
|
+
grant_type: 'client_credentials',
|
80
|
+
client_id: client_id,
|
81
|
+
client_secret: client_secret
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def save_authentication(data)
|
86
|
+
@token = data.fetch('access_token')
|
87
|
+
@token_type = data.fetch('token_type')
|
88
|
+
@valid_until = Time.now + data.fetch('expires_in')
|
89
|
+
@scope = data.fetch('scope')
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MarketoChef
|
4
|
+
# Store and validate Marketo client configuration data
|
5
|
+
class Configuration
|
6
|
+
FIELDS = %i[host client_id client_secret campaign_id].freeze
|
7
|
+
|
8
|
+
attr_accessor :client_id, :client_secret, :campaign_id
|
9
|
+
attr_reader :host
|
10
|
+
|
11
|
+
def initialize(config = {})
|
12
|
+
return unless config.any?
|
13
|
+
|
14
|
+
config.map { |k, v| send("#{k}=", v) if FIELDS.include?(k) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def host=(value)
|
18
|
+
value = value.sub('mktoapi', 'mktorest')
|
19
|
+
|
20
|
+
match = %r{https?:\/\/(.+)}.match(value)
|
21
|
+
|
22
|
+
@host = match ? match[1] : value
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate
|
26
|
+
missing = ->(f) { !instance_variable_defined?(:"@#{f}") }
|
27
|
+
bomb = ->(f) { raise "Required Marketo configuration undefined: #{f}" }
|
28
|
+
|
29
|
+
FIELDS.select(&missing).map(&bomb)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib = File.expand_path('../lib', __FILE__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
require 'marketo_chef/version'
|
7
|
+
|
8
|
+
# rubocop:disable Style/GuardClause
|
9
|
+
# rubocop:disable Metrics/BlockLength
|
10
|
+
Gem::Specification.new do |spec|
|
11
|
+
spec.name = 'marketo_chef'
|
12
|
+
spec.version = MarketoChef::VERSION
|
13
|
+
spec.authors = ['Trevor Bramble']
|
14
|
+
spec.email = ['tbramble@chef.io']
|
15
|
+
|
16
|
+
spec.summary = 'Marketo API client for our common uses and error handling'
|
17
|
+
spec.homepage = 'https://github.com/chef/marketo_chef'
|
18
|
+
|
19
|
+
spec.licenses = [] # closed-source
|
20
|
+
|
21
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the
|
22
|
+
# 'allowed_push_host' to allow pushing to a single host or delete this
|
23
|
+
# section to allow pushing to any host.
|
24
|
+
# if spec.respond_to?(:metadata)
|
25
|
+
# spec.metadata['allowed_push_host'] = 'https://ixnay.ushpay'
|
26
|
+
# else
|
27
|
+
# raise 'RubyGems >= 2.0 required to protect against public gem pushes.'
|
28
|
+
# end
|
29
|
+
|
30
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
31
|
+
f.match(%r{^(test|spec|features)/})
|
32
|
+
end
|
33
|
+
spec.bindir = 'exe'
|
34
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
35
|
+
spec.require_paths = ['lib']
|
36
|
+
|
37
|
+
# This gem needs to be compatible with OmniAuth (used on the Learn Chef site)
|
38
|
+
# which depends on the OAuth2 gem, which requires faraday ['>= 0.8', '< 0.12']
|
39
|
+
# https://github.com/intridea/oauth2/blob/v1.3.1/oauth2.gemspec
|
40
|
+
spec.add_runtime_dependency 'faraday', '~> 0.11.0'
|
41
|
+
spec.add_runtime_dependency 'faraday_middleware', '~> 0.11'
|
42
|
+
|
43
|
+
spec.add_development_dependency 'bundler', '~> 1.14'
|
44
|
+
spec.add_development_dependency 'minitest', '~> 5.10'
|
45
|
+
spec.add_development_dependency 'rake', '~> 12.0'
|
46
|
+
spec.add_development_dependency 'rspec-expectations', '~> 3.6'
|
47
|
+
spec.add_development_dependency 'rubocop', '~> 0.48'
|
48
|
+
spec.add_development_dependency 'travis', '~> 1.8'
|
49
|
+
end
|
50
|
+
# rubocop:enable Metrics/BlockLength
|
51
|
+
# rubocop:enable Style/GuardClause
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: marketo_chef
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Trevor Bramble
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-03-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.11.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.11.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday_middleware
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.11'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.14'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.14'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.10'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '12.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '12.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec-expectations
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.6'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.6'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.48'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.48'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: travis
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.8'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.8'
|
125
|
+
description:
|
126
|
+
email:
|
127
|
+
- tbramble@chef.io
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- ".env.example"
|
133
|
+
- ".gitignore"
|
134
|
+
- ".ruby-gemset"
|
135
|
+
- ".ruby-version"
|
136
|
+
- ".travis.yml"
|
137
|
+
- CHANGELOG.md
|
138
|
+
- Gemfile
|
139
|
+
- README.md
|
140
|
+
- Rakefile
|
141
|
+
- bin/console
|
142
|
+
- bin/setup
|
143
|
+
- lib/marketo_chef.rb
|
144
|
+
- lib/marketo_chef/client.rb
|
145
|
+
- lib/marketo_chef/configuration.rb
|
146
|
+
- lib/marketo_chef/version.rb
|
147
|
+
- marketo_chef.gemspec
|
148
|
+
homepage: https://github.com/chef/marketo_chef
|
149
|
+
licenses: []
|
150
|
+
metadata: {}
|
151
|
+
post_install_message:
|
152
|
+
rdoc_options: []
|
153
|
+
require_paths:
|
154
|
+
- lib
|
155
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project:
|
167
|
+
rubygems_version: 2.6.14
|
168
|
+
signing_key:
|
169
|
+
specification_version: 4
|
170
|
+
summary: Marketo API client for our common uses and error handling
|
171
|
+
test_files: []
|