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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +2 -0
  3. data/.gitignore +24 -0
  4. data/.rubocop.yml +57 -0
  5. data/.travis.yml +10 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +4 -0
  8. data/Guardfile +13 -0
  9. data/LICENSE +22 -0
  10. data/README.md +75 -0
  11. data/Rakefile +6 -0
  12. data/bin/_guard-core +17 -0
  13. data/bin/console +12 -0
  14. data/bin/guard +17 -0
  15. data/bin/rake +17 -0
  16. data/bin/rspec +17 -0
  17. data/bin/setup +6 -0
  18. data/exe/.keep +0 -0
  19. data/lib/marketo_api.rb +45 -0
  20. data/lib/marketo_api/abstract_client.rb +15 -0
  21. data/lib/marketo_api/api/activities.rb +64 -0
  22. data/lib/marketo_api/api/base.rb +63 -0
  23. data/lib/marketo_api/api/campaigns.rb +70 -0
  24. data/lib/marketo_api/api/leads.rb +86 -0
  25. data/lib/marketo_api/api/sales.rb +19 -0
  26. data/lib/marketo_api/api/stats.rb +54 -0
  27. data/lib/marketo_api/client.rb +8 -0
  28. data/lib/marketo_api/concerns/authentication.rb +20 -0
  29. data/lib/marketo_api/concerns/base.rb +49 -0
  30. data/lib/marketo_api/concerns/caching.rb +24 -0
  31. data/lib/marketo_api/concerns/connection.rb +75 -0
  32. data/lib/marketo_api/concerns/verbs.rb +60 -0
  33. data/lib/marketo_api/config.rb +131 -0
  34. data/lib/marketo_api/middleware.rb +27 -0
  35. data/lib/marketo_api/middleware/authentication.rb +64 -0
  36. data/lib/marketo_api/middleware/authentication/token.rb +12 -0
  37. data/lib/marketo_api/middleware/authorization.rb +16 -0
  38. data/lib/marketo_api/middleware/caching.rb +26 -0
  39. data/lib/marketo_api/middleware/logger.rb +40 -0
  40. data/lib/marketo_api/middleware/raise_error.rb +47 -0
  41. data/lib/marketo_api/version.rb +3 -0
  42. data/marketo_api.gemspec +37 -0
  43. 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,8 @@
1
+ module MarketoApi
2
+ class Client < AbstractClient
3
+ # Public: Returns a url to the resource.
4
+ def url
5
+ "#{instance_url}/rest/"
6
+ end
7
+ end
8
+ 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