gooddata_marketo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +131 -0
  4. data/README.md +207 -0
  5. data/bin/Gemfile +10 -0
  6. data/bin/auth.json +17 -0
  7. data/bin/main.rb +0 -0
  8. data/bin/process.rbx +541 -0
  9. data/examples/all_lead_changes.rb +119 -0
  10. data/examples/all_leads.rb +249 -0
  11. data/examples/lead_changes_to_ads.rb +63 -0
  12. data/gooddata_marketo.gemspec +24 -0
  13. data/gooddata_marketo_gem.zip +0 -0
  14. data/lib/gooddata_marketo.rb +24 -0
  15. data/lib/gooddata_marketo/adapters/rest.rb +287 -0
  16. data/lib/gooddata_marketo/client.rb +373 -0
  17. data/lib/gooddata_marketo/data/activity_types.rb +104 -0
  18. data/lib/gooddata_marketo/data/reserved_sql_keywords.rb +205 -0
  19. data/lib/gooddata_marketo/helpers/s3.rb +141 -0
  20. data/lib/gooddata_marketo/helpers/stringwizard.rb +32 -0
  21. data/lib/gooddata_marketo/helpers/table.rb +323 -0
  22. data/lib/gooddata_marketo/helpers/webdav.rb +118 -0
  23. data/lib/gooddata_marketo/loads.rb +235 -0
  24. data/lib/gooddata_marketo/models/campaigns.rb +57 -0
  25. data/lib/gooddata_marketo/models/channels.rb +30 -0
  26. data/lib/gooddata_marketo/models/child/activity.rb +104 -0
  27. data/lib/gooddata_marketo/models/child/criteria.rb +17 -0
  28. data/lib/gooddata_marketo/models/child/lead.rb +118 -0
  29. data/lib/gooddata_marketo/models/child/mobj.rb +68 -0
  30. data/lib/gooddata_marketo/models/etl.rb +75 -0
  31. data/lib/gooddata_marketo/models/leads.rb +493 -0
  32. data/lib/gooddata_marketo/models/load.rb +17 -0
  33. data/lib/gooddata_marketo/models/mobjects.rb +121 -0
  34. data/lib/gooddata_marketo/models/streams.rb +137 -0
  35. data/lib/gooddata_marketo/models/tags.rb +35 -0
  36. data/lib/gooddata_marketo/models/validate.rb +46 -0
  37. metadata +177 -0
Binary file
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+
3
+ module GoodDataMarketo
4
+ VERSION = "0.0.1"
5
+
6
+ class << self
7
+
8
+ attr_accessor :logging
9
+
10
+ def client(config = {})
11
+ GoodDataMarketo.logging = false
12
+ GoodDataMarketo::Client.new(config)
13
+ end
14
+
15
+ def freeze(*args) # Bloc freeze args.
16
+ args.each(&:freeze).freeze
17
+ end
18
+
19
+ alias :connect :client
20
+
21
+ end
22
+ end
23
+
24
+ require 'gooddata_marketo/client'
@@ -0,0 +1,287 @@
1
+ require 'gooddata_marketo/models/child/lead'
2
+
3
+ require 'rest_client'
4
+ require 'json'
5
+ require 'csv'
6
+
7
+ class GoodDataMarketo::RESTAdapter
8
+
9
+ attr_accessor :token
10
+ attr_accessor :token_timer
11
+
12
+ def initialize config = {}
13
+
14
+ @api_limit = MARKETO_API_LIMIT
15
+ @lead_list_dump = config[:file] || LEAD_LIST_DUMP_CSV || 'marketo_leads_dump.csv'
16
+ @marketo_subdomain = config[:subdomain] || MARKETO_SUBDOMAIN
17
+ @marketo_rest_secret = config[:secret] || config[:user] || MARKETO_REST_SECRET
18
+ @marketo_rest_id = config[:id] || config[:user] || MARKETO_REST_ID
19
+ @marketo_domain = "https://#{@marketo_subdomain}.mktorest.com"
20
+ @webdav = config[:webdav]
21
+ @lead_list_ids = []
22
+ @token = self.get_token unless config[:token]
23
+ @token_uri = "?access_token=#{@token}"
24
+
25
+ # Example endpoint = "/rest/v1/lists.json"
26
+
27
+ end
28
+
29
+ # If token has existed for more than 6000 seconds, refresh it.
30
+ def refresh_token?
31
+ if (@token_timer + 6000) < Time.now
32
+ self.get_token
33
+ true
34
+ else
35
+ false
36
+ end
37
+ end
38
+
39
+ def get url
40
+ @api_limit -= 1
41
+ begin
42
+ puts "#{Time.now} => REST:GET (#{url})" if GoodDataMarketo.logging
43
+ response = RestClient.get url
44
+ rescue Exception => exc
45
+ puts exc if GoodDataMarketo.logging
46
+ puts "#{Time.now} => Possible API Limit reached, last request was ##{@api_limit} of #{MARKETO_API_LIMIT}"
47
+ end
48
+ end
49
+
50
+ def get_lead_lists next_page_token = nil
51
+
52
+ endpoint = "/rest/v1/lists.json"
53
+ url = @marketo_domain + endpoint + @token_uri
54
+
55
+ if next_page_token
56
+ endpoint = "/rest/v1/lists.json"
57
+ url = @marketo_domain + endpoint + @token_uri + "&nextPageToken="+next_page_token
58
+ end
59
+
60
+ response = self.get url
61
+
62
+ json = JSON.parse(response.body, :symbolize_names => true)
63
+
64
+ json[:result].each { |m| @lead_list_ids << m[:id] }
65
+
66
+ next_page_token = json[:nextPageToken]
67
+
68
+ if next_page_token
69
+ self.get_lead_lists next_page_token
70
+ else
71
+ @lead_list_ids
72
+ end
73
+
74
+ end
75
+
76
+ def get_multiple_leads config = {}
77
+
78
+ self.refresh_token?
79
+
80
+ ids = config[:ids] || config[:values] || [28567,30885,32240,37161,40832]
81
+ domain = @marketo_domain
82
+ parameters = "&filterType=id"+"&filterValues="+ids.join(',')
83
+ endpoint= "/rest/v1/leads.json"
84
+ url = domain + endpoint + @token_uri + parameters
85
+
86
+ self.get url
87
+
88
+ end
89
+
90
+ def get_all_leads config = {}
91
+
92
+ self.refresh_token?
93
+
94
+ # Check if we already have a leads list, if so, download it.
95
+ self.load_lists
96
+
97
+ # Check if there was a stream broken while downloading a specific list.
98
+ self.load_last_page
99
+
100
+ # Check if there was a partial ID dump available on WebDAV, if so download it..
101
+ self.load_id_dump
102
+
103
+ @fields = config[:fields] || 'id'
104
+
105
+ # For each of the lead list ids, download their respective leads by id.
106
+ @csv = CSV.open(@lead_list_dump,'a+')
107
+
108
+ lists = @lead_list_ids
109
+
110
+ lists.each do |list|
111
+
112
+ id = @lead_list_ids.shift
113
+
114
+ domain = @marketo_domain
115
+ parameters = "&fields=#{@fields}"
116
+ endpoint= "/rest/v1/list/#{id}/leads.json"
117
+ url = domain + endpoint + @token_uri + parameters
118
+
119
+ # Conditional recursive function ends if nextPageToken is not available in response. Writes results to CSV.
120
+ def rest_lead_stream url, list_id
121
+
122
+ response = self.get url
123
+ json = JSON.parse(response.body, :symbolize_names => true)
124
+ results = json[:result]
125
+
126
+ if results
127
+ results.each { |result| @csv << [result[:id]] }
128
+ @csv.flush
129
+ puts "#{Time.now} => REST:leadList:#{list_id}:Results:#{results.length}" if GoodDataMarketo.logging
130
+ end
131
+
132
+ next_page_token = json[:nextPageToken]
133
+
134
+ # If there is another page, remember it and then attempt the next load.
135
+ if next_page_token
136
+
137
+ self.remember_next_page :token => token, :list => list_id
138
+ domain = @marketo_domain
139
+ parameters = "&fields=#{@fields}"
140
+ endpoint= "/rest/v1/list/#{list_id}/leads.json"
141
+ url = domain + endpoint + @token_uri + parameters + "&nextPageToken=" + next_page_token
142
+ rest_lead_stream url, list_id
143
+
144
+ else
145
+
146
+ # Update the local and remote lead lists
147
+ File.open('lead_list_ids.json','w'){ |f| JSON.dump(@lead_list_ids, f) }
148
+ @webdav.upload('lead_list_ids.json')
149
+
150
+ end
151
+
152
+ end
153
+
154
+ # While on this list, check to see if it failed working on it before and resume where it left off.
155
+ if @next_page_token_list == list
156
+
157
+ puts "#{Time.now} => REST(Resumed):leadList:#{list}:NextPageToken:#{@next_page_token}" if GoodDataMarketo.logging
158
+ domain = @marketo_domain
159
+ parameters = "" #"&fields=#{fields}"
160
+ endpoint= "/rest/v1/list/#{list}/leads.json"
161
+ url = domain + endpoint + @token_uri + parameters + "&nextPageToken=" + @next_page_token
162
+
163
+ rest_lead_stream url, list
164
+
165
+ else
166
+
167
+ rest_lead_stream url, list
168
+
169
+ end
170
+
171
+ end
172
+
173
+ # Remove lists from WebDav & Local, upload Marketo Ids Dump to webdav.
174
+ self.clean
175
+
176
+ # Update the etl controller that an update as occured.
177
+ self.resolve_with_etl_controller
178
+
179
+ end
180
+
181
+ def get_all_lead_ids config = {}
182
+ config[:fields] = 'id'
183
+ self.get_all_leads config
184
+ end
185
+
186
+ def get_all_lead_emails config = {}
187
+ config[:fields] = 'email'
188
+ self.get_all_leads config
189
+ end
190
+
191
+ def load_last_page
192
+
193
+ if @webdav.include? 'lead_list_next_page_token.json'
194
+ next_page_token_json = @webdav.download 'lead_list_next_page_token.json'
195
+ json = JSON.parse(next_page_token_json)
196
+ elsif File.exists? 'lead_list_next_page_token.json'
197
+ json = JSON.parse( IO.read('lead_list_next_page_token.json'))
198
+ else
199
+ json = {}
200
+ end
201
+
202
+ @next_page_token = json[:token]
203
+ @next_page_token_list = json[:list]
204
+
205
+ end
206
+
207
+ def load_id_dump
208
+ # Check if the lists leads have already been dumped. Append to it.
209
+ if @webdav.exists? @lead_list_dump
210
+ file = @webdav.download @lead_list_dump
211
+ puts "#{Time.now} => WEBDAV:ID_DUMP:Load" if GoodDataMarketo.logging
212
+ f = File.open(@lead_list_dump,'w')
213
+ f.write(file)
214
+ end
215
+ end
216
+
217
+ def load_lists
218
+ if @webdav.include? 'lead_list_ids.json'
219
+ lists = @webdav.download 'lead_list_ids.json'
220
+ @lead_list_ids = JSON.parse(lists)
221
+ puts "#{Time.now} => WEBDAV:ListsLoaded:#{@lead_list_ids.length}:lead_list_ids.json" if GoodDataMarketo.logging
222
+ else
223
+ self.get_lead_lists
224
+ end
225
+ end
226
+
227
+ def remember_next_page config = {}
228
+ File.open('lead_list_next_page_token.json','w'){ |f| JSON.dump(config, f) }
229
+ @webdav.upload('lead_list_next_page_token.json')
230
+ end
231
+
232
+ def clean
233
+
234
+ lli = 'lead_list_ids.json'
235
+ llnpt = 'lead_list_next_page_token.json'
236
+
237
+ # Remove list ids from webdav and local
238
+ if @webdav.exists?(lli)
239
+ @webdav.delete(lli)
240
+ end
241
+
242
+ if @webdav.exists?(llnpt)
243
+ @webdav.delete(llnpt)
244
+ end
245
+
246
+ File.delete(lli) if File.exists? lli
247
+ File.delete(llnpt) if File.exists? llnpt
248
+
249
+ # Upload marketo_dump to webdav for backup.
250
+ @webdav.upload(@lead_list_dump)
251
+
252
+ end
253
+
254
+ def get_token
255
+
256
+
257
+ domain = @marketo_domain
258
+ endpoint = "/identity/oauth/token?grant_type=client_credentials"
259
+ url = domain + endpoint + "&client_id=" + @marketo_rest_id + "&client_secret=" + @marketo_rest_secret
260
+ response = self.get url
261
+ results = JSON.parse(response.body)
262
+ access_token = results["access_token"]
263
+ @token_timer = Time.now
264
+ @token = access_token
265
+ access_token
266
+
267
+ end
268
+
269
+ def usage
270
+ domain = @marketo_domain
271
+ endpoint = "/rest/v1/stats/usage.json"
272
+ url = domain + endpoint + @token_uri
273
+
274
+ # Note this is the only rest call which does not use the log so as not to print the keys to log.
275
+ response = RestClient.get url
276
+
277
+ #Parse reponse and return only access token
278
+ results = JSON.parse(response.body)['result']
279
+ end
280
+
281
+ def resolve_with_etl_controller
282
+
283
+ puts 'Complete'
284
+ # Here it would update the log that a full upload as occured.
285
+ end
286
+
287
+ end
@@ -0,0 +1,373 @@
1
+ # encoding: UTF-8
2
+
3
+ begin
4
+ verbose, $VERBOSE = $VERBOSE, nil
5
+
6
+ dependencies = ['aws-sdk -v 1.61.0',
7
+ 'savon -v 2.8.0',
8
+ 'rubyntlm -v 0.3.2',
9
+ 'gooddata -v 0.6.11',
10
+ 'rest-client -v 1.7.2',
11
+ 'pmap -v 1.0.2']
12
+
13
+ puts "#{Time.now} => CheckDependencies: #{dependencies.join(', ')}" if GoodDataMarketo.logging
14
+ dependencies.each do |dep|
15
+ begin
16
+ gem dep.split(' ').first
17
+ rescue LoadError
18
+ puts "Installing dependency #{dep}..."
19
+ system("gem install #{dep}")
20
+ Gem.clear_paths
21
+ next
22
+ end
23
+ end
24
+
25
+ require 'openssl'
26
+ require 'savon'
27
+ require 'json'
28
+ require 'timeout'
29
+ require 'date'
30
+ require 'aws-sdk'
31
+ require 'pmap'
32
+ require 'gooddata'
33
+ require 'gooddata_datawarehouse'
34
+
35
+ require 'gooddata_marketo/loads'
36
+ require 'gooddata_marketo/helpers/stringwizard'
37
+ require 'gooddata_marketo/helpers/table'
38
+ require 'gooddata_marketo/helpers/webdav'
39
+ require 'gooddata_marketo/helpers/s3'
40
+
41
+ require 'gooddata_marketo/models/leads'
42
+ require 'gooddata_marketo/models/validate'
43
+ require 'gooddata_marketo/models/campaigns'
44
+ require 'gooddata_marketo/models/channels'
45
+ require 'gooddata_marketo/models/mobjects'
46
+ require 'gooddata_marketo/models/streams'
47
+ require 'gooddata_marketo/models/tags'
48
+
49
+ require 'gooddata_marketo/adapters/rest'
50
+
51
+ require 'gooddata_marketo/data/activity_types'
52
+ require 'gooddata_marketo/data/reserved_sql_keywords'
53
+
54
+ ensure
55
+ $VERBOSE = verbose
56
+ end
57
+
58
+ class GoodDataMarketo::Client
59
+
60
+ DEFAULT_CONFIG = {
61
+ wsdl: 'http://app.marketo.com/soap/mktows/2_4?WSDL',
62
+ read_timeout: 500,
63
+ open_timeout: 500,
64
+ namespace_identifier: :ns1,
65
+ env_namespace: 'SOAP-ENV',
66
+ namespaces: { 'xmlns:ns1' => 'http://www.marketo.com/mktows/' },
67
+ pretty_print_xml: true,
68
+ api_subdomain: '363-IXI-287',
69
+ api_version: '2_7',
70
+ log: false,
71
+ log_level: :debug
72
+ }
73
+
74
+ attr_accessor :load
75
+ attr_accessor :webdav
76
+ attr_accessor :api_limit
77
+ attr_accessor :activity_types
78
+
79
+ def initialize(config = {})
80
+
81
+ GoodDataMarketo.logging = true if config[:log]
82
+
83
+ @api_limit = config[:api_limit] || MARKETO_API_LIMIT
84
+
85
+ @loads = nil # Default is no jobs will be active.
86
+ @load = nil # No job is currently set.
87
+ @leads = nil
88
+
89
+ config = DEFAULT_CONFIG.merge(config)
90
+
91
+ @api_version = config.delete(:api_version).freeze
92
+ @subdomain = config.delete(:api_subdomain).freeze
93
+ @webdav = config.delete(:webdav)
94
+ @logger = config.delete(:logger)
95
+
96
+ @activity_types = ActivityTypes.new.values
97
+
98
+ user_id = config.delete(:user_id)
99
+ encryption_key = config.delete(:encryption_key)
100
+
101
+ @auth = AuthHeader.new(user_id, encryption_key)
102
+
103
+ @wsdl = "http://app.marketo.com/soap/mktows/#{@api_version}?WSDL".freeze
104
+ @endpoint = "https://#{@subdomain}.mktoapi.com/soap/mktows/#{@api_version}".freeze
105
+
106
+ #Create SOAP Header
107
+ @savon = Savon.client(config.merge(endpoint: @endpoint))
108
+
109
+ if GoodDataMarketo.logging
110
+ puts use = self.usage
111
+ puts "#{Time.now} => Marketo:SOAP/REST:Used of #{MARKETO_API_LIMIT}"
112
+
113
+ end
114
+
115
+ end
116
+
117
+ def test_rest
118
+ puts "#{Time.now} => SETUP: Connected to Marketo REST API:#{@subdomain}" if GoodDataMarketo.logging
119
+ begin
120
+ self.usage
121
+ true
122
+ rescue
123
+ false
124
+ end
125
+ end
126
+
127
+ def test_soap
128
+ puts "#{Time.now} => SETUP: Connected to Marketo SOAP API:#{@subdomain}" if GoodDataMarketo.logging
129
+ begin
130
+ self.leads.get_by_email('test@test.com')
131
+ true
132
+ rescue
133
+ false
134
+ end
135
+ end
136
+
137
+ def configuration
138
+ DEFAULT_CONFIG
139
+ end
140
+
141
+ def call(web_method, params, config = {}) #:nodoc:
142
+ @api_limit -= 1
143
+ @params = params
144
+ @timeouts = 0
145
+ @error = nil
146
+
147
+ # If the time limit is up, sect the process to wait
148
+ if @api_limit < 1
149
+
150
+ now = DateTime.now.utc
151
+ cst = now.in_time_zone('Central Time (US & Canada)')
152
+ delay = (24 - cst.hours) * 2
153
+ delay = 1 if delay == 0
154
+
155
+ sleep (delay * 60 * 60)
156
+ puts "#{Time.now} => API_LIMIT:Sleeping: #{delay}"
157
+
158
+ end
159
+
160
+ begin
161
+
162
+ def timed_call web_method, params, config = {}
163
+
164
+ puts "#{Time.now} => API Limit: #{@api_limit}" if GoodDataMarketo.logging
165
+ puts "#{Time.now} => Call: #{web_method}: #{@params.to_s}" if GoodDataMarketo.logging
166
+
167
+ Timeout.timeout(config[:timeout] || 4999) do
168
+
169
+ response = @savon.call(
170
+ web_method,
171
+ message: params,
172
+ soap_header: { 'ns1:AuthenticationHeader' => @auth.signature }
173
+ ).to_hash
174
+
175
+ # Add control flow to the root call because Marketo API changes for structure for just getLeadActivities
176
+ if response[:success_get_lead_activity]
177
+ response[:success_get_lead_activity][:lead_activity_list]
178
+ else
179
+ response[response.keys.first][:result]
180
+ end
181
+
182
+ end
183
+
184
+ end
185
+
186
+ timed_call web_method, @params, config
187
+
188
+ rescue Timeout::Error => e
189
+ @timeouts += 1
190
+
191
+ forward_days = config[:forward_days] || 30
192
+
193
+ def move_forward_30_days original_time, days
194
+ smart_time = Date.parse(original_time) + days
195
+ Time.parse(smart_time.to_s).to_s
196
+ end
197
+
198
+ if @params[:start_position]
199
+
200
+ last_created_at = @params[:start_position][:last_created_at]
201
+ latest_created_at = @params[:start_position][:latest_created_at]
202
+ oldest_created_at = @params[:start_position][:oldest_created_at]
203
+ last_updated_at = @params[:start_position][:last_updated_at]
204
+
205
+ if oldest_created_at
206
+ new_time = move_forward_30_days(oldest_created_at, forward_days)
207
+ @params[:start_position][:oldest_created_at] = new_time
208
+ elsif last_created_at
209
+ new_time = move_forward_30_days(last_created_at, forward_days)
210
+ @params[:start_position][:last_created_at] = new_time
211
+ elsif latest_created_at
212
+ new_time = move_forward_30_days(latest_created_at, forward_days)
213
+ @params[:start_position][:latest_created_at] = new_time
214
+ elsif last_updated_at
215
+ new_time = move_forward_30_days(last_updated_at, forward_days)
216
+ @params[:start_position][:last_updated_at] = new_time
217
+ else
218
+ exit
219
+ end
220
+
221
+ puts "#{Time.now} => #{e}:Retrying requested date +#{forward_days} days:attempts:#{@timeouts}/12" if GoodDataMarketo.logging
222
+ retry unless @timeouts > 12
223
+
224
+ else
225
+ exit
226
+ end
227
+
228
+ end
229
+
230
+ rescue Exception => e
231
+ puts @error = e
232
+ @logger.log(e) if @logger
233
+ nil
234
+ end
235
+
236
+ def died(json = nil)
237
+
238
+ if json
239
+ file = File.open('marketo_connector_log.json','wb')
240
+ file.write(json.to_json)
241
+ exit
242
+ else
243
+ json = File.open('marketo_connector_log.json', 'r')
244
+ json.to_h
245
+ end
246
+
247
+ end
248
+
249
+ def stream(web_method, params, config = {})
250
+
251
+ # If the stream is part of a load.
252
+
253
+ if self.load
254
+ "#{Time.now} => Load:#{self.load.json[:type]}:#{self.load.json[:method]}" if GoodDataMarketo.logging
255
+ end
256
+
257
+ puts "#{Time.now} => Stream: #{web_method}: #{params.to_s}" if GoodDataMarketo.logging
258
+
259
+ safe = config[:safe] || true
260
+ @timeouts = 0
261
+
262
+ def safe_stream web_method, params, config
263
+ begin
264
+ #Timeout.timeout(config[:timeout] || 18000) do
265
+ GoodDataMarketo::Stream.new web_method, params, :client => self
266
+ #end
267
+ rescue Timeout::Error => e
268
+ @timeouts += 1
269
+ puts e if GoodDataMarketo.logging
270
+ params[:timeouts] = @timeouts
271
+ self.load.log('TIMEOUT') if self.load
272
+ self.died params
273
+ end
274
+
275
+ end
276
+
277
+ if safe
278
+ safe_stream web_method, params, config
279
+ else
280
+ GoodDataMarketo::Stream.new web_method, params, :client => self
281
+ end
282
+
283
+
284
+ end
285
+
286
+ class AuthHeader #:nodoc:
287
+ DIGEST = OpenSSL::Digest.new('sha1')
288
+ private_constant :DIGEST
289
+
290
+ def initialize(user_id, encryption_key)
291
+ if user_id.nil? || encryption_key.nil?
292
+ raise ArgumentError, ":user_id and :encryption_key required"
293
+ end
294
+
295
+ @user_id = user_id
296
+ @encryption_key = encryption_key
297
+ end
298
+
299
+ attr_reader :user_id
300
+
301
+ # Compute the HMAC signature and return it.
302
+ def signature
303
+ time = Time.now
304
+ {
305
+ mktowsUserId: user_id,
306
+ requestTimestamp: time.to_s,
307
+ requestSignature: hmac(time),
308
+ }
309
+ end
310
+
311
+ private
312
+ def hmac(time)
313
+ OpenSSL::HMAC.hexdigest(
314
+ DIGEST,
315
+ @encryption_key,
316
+ "#{time}#{user_id}"
317
+ )
318
+ end
319
+
320
+ end
321
+
322
+ private_constant :AuthHeader
323
+
324
+ def rest
325
+ GoodDataMarketo::RESTAdapter.new :webdav => @webdav
326
+ end
327
+
328
+ def get_all_leads config = {}
329
+ rest = GoodDataMarketo::RESTAdapter.new :webdav => @webdav
330
+ rest.get_all_leads
331
+ end
332
+
333
+ alias :write_all_lead_ids_to_csv :get_all_leads
334
+
335
+ def set_load load
336
+ @load = load
337
+ end
338
+
339
+ def leads # http://developers.marketo.com/documentation/soap/getleadchanges/
340
+ GoodDataMarketo::Leads.new :client => self
341
+ end
342
+
343
+ def usage(config = {})
344
+ rest = GoodDataMarketo::RESTAdapter.new :webdav => @webdav
345
+ rest.usage
346
+ end
347
+
348
+ def campaigns # http://developers.marketo.com/documentation/soap/campaigns/
349
+ GoodDataMarketo::Campaigns.new :client => self
350
+ end
351
+
352
+ def mobjects # http://developers.marketo.com/documentation/soap/getmobjects/
353
+ GoodDataMarketo::MObjects.new :client => self
354
+ end
355
+
356
+ def operations
357
+ @savon.operations
358
+ end
359
+
360
+ def loads(config = {})
361
+ self.load = true
362
+ @loads = GoodDataMarketo::Loads.new config
363
+ end
364
+
365
+ def load=(load)
366
+ @load = load
367
+ end
368
+
369
+ alias :objects :mobjects
370
+
371
+ alias :lead :leads
372
+
373
+ end