ruby-pardot 1.2.0 → 1.4.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +9 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +26 -19
- data/README.rdoc +23 -18
- data/Rakefile +2 -3
- data/lib/pardot/authentication.rb +23 -12
- data/lib/pardot/client.rb +18 -6
- data/lib/pardot/error.rb +6 -2
- data/lib/pardot/http.rb +51 -41
- data/lib/pardot/objects/custom_fields.rb +33 -0
- data/lib/pardot/objects/emails.rb +9 -14
- data/lib/pardot/objects/list_memberships.rb +8 -12
- data/lib/pardot/objects/lists.rb +20 -25
- data/lib/pardot/objects/opportunities.rb +21 -26
- data/lib/pardot/objects/prospect_accounts.rb +6 -7
- data/lib/pardot/objects/prospects.rb +69 -71
- data/lib/pardot/objects/users.rb +17 -21
- data/lib/pardot/objects/visitor_activities.rb +15 -19
- data/lib/pardot/objects/visitors.rb +17 -21
- data/lib/pardot/objects/visits.rb +15 -19
- data/lib/pardot/version.rb +1 -1
- data/lib/ruby-pardot.rb +1 -0
- data/ruby-pardot.gemspec +15 -13
- data/spec/pardot/authentication_spec.rb +84 -50
- data/spec/pardot/client_spec.rb +52 -17
- data/spec/pardot/error_spec.rb +6 -4
- data/spec/pardot/http_spec.rb +96 -104
- data/spec/pardot/objects/custom_fields_spec.rb +53 -0
- data/spec/pardot/objects/emails_spec.rb +34 -33
- data/spec/pardot/objects/lists_spec.rb +34 -37
- data/spec/pardot/objects/opportunities_spec.rb +59 -60
- data/spec/pardot/objects/prospect_accounts_spec.rb +72 -73
- data/spec/pardot/objects/prospects_spec.rb +58 -57
- data/spec/pardot/objects/users_spec.rb +58 -60
- data/spec/pardot/objects/visitor_activities_spec.rb +57 -60
- data/spec/pardot/objects/visitors_spec.rb +56 -60
- data/spec/pardot/objects/visits_spec.rb +56 -60
- data/spec/spec_helper.rb +2 -0
- data/spec/support/client_support.rb +40 -4
- data/spec/support/fakeweb.rb +14 -5
- metadata +17 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3bbcca81ecfa08ef3cfb444a8117ef8a708f3e6975336e0f48fd480972449a6
|
4
|
+
data.tar.gz: 1f4b717f3150591b35ae17d96a5da3382235988afbe06c646cb84dfd198a7461
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0da946b746fed6cd5091b6d6e55d978a6cee69f641aa7e01040013d3ca81538eeec91424b6e23ca7232975cc100716681eba97007dd60d68f35f9c2bb5e0c6f
|
7
|
+
data.tar.gz: 519af7a9e7870b7a8da0242c7c6fd2f011ac46251a24f1fcd5f82117191f596c565032927bbdd152b76a3137038679d02355b750389ecd6d74c600d136c7d17c
|
data/.rubocop.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,40 +1,47 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-pardot (1.
|
4
|
+
ruby-pardot (1.4.0)
|
5
5
|
crack (= 0.4.3)
|
6
|
-
httparty (= 0.
|
6
|
+
httparty (= 0.18.1)
|
7
7
|
|
8
8
|
GEM
|
9
|
-
remote:
|
9
|
+
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
crack (0.4.3)
|
12
12
|
safe_yaml (~> 1.0.0)
|
13
|
-
diff-lcs (1.
|
13
|
+
diff-lcs (1.4.4)
|
14
14
|
fakeweb (1.3.0)
|
15
|
-
httparty (0.
|
16
|
-
|
15
|
+
httparty (0.18.1)
|
16
|
+
mime-types (~> 3.0)
|
17
17
|
multi_xml (>= 0.5.2)
|
18
|
-
|
18
|
+
mime-types (3.3.1)
|
19
|
+
mime-types-data (~> 3.2015)
|
20
|
+
mime-types-data (3.2020.1104)
|
19
21
|
multi_xml (0.6.0)
|
20
|
-
rspec (
|
21
|
-
rspec-core (~>
|
22
|
-
rspec-expectations (~>
|
23
|
-
rspec-mocks (~>
|
24
|
-
rspec-core (
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
rspec (3.5.0)
|
23
|
+
rspec-core (~> 3.5.0)
|
24
|
+
rspec-expectations (~> 3.5.0)
|
25
|
+
rspec-mocks (~> 3.5.0)
|
26
|
+
rspec-core (3.5.4)
|
27
|
+
rspec-support (~> 3.5.0)
|
28
|
+
rspec-expectations (3.5.0)
|
29
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
+
rspec-support (~> 3.5.0)
|
31
|
+
rspec-mocks (3.5.0)
|
32
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
33
|
+
rspec-support (~> 3.5.0)
|
34
|
+
rspec-support (3.5.0)
|
35
|
+
safe_yaml (1.0.5)
|
29
36
|
|
30
37
|
PLATFORMS
|
31
38
|
ruby
|
32
39
|
|
33
40
|
DEPENDENCIES
|
34
41
|
bundler (>= 1.10)
|
35
|
-
fakeweb
|
36
|
-
rspec
|
42
|
+
fakeweb (= 1.3.0)
|
43
|
+
rspec (= 3.5.0)
|
37
44
|
ruby-pardot!
|
38
45
|
|
39
46
|
BUNDLED WITH
|
40
|
-
2.
|
47
|
+
2.2.7
|
data/README.rdoc
CHANGED
@@ -8,18 +8,23 @@ Add the following to your Gemfile
|
|
8
8
|
|
9
9
|
=== Authentication
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
In order to use this client, an access token retrieved from Salesforce OAuth must be specified. See
|
12
|
+
the [authetication documentation on developer.pardot.com](https://developer.pardot.com/kb/authentication/) for more information.
|
13
|
+
|
14
|
+
require "ruby-pardot"
|
15
|
+
|
16
|
+
version = 3 # or 4
|
17
|
+
access_token = '<access_token>' # Retrieve an access token from Salesforce using OAuth
|
18
|
+
business_unit_id = '<business_unit_id>' # Specify the Business Unit ID of the account to access
|
19
|
+
client = Pardot::Client.new nil, nil, nil, version, access_token, business_unit_id
|
20
|
+
|
21
|
+
Usage of the username, password, and API key authentication is deprecated and will be removed in an upcoming release.
|
22
|
+
|
19
23
|
=== Object Types
|
20
24
|
|
21
25
|
The available objects are:
|
22
26
|
|
27
|
+
* custom_fields
|
23
28
|
* emails
|
24
29
|
* lists
|
25
30
|
* opportunities
|
@@ -30,15 +35,15 @@ The available objects are:
|
|
30
35
|
* visits
|
31
36
|
|
32
37
|
=== Querying Objects
|
33
|
-
|
38
|
+
|
34
39
|
http://developer.pardot.com/kb/api-version-3/querying-prospects
|
35
|
-
|
40
|
+
|
36
41
|
Most objects accept limit, offset, sort_by, and sord_order parameters
|
37
42
|
|
38
43
|
prospects = client.prospects.query(:assigned => false, :sort_by => "last_activity_at", :limit => 20)
|
39
|
-
|
44
|
+
|
40
45
|
prospects["total_results"] # number of prospects found
|
41
|
-
|
46
|
+
|
42
47
|
prospects["prospect"].each do |prospect|
|
43
48
|
puts prospect["first_name"]
|
44
49
|
end
|
@@ -50,11 +55,11 @@ See each individual object's API reference page for available methods
|
|
50
55
|
http://developer.pardot.com/kb/api-version-3/using-prospects
|
51
56
|
|
52
57
|
prospect = client.prospects.create("user@test.com", :first_name => "John", :last_name => "Doe")
|
53
|
-
|
58
|
+
|
54
59
|
prospect.each do |key, value|
|
55
60
|
puts "#{key} is #{value}"
|
56
61
|
end
|
57
|
-
|
62
|
+
|
58
63
|
=== Emails
|
59
64
|
|
60
65
|
See each individual call's [API reference page](http://developer.pardot.com/kb/api-version-3/introduction-table-of-contents).
|
@@ -63,15 +68,15 @@ See each individual call's [API reference page](http://developer.pardot.com/kb/a
|
|
63
68
|
@pardot.emails.read_by_id(email_id)
|
64
69
|
@pardot.emails.send_to_list(:email_template_id => template_id, 'list_ids[]' => list_id, :campaign_id => campaign_id)
|
65
70
|
@pardot.emails.send_to_prospect(prospect_id, :campaign_id => campaign_id, :email_template_id => template_id)
|
66
|
-
|
71
|
+
|
67
72
|
=== Output formats
|
68
|
-
|
73
|
+
|
69
74
|
client.format = "simple" # default
|
70
75
|
client.format = "mobile"
|
71
76
|
client.format = "full"
|
72
77
|
|
73
78
|
=== Error handling
|
74
|
-
|
79
|
+
|
75
80
|
Pardot will respond with an error message when you provide invalid parameters
|
76
81
|
|
77
82
|
begin
|
@@ -81,7 +86,7 @@ Pardot will respond with an error message when you provide invalid parameters
|
|
81
86
|
end
|
82
87
|
|
83
88
|
Performing API calls across the internet is inherently unsafe, so be sure to catch the exceptions
|
84
|
-
|
89
|
+
|
85
90
|
begin
|
86
91
|
visitor = client.visitors.query(:id_greater_than => 200)
|
87
92
|
rescue Pardot::NetError => e
|
data/Rakefile
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
|
-
|
5
4
|
require 'rspec/core'
|
6
5
|
require 'rspec/core/rake_task'
|
7
6
|
|
8
|
-
desc
|
7
|
+
desc 'Run all specs'
|
9
8
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
10
|
-
t.pattern =
|
9
|
+
t.pattern = './spec/**/*_spec.rb'
|
11
10
|
end
|
@@ -1,29 +1,40 @@
|
|
1
1
|
module Pardot
|
2
2
|
module Authentication
|
3
|
-
|
3
|
+
# @deprecated Use of username and password authentication is deprecated.
|
4
4
|
def authenticate
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
if using_salesforce_access_token?
|
6
|
+
raise 'Authentication not available when using Salesforce access token. See https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm for more information.'
|
7
|
+
end
|
8
|
+
|
9
|
+
warn '[DEPRECATION] Use of username and password authentication is deprecated in favor of Salesforce OAuth. See https://developer.pardot.com/kb/authentication/ for more information.'
|
10
|
+
resp = post 'login', nil, nil, nil, email: @email, password: @password, user_key: @user_key
|
11
|
+
update_version(resp['version']) if resp && resp['version']
|
12
|
+
@api_key = resp && resp['api_key']
|
8
13
|
end
|
9
|
-
|
14
|
+
|
10
15
|
def authenticated?
|
11
|
-
|
16
|
+
!@api_key.nil? || !@salesforce_access_token.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def using_salesforce_access_token?
|
20
|
+
@salesforce_access_token != nil
|
12
21
|
end
|
13
|
-
|
22
|
+
|
14
23
|
def reauthenticate
|
24
|
+
if using_salesforce_access_token?
|
25
|
+
raise 'Reauthentication not available when using Salesforce access token. See https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/oauth_refresh_token_flow.htm for more information.'
|
26
|
+
end
|
27
|
+
|
28
|
+
warn '[DEPRECATION] Use Salesforce OAuth to refresh the Salesforce access token. See https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/oauth_refresh_token_flow.htm for more information.'
|
15
29
|
@api_key = nil
|
16
30
|
authenticate
|
17
31
|
end
|
18
32
|
|
19
33
|
private
|
20
34
|
|
21
|
-
def update_version
|
22
|
-
if version.is_a? Array
|
23
|
-
version = version.last
|
24
|
-
end
|
35
|
+
def update_version(version)
|
36
|
+
version = version.last if version.is_a? Array
|
25
37
|
@version = version if version.to_i > 3
|
26
38
|
end
|
27
|
-
|
28
39
|
end
|
29
40
|
end
|
data/lib/pardot/client.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Pardot
|
2
|
-
|
3
2
|
class Client
|
4
|
-
|
5
3
|
include HTTParty
|
6
4
|
base_uri 'https://pi.pardot.com'
|
7
5
|
format :xml
|
@@ -9,6 +7,7 @@ module Pardot
|
|
9
7
|
include Authentication
|
10
8
|
include Http
|
11
9
|
|
10
|
+
include Objects::CustomFields
|
12
11
|
include Objects::Emails
|
13
12
|
include Objects::Lists
|
14
13
|
include Objects::ListMemberships
|
@@ -20,16 +19,29 @@ module Pardot
|
|
20
19
|
include Objects::Visits
|
21
20
|
include Objects::VisitorActivities
|
22
21
|
|
23
|
-
attr_accessor :email, :password, :user_key, :api_key, :version, :format
|
22
|
+
attr_accessor :email, :password, :user_key, :api_key, :version, :salesforce_access_token, :business_unit_id, :format
|
23
|
+
|
24
|
+
# @deprecated Arguments email, password and user_key are deprecated. Use salesforce_access_token with Salesforce OAuth.
|
25
|
+
def initialize(email = nil, password = nil, user_key = nil, version = 3, salesforce_access_token = nil, business_unit_id = nil)
|
26
|
+
unless email.nil? || password.nil? || user_key.nil?
|
27
|
+
warn '[DEPRECATION] Use of username and password authentication is deprecated in favor of Salesforce OAuth. See https://developer.pardot.com/kb/authentication/ for more information.'
|
28
|
+
end
|
29
|
+
|
30
|
+
if !salesforce_access_token.nil? && business_unit_id.nil?
|
31
|
+
raise 'business_unit_id required when using Salesforce access_token'
|
32
|
+
end
|
33
|
+
if !business_unit_id.nil? && (!business_unit_id.start_with?('0Uv') || business_unit_id.length != 18)
|
34
|
+
raise "Invalid business_unit_id value. Expected ID to start with '0Uv' and be length of 18 characters."
|
35
|
+
end
|
24
36
|
|
25
|
-
def initialize email, password, user_key, version = 3
|
26
37
|
@email = email
|
27
38
|
@password = password
|
28
39
|
@user_key = user_key
|
29
40
|
@version = version
|
41
|
+
@salesforce_access_token = salesforce_access_token
|
42
|
+
@business_unit_id = business_unit_id
|
30
43
|
|
31
|
-
@format =
|
44
|
+
@format = 'simple'
|
32
45
|
end
|
33
|
-
|
34
46
|
end
|
35
47
|
end
|
data/lib/pardot/error.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
module Pardot
|
2
2
|
class Error < StandardError; end
|
3
|
+
|
3
4
|
class NetError < Error; end
|
5
|
+
|
4
6
|
class ExpiredApiKeyError < Error; end
|
5
7
|
|
8
|
+
class AccessTokenExpiredError < Error; end
|
9
|
+
|
6
10
|
class ResponseError < Error
|
7
11
|
def initialize(res)
|
8
12
|
@res = res
|
9
13
|
end
|
10
14
|
|
11
15
|
def to_s
|
12
|
-
@res[
|
16
|
+
@res['__content__']
|
13
17
|
end
|
14
18
|
|
15
19
|
def code
|
16
|
-
@res[
|
20
|
+
@res['code'].to_i
|
17
21
|
end
|
18
22
|
|
19
23
|
def inspect
|
data/lib/pardot/http.rb
CHANGED
@@ -1,70 +1,80 @@
|
|
1
1
|
module Pardot
|
2
2
|
module Http
|
3
|
-
|
4
|
-
def get object, path, params = {}, num_retries = 0
|
3
|
+
def get(object, path, params = {}, num_retries = 0)
|
5
4
|
smooth_params object, params
|
6
5
|
full_path = fullpath object, path
|
7
|
-
|
8
|
-
|
6
|
+
headers = create_auth_header object
|
7
|
+
check_response self.class.get(full_path, query: params, headers: headers)
|
9
8
|
rescue Pardot::ExpiredApiKeyError => e
|
10
9
|
handle_expired_api_key :get, object, path, params, num_retries, e
|
11
|
-
|
12
10
|
rescue SocketError, Interrupt, EOFError, SystemCallError, Timeout::Error, MultiXml::ParseError => e
|
13
|
-
raise Pardot::NetError
|
11
|
+
raise Pardot::NetError, e
|
14
12
|
end
|
15
|
-
|
16
|
-
def post
|
13
|
+
|
14
|
+
def post(object, path, params = {}, num_retries = 0, bodyParams = {})
|
17
15
|
smooth_params object, params
|
18
16
|
full_path = fullpath object, path
|
19
|
-
|
20
|
-
|
17
|
+
headers = create_auth_header object
|
18
|
+
check_response self.class.post(full_path, query: params, body: bodyParams, headers: headers)
|
21
19
|
rescue Pardot::ExpiredApiKeyError => e
|
22
20
|
handle_expired_api_key :post, object, path, params, num_retries, e
|
23
|
-
|
24
21
|
rescue SocketError, Interrupt, EOFError, SystemCallError, Timeout::Error, MultiXml::ParseError => e
|
25
|
-
raise Pardot::NetError
|
22
|
+
raise Pardot::NetError, e
|
26
23
|
end
|
27
|
-
|
24
|
+
|
28
25
|
protected
|
29
|
-
|
30
|
-
|
26
|
+
|
27
|
+
# @deprecated With Salesforce OAuth, this method will never be invoked.
|
28
|
+
def handle_expired_api_key(method, object, path, params, num_retries, e)
|
31
29
|
raise e unless num_retries == 0
|
32
|
-
|
30
|
+
|
33
31
|
reauthenticate
|
34
|
-
|
32
|
+
|
35
33
|
send(method, object, path, params, 1)
|
36
34
|
end
|
37
|
-
|
38
|
-
def smooth_params
|
39
|
-
return if object ==
|
40
|
-
|
35
|
+
|
36
|
+
def smooth_params(object, params)
|
37
|
+
return if object == 'login'
|
38
|
+
|
41
39
|
authenticate unless authenticated?
|
42
|
-
params.merge! :
|
40
|
+
params.merge! format: @format
|
43
41
|
end
|
44
|
-
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
42
|
+
|
43
|
+
def create_auth_header(object)
|
44
|
+
return if object == 'login'
|
45
|
+
|
46
|
+
if using_salesforce_access_token?
|
47
|
+
{
|
48
|
+
:Authorization => "Bearer #{@salesforce_access_token}",
|
49
|
+
'Pardot-Business-Unit-Id' => @business_unit_id
|
50
|
+
}
|
51
|
+
else
|
52
|
+
{ Authorization: "Pardot api_key=#{@api_key}, user_key=#{@user_key}" }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def check_response(http_response)
|
57
|
+
rsp = http_response['rsp']
|
58
|
+
|
59
|
+
error = rsp['err'] if rsp
|
60
|
+
error ||= "Unknown Failure: #{rsp.inspect}" if rsp && rsp['stat'] == 'fail'
|
50
61
|
content = error['__content__'] if error.is_a?(Hash)
|
51
|
-
|
52
|
-
if [error, content].
|
53
|
-
raise
|
62
|
+
|
63
|
+
if [error, content].grep(/access_token is invalid/).any? && using_salesforce_access_token?
|
64
|
+
raise AccessTokenExpiredError,
|
65
|
+
'Access token is invalid. Use Salesforce OAuth to refresh the existing Salesforce access token or to retrieve a new token. See https://developer.salesforce.com/docs/atlas.en-us.mobile_sdk.meta/mobile_sdk/oauth_refresh_token_flow.htm for more information.'
|
54
66
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
67
|
+
raise ExpiredApiKeyError, @api_key if [error, content].include?('Invalid API key or user key') && @api_key
|
68
|
+
|
69
|
+
raise ResponseError, error if error
|
70
|
+
|
58
71
|
rsp
|
59
72
|
end
|
60
|
-
|
61
|
-
def fullpath
|
62
|
-
full = File.join(
|
63
|
-
unless path.nil?
|
64
|
-
full = File.join(full, path)
|
65
|
-
end
|
73
|
+
|
74
|
+
def fullpath(object, path)
|
75
|
+
full = File.join('/api', object, 'version', @version.to_s)
|
76
|
+
full = File.join(full, path) unless path.nil?
|
66
77
|
full
|
67
78
|
end
|
68
|
-
|
69
79
|
end
|
70
80
|
end
|