marketo_api 0.0.7.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- 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
|