marketo_api 0.0.7.pre.alpha
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/.codeclimate.yml +2 -0
- data/.gitignore +24 -0
- data/.rubocop.yml +57 -0
- data/.travis.yml +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Guardfile +13 -0
- data/LICENSE +22 -0
- data/README.md +75 -0
- data/Rakefile +6 -0
- data/bin/_guard-core +17 -0
- data/bin/console +12 -0
- data/bin/guard +17 -0
- data/bin/rake +17 -0
- data/bin/rspec +17 -0
- data/bin/setup +6 -0
- data/exe/.keep +0 -0
- data/lib/marketo_api.rb +45 -0
- data/lib/marketo_api/abstract_client.rb +15 -0
- data/lib/marketo_api/api/activities.rb +64 -0
- data/lib/marketo_api/api/base.rb +63 -0
- data/lib/marketo_api/api/campaigns.rb +70 -0
- data/lib/marketo_api/api/leads.rb +86 -0
- data/lib/marketo_api/api/sales.rb +19 -0
- data/lib/marketo_api/api/stats.rb +54 -0
- data/lib/marketo_api/client.rb +8 -0
- data/lib/marketo_api/concerns/authentication.rb +20 -0
- data/lib/marketo_api/concerns/base.rb +49 -0
- data/lib/marketo_api/concerns/caching.rb +24 -0
- data/lib/marketo_api/concerns/connection.rb +75 -0
- data/lib/marketo_api/concerns/verbs.rb +60 -0
- data/lib/marketo_api/config.rb +131 -0
- data/lib/marketo_api/middleware.rb +27 -0
- data/lib/marketo_api/middleware/authentication.rb +64 -0
- data/lib/marketo_api/middleware/authentication/token.rb +12 -0
- data/lib/marketo_api/middleware/authorization.rb +16 -0
- data/lib/marketo_api/middleware/caching.rb +26 -0
- data/lib/marketo_api/middleware/logger.rb +40 -0
- data/lib/marketo_api/middleware/raise_error.rb +47 -0
- data/lib/marketo_api/version.rb +3 -0
- data/marketo_api.gemspec +37 -0
- metadata +269 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
module MarketoApi
|
2
|
+
class AbstractClient
|
3
|
+
include MarketoApi::Concerns::Base
|
4
|
+
include MarketoApi::Concerns::Connection
|
5
|
+
include MarketoApi::Concerns::Authentication
|
6
|
+
include MarketoApi::Concerns::Caching
|
7
|
+
|
8
|
+
include MarketoApi::API::Base
|
9
|
+
include MarketoApi::API::Stats
|
10
|
+
include MarketoApi::API::Activities
|
11
|
+
include MarketoApi::API::Leads
|
12
|
+
include MarketoApi::API::Sales
|
13
|
+
include MarketoApi::API::Campaigns
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module MarketoApi
|
4
|
+
module API
|
5
|
+
module Activities
|
6
|
+
include Base
|
7
|
+
|
8
|
+
# Public: Returns a detailed describe result for the specified activities
|
9
|
+
#
|
10
|
+
# Example
|
11
|
+
# # get the describe for the Activities object
|
12
|
+
# client.activities_describe
|
13
|
+
# # => { ... }
|
14
|
+
#
|
15
|
+
# Returns the Hash representation of the describe call.
|
16
|
+
def activities_describe
|
17
|
+
api_get('activities/types.json')
|
18
|
+
end
|
19
|
+
|
20
|
+
def paging_token(start_time)
|
21
|
+
# FIXME: (MT) Need to make sure `start_time` is a `Time` obj
|
22
|
+
if start_time
|
23
|
+
mod_time = start_time.iso8601
|
24
|
+
else
|
25
|
+
mod_time = Time.now.iso8601
|
26
|
+
end
|
27
|
+
|
28
|
+
api_get("activities/pagingtoken.json?sinceDatetime=#{mod_time}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_next_page_token(path, token)
|
32
|
+
path = "#{path}&nextPageToken=#{token}" if token
|
33
|
+
path
|
34
|
+
end
|
35
|
+
|
36
|
+
def add_activity_type_ids(type_ids)
|
37
|
+
ids = format_filter_values(type_ids)
|
38
|
+
if ids
|
39
|
+
"activityTypeIds=#{ids}"
|
40
|
+
else
|
41
|
+
""
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# FIXME: (MT) Refactor this
|
46
|
+
def activities_by_lead_ids(lead_ids, type_ids, next_page_token=nil)
|
47
|
+
# FIXME: (MT) Raise an error when lead_ids is empty
|
48
|
+
path = "activities.json"
|
49
|
+
path << "?leadIds=#{format_filter_values(lead_ids)}" if lead_ids
|
50
|
+
path << "&#{add_activity_type_ids(type_ids)}" if type_ids
|
51
|
+
api_get(add_next_page_token(path, next_page_token))
|
52
|
+
end
|
53
|
+
|
54
|
+
# FIXME: (MT) Refactor this
|
55
|
+
def activities_by_type_id(type_ids, next_page_token=nil)
|
56
|
+
# FIXME: (MT) Rename method to support plural (type_ids)
|
57
|
+
# FIXME: (MT) Raise an error when type_ids is empty
|
58
|
+
path = "activities.json"
|
59
|
+
path << "?#{add_activity_type_ids(type_ids)}" if type_ids
|
60
|
+
api_get(add_next_page_token(path, next_page_token))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'marketo_api/concerns/verbs'
|
3
|
+
|
4
|
+
module MarketoApi
|
5
|
+
module API
|
6
|
+
module Base
|
7
|
+
extend MarketoApi::Concerns::Verbs
|
8
|
+
|
9
|
+
# Public: Helper methods for performing arbitrary actions against the API using
|
10
|
+
# various HTTP verbs.
|
11
|
+
#
|
12
|
+
# Examples
|
13
|
+
#
|
14
|
+
# # Perform a get request
|
15
|
+
# client.get '/rest/v1/leads'
|
16
|
+
# client.api_get 'leads'
|
17
|
+
#
|
18
|
+
# Returns the Faraday::Response.
|
19
|
+
define_verbs :get, :post, :put, :delete, :patch, :head
|
20
|
+
|
21
|
+
# TODO: (MT) Move this to a helper
|
22
|
+
def format_filter_values(filter_values)
|
23
|
+
filter_values = filter_values.join(',') if filter_values.is_a?(Array)
|
24
|
+
filter_values
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Internal: Returns a path to an api endpoint
|
30
|
+
#
|
31
|
+
# Examples
|
32
|
+
#
|
33
|
+
# api_path('leads')
|
34
|
+
# # => '/rest/v1/leads'
|
35
|
+
def api_path(path)
|
36
|
+
"/rest/v#{options[:api_version]}/#{path}"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Internal: Ensures that the `api_version` set for the Marketo client is at least
|
40
|
+
# the provided version before performing a particular action
|
41
|
+
def version_guard(version)
|
42
|
+
if version.to_f <= options[:api_version].to_f
|
43
|
+
yield
|
44
|
+
else
|
45
|
+
raise APIVersionError, "You must set an `api_version` of at least #{version} "
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def extract_case_insensitive_string_or_symbol_key_from_hash!(hash, key)
|
50
|
+
value = hash.delete(key.to_sym)
|
51
|
+
value ||= hash.delete(key.to_s)
|
52
|
+
value ||= hash.delete(key.to_s.downcase)
|
53
|
+
value ||= hash.delete(key.to_s.downcase.to_sym)
|
54
|
+
value
|
55
|
+
end
|
56
|
+
|
57
|
+
# Internal: Errors that should be rescued from in non-bang methods
|
58
|
+
def exceptions
|
59
|
+
[Faraday::Error::ClientError]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module MarketoApi
|
2
|
+
module API
|
3
|
+
module Campaigns
|
4
|
+
include Base
|
5
|
+
|
6
|
+
# Public: Executes specific entity request and returns the result.
|
7
|
+
#
|
8
|
+
# Example
|
9
|
+
# # Find the specific campaign
|
10
|
+
# client.campaign_by_id(3711)
|
11
|
+
# # => {
|
12
|
+
# "requestId": "717#15f4b51ed20"
|
13
|
+
# "success": "true"
|
14
|
+
# "result": [
|
15
|
+
# {
|
16
|
+
# "id": "3711"
|
17
|
+
# "name": "John Clark - Smart Campaign"
|
18
|
+
# "type": "trigger"
|
19
|
+
# "programName": "John Clark - Request Campaign.John Clark - Email Program"
|
20
|
+
# "programId": "1073"
|
21
|
+
# "workspaceName": "Default"
|
22
|
+
# "createdAt": "'2017-02-13T19:58:56Z'"
|
23
|
+
# "updatedAt": "'2017-02-13T20:06:29Z'"
|
24
|
+
# "active": "true"
|
25
|
+
# }
|
26
|
+
# ]
|
27
|
+
# }
|
28
|
+
def campaign_by_id(id)
|
29
|
+
api_get("campaigns/#{id}.json")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Public: Returns a list of campaign records.
|
33
|
+
# Required Permissions: Read-Only Campaigns, Read-Write Campaigns
|
34
|
+
#
|
35
|
+
# Example
|
36
|
+
# # Find the specific campaign
|
37
|
+
# client.campaigns_by_workspace(true)
|
38
|
+
# # => {
|
39
|
+
# "requestId": "cab#15f4b36d1ca"
|
40
|
+
# "success": "true"
|
41
|
+
# "result": [
|
42
|
+
# {
|
43
|
+
# "id": "3711"
|
44
|
+
# "name": "John Clark - Smart Campaign"
|
45
|
+
# "type": "trigger"
|
46
|
+
# "programName": "John Clark - Request Campaign.John Clark - Email Program"
|
47
|
+
# "programId": "1073"
|
48
|
+
# "workspaceName": "Default"
|
49
|
+
# "createdAt": "'2017-02-13T19:58:56Z'"
|
50
|
+
# "updatedAt": "'2017-02-13T20:06:29Z'"
|
51
|
+
# "active": "true"
|
52
|
+
# }
|
53
|
+
# ]
|
54
|
+
# }
|
55
|
+
#
|
56
|
+
# If no records are found, the following is returned:
|
57
|
+
# # => {
|
58
|
+
# "requestId": "13cc0#15f4b5134af",
|
59
|
+
# "result": [],
|
60
|
+
# "success": true
|
61
|
+
# }
|
62
|
+
#
|
63
|
+
def campaigns_by_workspace(is_triggerable, workspace_name = 'Default')
|
64
|
+
triggerable_param = "isTriggerable=#{is_triggerable ? 1 : 0}"
|
65
|
+
workspace_param = "workspaceName=#{workspace_name}"
|
66
|
+
api_get("campaigns.json?#{triggerable_param}&#{workspace_param}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module MarketoApi
|
2
|
+
module API
|
3
|
+
module Leads
|
4
|
+
include Base
|
5
|
+
|
6
|
+
# Public: Returns a detailed describe result for the specified leads
|
7
|
+
#
|
8
|
+
# Example
|
9
|
+
# # get the describe for the Leads object
|
10
|
+
# client.leads_describe
|
11
|
+
# # => { ... }
|
12
|
+
#
|
13
|
+
# Returns the Hash representation of the describe call.
|
14
|
+
def leads_describe
|
15
|
+
api_get('leads/describe.json')
|
16
|
+
end
|
17
|
+
|
18
|
+
# Public: Executes specific entity request and returns the result.
|
19
|
+
#
|
20
|
+
# Example
|
21
|
+
# # Find the specific lead
|
22
|
+
# client.leads_by_id(318581)
|
23
|
+
# # => {
|
24
|
+
# "requestId": "10226#14d3049e51b",
|
25
|
+
# "success": true,
|
26
|
+
# "result": [
|
27
|
+
# {
|
28
|
+
# "id": 318581,
|
29
|
+
# "updatedAt":"2015-05-07T11:47:30-08:00"
|
30
|
+
# "lastName": "Doe",
|
31
|
+
# "email": "jdoe@marketo.com",
|
32
|
+
# "createdAt": "2015-05-01T16:47:30-08:00",
|
33
|
+
# "firstName": "John"
|
34
|
+
# }
|
35
|
+
# ]
|
36
|
+
# }
|
37
|
+
#
|
38
|
+
def leads_by_id(id)
|
39
|
+
api_get("leads/#{id}.json")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Public: Executes specific filterType with filterValues request
|
43
|
+
# and returns the result.
|
44
|
+
#
|
45
|
+
# Example
|
46
|
+
# # Find the specific lead
|
47
|
+
# client.leads_by_filter_type('email',
|
48
|
+
# ['abe@usa.gov', 'george@usa.gov'])
|
49
|
+
# # => {
|
50
|
+
# "requestId": "12951#15699db5c97",
|
51
|
+
# "result": [
|
52
|
+
# {
|
53
|
+
# "id": 318581,
|
54
|
+
# "updatedAt": "2016-05-17T22:11:45Z",
|
55
|
+
# "lastName": "Lincoln",
|
56
|
+
# "email": "abe@usa.gov",
|
57
|
+
# "createdAt": "2015-03-17T00:18:40Z",
|
58
|
+
# "firstName": "Abraham"
|
59
|
+
# },
|
60
|
+
# {
|
61
|
+
# "id": 318592,
|
62
|
+
# "updatedAt": "2016-05-17T22:20:51Z",
|
63
|
+
# "lastName": "Washington",
|
64
|
+
# "email": "george@usa.gov",
|
65
|
+
# "createdAt": "2015-04-06T16:29:21Z",
|
66
|
+
# "firstName": "George"
|
67
|
+
# }
|
68
|
+
# ],
|
69
|
+
# "success": true
|
70
|
+
# }
|
71
|
+
#
|
72
|
+
# If no records are found, the following is returned:
|
73
|
+
# # => {
|
74
|
+
# "requestId": "177a1#1578b643357",
|
75
|
+
# "result": [],
|
76
|
+
# "success": true
|
77
|
+
# }
|
78
|
+
#
|
79
|
+
def leads_by_filter_type(filter_type, filter_values)
|
80
|
+
type_param = "filterType=#{filter_type}"
|
81
|
+
values_param = "filterValues=#{format_filter_values(filter_values)}"
|
82
|
+
api_get("leads.json?#{type_param}&#{values_param}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MarketoApi
|
2
|
+
module API
|
3
|
+
module Sales
|
4
|
+
include Base
|
5
|
+
|
6
|
+
def best_bets(attrs)
|
7
|
+
api_get('sales/bestbets.json', attrs)
|
8
|
+
end
|
9
|
+
|
10
|
+
def interesting_moments(attrs)
|
11
|
+
api_get('sales/interestingmoments.json', attrs)
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_activity!(attrs)
|
15
|
+
api_post('sales/activities.json', attrs)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module MarketoApi
|
2
|
+
module API
|
3
|
+
module Stats
|
4
|
+
include Base
|
5
|
+
|
6
|
+
# Public: Returns the daily usage of API requests
|
7
|
+
#
|
8
|
+
# Example
|
9
|
+
# client.daily_usage
|
10
|
+
# # => { ... }
|
11
|
+
#
|
12
|
+
# Returns the Hash representation of the usage call.
|
13
|
+
def daily_usage
|
14
|
+
api_get('stats/usage.json')
|
15
|
+
end
|
16
|
+
|
17
|
+
# Public: Returns the count of each error type encountered
|
18
|
+
# in the current day
|
19
|
+
#
|
20
|
+
# Example
|
21
|
+
# client.daily_errors
|
22
|
+
# # => { ... }
|
23
|
+
#
|
24
|
+
# Returns the Hash representation of the usage call.
|
25
|
+
def daily_errors
|
26
|
+
api_get('stats/errors.json')
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Returns a list of API users and the number of calls
|
30
|
+
# they have consumed in the past 7 days.
|
31
|
+
#
|
32
|
+
# Example
|
33
|
+
# client.weekly_usage
|
34
|
+
# # => { ... }
|
35
|
+
#
|
36
|
+
# Returns the Hash representation of the usage call.
|
37
|
+
def weekly_usage
|
38
|
+
api_get('stats/usage/last7days.json')
|
39
|
+
end
|
40
|
+
|
41
|
+
# Public: Returns a list of API users and a count of each error type
|
42
|
+
# they have encountered in the past 7 days
|
43
|
+
#
|
44
|
+
# Example
|
45
|
+
# client.weekly_errors
|
46
|
+
# # => { ... }
|
47
|
+
#
|
48
|
+
# Returns the Hash representation of the usage call.
|
49
|
+
def weekly_errors
|
50
|
+
api_get('stats/errors/last7days.json')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module MarketoApi
|
2
|
+
module Concerns
|
3
|
+
module Authentication
|
4
|
+
# Public: Force an authentication
|
5
|
+
def authenticate!
|
6
|
+
unless authentication_middleware
|
7
|
+
fail AuthenticationError.new('No authentication middleware present')
|
8
|
+
end
|
9
|
+
|
10
|
+
middleware = authentication_middleware.new nil, self, options
|
11
|
+
middleware.authenticate!
|
12
|
+
end
|
13
|
+
|
14
|
+
# Internal: Determines what middleware will be used based on the options provided
|
15
|
+
def authentication_middleware
|
16
|
+
MarketoApi::Middleware::Authentication::Token
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module MarketoApi
|
2
|
+
module Concerns
|
3
|
+
module Base
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
# Public: Creates a new client instance
|
7
|
+
#
|
8
|
+
# opts - A hash of options to be passed in (default: {}).
|
9
|
+
# :oauth_token - The String oauth access token to authenticate
|
10
|
+
# API calls (required unless password
|
11
|
+
# authentication is used).
|
12
|
+
# :instance_url - The String base url for all api requests
|
13
|
+
# (required if oauth authentication is used).
|
14
|
+
#
|
15
|
+
# :client_id - The oauth client id to use. Needed for both
|
16
|
+
# password and oauth authentication
|
17
|
+
# :client_secret - The oauth client secret to use.
|
18
|
+
#
|
19
|
+
# :api_version - The String REST api version to use
|
20
|
+
# (default: '24.0')
|
21
|
+
#
|
22
|
+
# :timeout - Faraday connection request read/open timeout.
|
23
|
+
# (default: nil).
|
24
|
+
#
|
25
|
+
# :request_headers - A hash containing custom headers that will be
|
26
|
+
# appended to each request
|
27
|
+
|
28
|
+
def initialize(opts = {})
|
29
|
+
fail ArgumentError.new('Please specify a hash of options') unless opts.is_a?(Hash)
|
30
|
+
|
31
|
+
@options = Hash[MarketoApi.configuration.options.map do |option|
|
32
|
+
[option, MarketoApi.configuration.send(option)]
|
33
|
+
end]
|
34
|
+
|
35
|
+
@options.merge! opts
|
36
|
+
yield builder if block_given?
|
37
|
+
end
|
38
|
+
|
39
|
+
def instance_url
|
40
|
+
authenticate! unless options[:instance_url]
|
41
|
+
options[:instance_url]
|
42
|
+
end
|
43
|
+
|
44
|
+
def inspect
|
45
|
+
"#<#{self.class} @options=#{@options.inspect}>"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|