gooddata_marketo 0.0.1-java
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/Gemfile +9 -0
- data/Gemfile.lock +131 -0
- data/README.md +207 -0
- data/bin/Gemfile +10 -0
- data/bin/auth.json +16 -0
- data/bin/main.rb +24 -0
- data/bin/process.rbx +541 -0
- data/examples/all_lead_changes.rb +119 -0
- data/examples/all_leads.rb +249 -0
- data/examples/lead_changes_to_ads.rb +63 -0
- data/gooddata_marketo.gemspec +25 -0
- data/lib/gooddata_marketo/adapters/rest.rb +287 -0
- data/lib/gooddata_marketo/client.rb +373 -0
- data/lib/gooddata_marketo/data/activity_types.rb +104 -0
- data/lib/gooddata_marketo/data/reserved_sql_keywords.rb +205 -0
- data/lib/gooddata_marketo/helpers/s3.rb +141 -0
- data/lib/gooddata_marketo/helpers/stringwizard.rb +32 -0
- data/lib/gooddata_marketo/helpers/table.rb +323 -0
- data/lib/gooddata_marketo/helpers/webdav.rb +118 -0
- data/lib/gooddata_marketo/loads.rb +235 -0
- data/lib/gooddata_marketo/models/campaigns.rb +57 -0
- data/lib/gooddata_marketo/models/channels.rb +30 -0
- data/lib/gooddata_marketo/models/child/activity.rb +104 -0
- data/lib/gooddata_marketo/models/child/criteria.rb +17 -0
- data/lib/gooddata_marketo/models/child/lead.rb +118 -0
- data/lib/gooddata_marketo/models/child/mobj.rb +68 -0
- data/lib/gooddata_marketo/models/etl.rb +75 -0
- data/lib/gooddata_marketo/models/leads.rb +493 -0
- data/lib/gooddata_marketo/models/load.rb +17 -0
- data/lib/gooddata_marketo/models/mobjects.rb +121 -0
- data/lib/gooddata_marketo/models/streams.rb +137 -0
- data/lib/gooddata_marketo/models/tags.rb +35 -0
- data/lib/gooddata_marketo/models/validate.rb +46 -0
- data/lib/gooddata_marketo.rb +24 -0
- data/process.rb +517 -0
- metadata +177 -0
data/bin/process.rbx
ADDED
@@ -0,0 +1,541 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
###################################################################
|
4
|
+
# #
|
5
|
+
# #
|
6
|
+
# GOODDATA MARKETO CONNECTOR #
|
7
|
+
# #
|
8
|
+
# Ruby process for download client data from Marketo. #
|
9
|
+
# https://github.com/gooddata/app_store/marketo_connector #
|
10
|
+
# #
|
11
|
+
# #
|
12
|
+
###################################################################
|
13
|
+
|
14
|
+
require 'gooddata_marketo'
|
15
|
+
|
16
|
+
# Load the authorization keys.
|
17
|
+
auth = JSON.parse(IO.read('auth.json'), :symbolize_names => true)
|
18
|
+
|
19
|
+
MARKETO_SOAP_USER = auth[:MARKETO_SOAP_USER]
|
20
|
+
MARKETO_SOAP_KEY = auth[:MARKETO_SOAP_KEY]
|
21
|
+
MARKETO_REST_ID = auth[:MARKETO_REST_ID]
|
22
|
+
MARKETO_REST_SECRET = auth[:MARKETO_REST_SECRET]
|
23
|
+
MARKETO_SUBDOMAIN = auth[:MARKETO_SUBDOMAIN]
|
24
|
+
MARKETO_API_LIMIT = auth[:MARKETO_API_LIMIT]
|
25
|
+
LEAD_LIST_DUMP_CSV = auth[:LEAD_LIST_DUMP_CSV]
|
26
|
+
GOODDATA_USER = auth[:GOODDATA_USER]
|
27
|
+
GOODDATA_PASSWORD = auth[:GOODDATA_PASSWORD]
|
28
|
+
GOODDATA_PROJECT = auth[:GOODDATA_PROJECT]
|
29
|
+
GOODDATA_ADS = auth[:GOODDATA_ADS]
|
30
|
+
|
31
|
+
S3_PUBLIC_KEY = auth[:S3_PUBLIC_KEY]
|
32
|
+
S3_PRIVATE_KEY = auth[:S3_PRIVATE_KEY]
|
33
|
+
S3_BUCKET = auth[:S3_BUCKET]
|
34
|
+
|
35
|
+
# No need to configure beyond this point. #
|
36
|
+
@s3 = S3Helper.new :public_key => S3_PUBLIC_KEY,
|
37
|
+
:private_key => S3_PRIVATE_KEY,
|
38
|
+
:bucket => S3_BUCKET
|
39
|
+
|
40
|
+
@webdav = WebDAV.new(:user => GOODDATA_USER,
|
41
|
+
:pass => GOODDATA_PASSWORD,
|
42
|
+
:project => GOODDATA_PROJECT)
|
43
|
+
|
44
|
+
@dwh = GoodData::Datawarehouse.new(GOODDATA_USER,
|
45
|
+
GOODDATA_PASSWORD,
|
46
|
+
GOODDATA_ADS)
|
47
|
+
|
48
|
+
@marketo = GoodDataMarketo.connect(:user_id => MARKETO_SOAP_USER,
|
49
|
+
:encryption_key => MARKETO_SOAP_KEY,
|
50
|
+
:api_subdomain => MARKETO_SUBDOMAIN,
|
51
|
+
:webdav => @webdav)
|
52
|
+
|
53
|
+
GoodDataMarketo.logging = true
|
54
|
+
|
55
|
+
# Test services
|
56
|
+
# @marketo.test_rest
|
57
|
+
# @marketo.test_soap
|
58
|
+
# @s3.test
|
59
|
+
# @dwh.test
|
60
|
+
# @webdav.test
|
61
|
+
|
62
|
+
def run_load config = {}
|
63
|
+
|
64
|
+
index = config[:index] || 1
|
65
|
+
@increment = config[:increment] || (12*60*60)
|
66
|
+
@marketo = config[:marketo_client]
|
67
|
+
@ads_target_table_name = config[:ads_table]
|
68
|
+
@lead_dump_file = "get_load_chunk_#{index}"
|
69
|
+
|
70
|
+
if @s3.exists? 'queue.json'
|
71
|
+
|
72
|
+
@queue = JSON.parse(@s3.download('queue.json'))
|
73
|
+
# Cancel the load if the queue is empty and delete the object.
|
74
|
+
if @queue.empty?
|
75
|
+
puts 'WARNING: Empty queue array was extracted from S3. Using queue passed in method.' if GoodDataMarketo.logging
|
76
|
+
@s3.delete('queue.json')
|
77
|
+
@queue = config[:queue]
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
else
|
82
|
+
@queue = config[:queue]
|
83
|
+
end
|
84
|
+
|
85
|
+
raise "You must pass an array of job hashs :queue_array when using run_load AND define a :marketo_client." unless @queue.length > 0 && @marketo
|
86
|
+
raise ":ads_table param is required with using run_load." unless @ads_target_table_name
|
87
|
+
|
88
|
+
loop do
|
89
|
+
|
90
|
+
loads = @marketo.loads(:user => GOODDATA_USER,
|
91
|
+
:pass => GOODDATA_PASSWORD,
|
92
|
+
:project => GOODDATA_PROJECT,
|
93
|
+
:marketo_client => @marketo)
|
94
|
+
|
95
|
+
if loads.available?
|
96
|
+
|
97
|
+
file = loads.available.first
|
98
|
+
|
99
|
+
load = loads.create :name => file
|
100
|
+
|
101
|
+
@job_name = file
|
102
|
+
@id = load.id
|
103
|
+
@ads_table = load.json[:ads_table]
|
104
|
+
# Run the load from local or remote.
|
105
|
+
load.execute
|
106
|
+
# Data from the job can now be accessed ARRAY load.storage
|
107
|
+
# load.storage
|
108
|
+
|
109
|
+
if !load.storage.empty?
|
110
|
+
|
111
|
+
# Join all of the columns from the sample to all other columns.
|
112
|
+
|
113
|
+
@columns_load_aggregate = ['sys_capture_date']
|
114
|
+
load.storage.each { |raw_json_lead|
|
115
|
+
|
116
|
+
lead = GoodDataMarketo::Activity.new raw_json_lead if load.json[:method] == 'get_changes'
|
117
|
+
lead = GoodDataMarketo::Lead.new raw_json_lead if load.json[:method] == 'get_multiple'
|
118
|
+
|
119
|
+
print "\r#{Time.now} => Resolving columns: #{lead.id}\s" if GoodDataMarketo.logging
|
120
|
+
|
121
|
+
@columns_load_aggregate = @columns_load_aggregate | lead.columns
|
122
|
+
}
|
123
|
+
@columns_load_aggregate.map! { |column|
|
124
|
+
column.downcase.gsub('-','_')
|
125
|
+
}
|
126
|
+
|
127
|
+
# DEFAULTS: Use the correct ADS table.
|
128
|
+
if load.json[:method] == "get_multiple"
|
129
|
+
ads_target_table_name = 'marketo_leads'
|
130
|
+
elsif load.json[:method] = 'get_changes'
|
131
|
+
ads_target_table_name = 'marketo_changes'
|
132
|
+
else
|
133
|
+
ads_target_table_name = 'dump'
|
134
|
+
end
|
135
|
+
|
136
|
+
# Set up a new Table/Automatically loads current table if exists.
|
137
|
+
|
138
|
+
table = Table.new :client => @dwh, :name => @ads_table || ads_target_table_name, :columns => ['id','sys_capture_date']
|
139
|
+
|
140
|
+
if @columns_load_aggregate.length > 0
|
141
|
+
table.merge_columns :merge_with => @columns_load_aggregate
|
142
|
+
|
143
|
+
end
|
144
|
+
@csv = CSV.open("#{@id}.csv", 'w')
|
145
|
+
|
146
|
+
updated_columns = table.columns
|
147
|
+
|
148
|
+
if @columns_load_aggregate.length > 0
|
149
|
+
@csv << updated_columns
|
150
|
+
end
|
151
|
+
|
152
|
+
count = 0
|
153
|
+
|
154
|
+
ids_for_get_multiple_load = []
|
155
|
+
|
156
|
+
puts "#{Time.now} => Building objects from stream cache." if GoodDataMarketo.logging
|
157
|
+
|
158
|
+
total_leads = load.storage.length
|
159
|
+
total_leads_index = 0
|
160
|
+
load.storage.pmap do |lead|
|
161
|
+
|
162
|
+
lead = GoodDataMarketo::Activity.new lead if load.json[:method] == 'get_changes'
|
163
|
+
lead = GoodDataMarketo::Lead.new lead if load.json[:method] == 'get_multiple'
|
164
|
+
|
165
|
+
total_leads_index += 1
|
166
|
+
percentage = ((100*total_leads_index.to_f)/total_leads.to_f).round(1)
|
167
|
+
print "\r#{Time.now} => Transforming #{lead.id} #{percentage}%\s" if GoodDataMarketo.logging
|
168
|
+
|
169
|
+
# Get any new lead or merge lead ids and queue them for a load with get multiple.
|
170
|
+
ids_for_get_multiple_load << lead.values['merge_id'] if lead.values['merge_id']
|
171
|
+
ids_for_get_multiple_load << lead.values['lead_id'] if lead.values['lead_id']
|
172
|
+
|
173
|
+
row_to_save_csv = []
|
174
|
+
|
175
|
+
row_with_columns = updated_columns.map { |column|
|
176
|
+
if lead.columns.include? column
|
177
|
+
{ column => lead.values[column] }
|
178
|
+
elsif lead.columns.include? "#{column}_m" # Check for anything that was removed by SQL
|
179
|
+
{ "#{column}_m" => lead.values["#{column}_m"] }
|
180
|
+
elsif column == 'sys_capture_date'
|
181
|
+
{ 'sys_capture_date' => Time.now.to_s }
|
182
|
+
else
|
183
|
+
{ column => nil }
|
184
|
+
end
|
185
|
+
}
|
186
|
+
|
187
|
+
row_with_columns.each { |item|
|
188
|
+
c = item.to_a.flatten
|
189
|
+
if c[1] == nil
|
190
|
+
row_to_save_csv << nil
|
191
|
+
else
|
192
|
+
row_to_save_csv << c[1]
|
193
|
+
end
|
194
|
+
|
195
|
+
}
|
196
|
+
|
197
|
+
count += 1
|
198
|
+
@csv << row_to_save_csv
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
# Prepare (flush) the CSV for upload.
|
203
|
+
@csv.flush
|
204
|
+
|
205
|
+
table.import_csv("#{@id}.csv")
|
206
|
+
|
207
|
+
puts "#{Time.now} => #{@dwh.execute_select("SELECT id FROM #{@ads_table}").length} rows in ADS." if GoodDataMarketo.logging
|
208
|
+
puts "#{Time.now} => Rows extracted from CSV: #{count}" if GoodDataMarketo.logging
|
209
|
+
puts "#{Time.now} => New and merged ids queued: #{ids_for_get_multiple_load.length}" if GoodDataMarketo.logging
|
210
|
+
|
211
|
+
save_ids_for_get_multiple ids_for_get_multiple_load, 'a'
|
212
|
+
|
213
|
+
File.delete("#{load.json[:name]}_load.json") if File.exists? ("#{load.json[:name]}_load.json")
|
214
|
+
File.delete("#{@id}.csv") if File.exists? ("#{@id}.csv")
|
215
|
+
|
216
|
+
puts "#{Time.now} => Ads import of \"#{@lead_dump_file}\" complete." if GoodDataMarketo.logging
|
217
|
+
puts "#{Time.now} => Arguments: #{load.arguments}" if GoodDataMarketo.logging
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
case load.json[:method]
|
222
|
+
|
223
|
+
when 'get_changes'
|
224
|
+
|
225
|
+
# Increment the load by one day if it is time related.
|
226
|
+
|
227
|
+
oca = load.arguments[:oldest_created_at]
|
228
|
+
lca = load.arguments[:latest_created_at]
|
229
|
+
|
230
|
+
increment = Time.parse(lca) - Time.parse(oca)
|
231
|
+
total_time_range = Time.now - Time.parse(oca)
|
232
|
+
|
233
|
+
load.arguments[:oldest_created_at] = Time.parse(lca).to_s
|
234
|
+
load.arguments[:latest_created_at] = (Time.parse(lca) + increment).to_s
|
235
|
+
|
236
|
+
puts "#{Time.now} => API calls until current time: #{(total_time_range/increment).round}" if GoodDataMarketo.logging
|
237
|
+
|
238
|
+
# If the latest time is later then today kill the load.
|
239
|
+
|
240
|
+
if Time.parse(load.arguments[:latest_created_at]) > Time.now
|
241
|
+
|
242
|
+
|
243
|
+
load.terminate
|
244
|
+
|
245
|
+
next
|
246
|
+
|
247
|
+
# Otherwise save the load and resume additional loads.
|
248
|
+
else
|
249
|
+
|
250
|
+
load.save
|
251
|
+
|
252
|
+
next
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
when 'get_multiple'
|
257
|
+
|
258
|
+
determine_loads_state
|
259
|
+
|
260
|
+
else
|
261
|
+
|
262
|
+
raise 'Unable to determine lead type ("get_multiple"/"get_changes")!'
|
263
|
+
|
264
|
+
break
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
else
|
269
|
+
|
270
|
+
load = @queue.pop
|
271
|
+
|
272
|
+
puts "#{Time.now} => #{@queue.length} loads remaining."
|
273
|
+
|
274
|
+
if @queue.length > 0
|
275
|
+
File.open('queue.json','w'){ |f| JSON.dump(@queue, f) }
|
276
|
+
@s3.upload('queue.json')
|
277
|
+
end
|
278
|
+
|
279
|
+
if load
|
280
|
+
|
281
|
+
loads.create load
|
282
|
+
|
283
|
+
next
|
284
|
+
|
285
|
+
else
|
286
|
+
|
287
|
+
@s3.delete('queue.json')
|
288
|
+
File.delete('queue.json') if File.exists?('queue.json')
|
289
|
+
|
290
|
+
break
|
291
|
+
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
end
|
296
|
+
|
297
|
+
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
301
|
+
|
302
|
+
#####################################
|
303
|
+
# #
|
304
|
+
# INITIAL GET ALL MULTIPLE LEADS #
|
305
|
+
# #
|
306
|
+
#####################################
|
307
|
+
# Downloads all current lead ids with REST ID.
|
308
|
+
# Uses SOAP API to rotate through ids with get multiple.
|
309
|
+
# Runs once, boolean value set in initial_load_get_multiple at marketo_connector_config.json
|
310
|
+
|
311
|
+
def initial_load_get_multiple
|
312
|
+
|
313
|
+
@marketo.write_all_lead_ids_to_csv # Large bulk download to CSV of leads over REST API.
|
314
|
+
|
315
|
+
ids = CSV.open(LEAD_LIST_DUMP_CSV).map { |m| m[0] }
|
316
|
+
|
317
|
+
puts "#{Time.now} => #{ids.length} imported from local CSV." if GoodDataMarketo.logging
|
318
|
+
|
319
|
+
counter = 0
|
320
|
+
|
321
|
+
loop do
|
322
|
+
|
323
|
+
counter += 1
|
324
|
+
|
325
|
+
batch = ids.slice!(1..1000)
|
326
|
+
|
327
|
+
break if batch.length <= 0
|
328
|
+
|
329
|
+
get_multiple_leads_configuration = {
|
330
|
+
:name => "get_all_leads_chunk",
|
331
|
+
:type => 'leads',
|
332
|
+
:method => 'get_multiple',
|
333
|
+
:ads_table => 'marketo_leads',
|
334
|
+
:arguments => {
|
335
|
+
:ids => batch, # Notice the addition of the IDS box
|
336
|
+
:type => 'IDNUM'
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
340
|
+
puts "#{Time.now} => Id count in batch:#{batch.length} (Req:#{counter})" if GoodDataMarketo.logging
|
341
|
+
|
342
|
+
run_load :batch => batch,
|
343
|
+
:counter => counter,
|
344
|
+
:ads_table => 'marketo_leads',
|
345
|
+
:marketo_client => @marketo,
|
346
|
+
:queue => [get_multiple_leads_configuration]
|
347
|
+
|
348
|
+
save_ids_for_get_multiple ids, 'w'
|
349
|
+
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
########################################
|
354
|
+
# #
|
355
|
+
# INITIAL GET ALL LEAD CHANGES #
|
356
|
+
# #
|
357
|
+
########################################
|
358
|
+
# Starts January 1st 2000 and increments by the day until present day.
|
359
|
+
# All Activity Types included unless specified.
|
360
|
+
# Runs once, boolean value set in initial_load_get_changes at marketo_connector_config.json
|
361
|
+
|
362
|
+
def initial_load_get_changes
|
363
|
+
|
364
|
+
get_lead_changes_configuration = {
|
365
|
+
:name => 'get_lead_changes_chunk',
|
366
|
+
:type => 'leads',
|
367
|
+
:method => 'get_changes',
|
368
|
+
:ads_table => 'marketo_changes',
|
369
|
+
:arguments => {
|
370
|
+
# "oldest_created_at" and "latest_created_at" is the size of the increment it will to current time.
|
371
|
+
:oldest_created_at => 'January 1st 2004',
|
372
|
+
:latest_created_at => 'January 2nd 2004',
|
373
|
+
:filters => []
|
374
|
+
}
|
375
|
+
}
|
376
|
+
|
377
|
+
# Create a new configuration object for each activity type.
|
378
|
+
get_lead_changes_configuration.freeze
|
379
|
+
|
380
|
+
queue = []
|
381
|
+
|
382
|
+
@marketo.activity_types.each { |type|
|
383
|
+
|
384
|
+
g = {
|
385
|
+
:filters => [type]
|
386
|
+
}
|
387
|
+
|
388
|
+
m = get_lead_changes_configuration.dup
|
389
|
+
c = m.dup
|
390
|
+
c[:arguments] = m[:arguments].merge(g)
|
391
|
+
|
392
|
+
queue << c
|
393
|
+
|
394
|
+
}
|
395
|
+
|
396
|
+
run_load :ads_table => get_lead_changes_configuration[:ads_table],
|
397
|
+
:queue => queue,
|
398
|
+
:marketo_client => @marketo,
|
399
|
+
:index => 1,
|
400
|
+
:counter => 1
|
401
|
+
|
402
|
+
puts "#{Time.now} => Updating initial load changes to true in connector configuration." if GoodDataMarketo.logging
|
403
|
+
|
404
|
+
@s3.set_config(:initial_load_get_changes => true)
|
405
|
+
|
406
|
+
end
|
407
|
+
|
408
|
+
########################################
|
409
|
+
# #
|
410
|
+
# SYNC MULTIPLE LEADS #
|
411
|
+
# #
|
412
|
+
########################################
|
413
|
+
|
414
|
+
def update_get_multiple_leads
|
415
|
+
|
416
|
+
file = File.open(LEAD_LIST_DUMP_CSV, 'w')
|
417
|
+
file.puts @s3.download(LEAD_LIST_DUMP_CSV)
|
418
|
+
|
419
|
+
ids = CSV.open(LEAD_LIST_DUMP_CSV).map { |m| m[0] }
|
420
|
+
|
421
|
+
puts "#{Time.now} => #{ids.length} imported from local CSV." if GoodDataMarketo.logging
|
422
|
+
|
423
|
+
counter = 0
|
424
|
+
|
425
|
+
loop do
|
426
|
+
|
427
|
+
counter += 1
|
428
|
+
|
429
|
+
batch = ids.slice!(1..1000)
|
430
|
+
|
431
|
+
break if batch.length <= 0
|
432
|
+
|
433
|
+
get_multiple_leads_configuration = {
|
434
|
+
:name => "get_all_leads_chunk",
|
435
|
+
:type => 'leads',
|
436
|
+
:method => 'get_multiple',
|
437
|
+
:ads_table => 'marketo_leads',
|
438
|
+
:arguments => {
|
439
|
+
:ids => batch, # Notice the addition of the IDS box
|
440
|
+
:type => 'IDNUM'
|
441
|
+
}
|
442
|
+
}
|
443
|
+
|
444
|
+
puts "#{Time.now} => Id count in batch:#{batch.length} (Req:#{counter})" if GoodDataMarketo.logging
|
445
|
+
|
446
|
+
run_load :batch => batch,
|
447
|
+
:counter => counter,
|
448
|
+
:ads_table => 'marketo_leads',
|
449
|
+
:marketo_client => @marketo,
|
450
|
+
:queue => [get_multiple_leads_configuration]
|
451
|
+
|
452
|
+
save_ids_for_get_multiple ids, 'w'
|
453
|
+
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
########################################
|
458
|
+
# #
|
459
|
+
# SYNC LEAD CHANGES #
|
460
|
+
# #
|
461
|
+
########################################
|
462
|
+
# Synchronizes last 12 hours from process execution.
|
463
|
+
# Runs continuously.
|
464
|
+
|
465
|
+
def update_lead_changes
|
466
|
+
|
467
|
+
# Changing activity types from the default set to just Visit Webpage type.
|
468
|
+
#@marketo.activity_types = ['Visit Webpage']
|
469
|
+
#@marketo.activity_types = ['New SFDC Opportunity','Remove from Opportunity','Add to Opportunity', 'Update Opportunity']
|
470
|
+
|
471
|
+
fourty_eight_hours_ago = (Time.now - (48*60*60)).to_s
|
472
|
+
twenty_four_hours_ago = (Time.now - (24*60*60)).to_s
|
473
|
+
twelve_hours_ago = (Time.now - (12*60*60)).to_s
|
474
|
+
six_hours_ago = (Time.now - (6*60*60)).to_s
|
475
|
+
|
476
|
+
get_lead_changes_configuration = {
|
477
|
+
:name => 'get_lead_changes_chunk',
|
478
|
+
:type => 'leads',
|
479
|
+
:method => 'get_changes',
|
480
|
+
:ads_table => 'marketo_changes_date',
|
481
|
+
:arguments => {
|
482
|
+
# "oldest_created_at" and "latest_created_at" is the size of the increment it will to current time.
|
483
|
+
:oldest_created_at => twelve_hours_ago,
|
484
|
+
:latest_created_at => six_hours_ago,
|
485
|
+
:filters => []
|
486
|
+
}
|
487
|
+
}
|
488
|
+
|
489
|
+
# Create a new configuration object for each activity type.
|
490
|
+
get_lead_changes_configuration.freeze
|
491
|
+
|
492
|
+
queue = []
|
493
|
+
|
494
|
+
@marketo.activity_types.each { |type|
|
495
|
+
|
496
|
+
g = {
|
497
|
+
:filters => [type]
|
498
|
+
}
|
499
|
+
|
500
|
+
m = get_lead_changes_configuration.dup
|
501
|
+
c = m.dup
|
502
|
+
c[:arguments] = m[:arguments].merge(g)
|
503
|
+
|
504
|
+
queue << c
|
505
|
+
|
506
|
+
}
|
507
|
+
|
508
|
+
run_load :ads_table => get_lead_changes_configuration[:ads_table],
|
509
|
+
:queue => queue,
|
510
|
+
:marketo_client => @marketo,
|
511
|
+
:increment => (24*60*60),
|
512
|
+
:counter => 1
|
513
|
+
|
514
|
+
end
|
515
|
+
|
516
|
+
def save_ids_for_get_multiple ids, write_type
|
517
|
+
csv = CSV.open(LEAD_LIST_DUMP_CSV, write_type)
|
518
|
+
ids.each { |row| csv << [row] }
|
519
|
+
csv.flush
|
520
|
+
@s3.upload(LEAD_LIST_DUMP_CSV)
|
521
|
+
end
|
522
|
+
|
523
|
+
# Download the configuration file from S3. If there is not one, one will be created.
|
524
|
+
config = @s3.get_config
|
525
|
+
|
526
|
+
if !config[:initial_load_get_multiple]
|
527
|
+
|
528
|
+
initial_load_get_multiple
|
529
|
+
|
530
|
+
elsif !config[:initial_load_get_changes]
|
531
|
+
|
532
|
+
initial_load_get_changes
|
533
|
+
|
534
|
+
else
|
535
|
+
|
536
|
+
update_lead_changes
|
537
|
+
|
538
|
+
#Once the most recent changes downloaded, create and save a load for update_get_multiple_leads
|
539
|
+
update_get_multiple_leads
|
540
|
+
|
541
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'gooddata_marketo'
|
2
|
+
|
3
|
+
MARKETO_USER = ''
|
4
|
+
MARKETO_KEY = ''
|
5
|
+
MARKETO_SUBDOMAIN = ''
|
6
|
+
|
7
|
+
GOODDATA_USER = ''
|
8
|
+
GOODDATA_PASSWORD = ''
|
9
|
+
GOODDATA_PROJECT = ''
|
10
|
+
|
11
|
+
@marketo = GoodDataMarketo.connect(:user_id => MARKETO_USER, :encryption_key => MARKETO_KEY, :api_subdomain => MARKETO_SUBDOMAIN)
|
12
|
+
|
13
|
+
# The specific parameters used in the method.
|
14
|
+
|
15
|
+
#################
|
16
|
+
# #
|
17
|
+
# CONFIGURATION #
|
18
|
+
# #
|
19
|
+
#################
|
20
|
+
|
21
|
+
get_lead_changes_from_march = {
|
22
|
+
:name => 'get_lead_changes_from_march',
|
23
|
+
:type => 'leads',
|
24
|
+
:method => 'get_changes',
|
25
|
+
:arguments => {
|
26
|
+
:oldest_created_at => 'March 26th 2014',
|
27
|
+
:latest_created_at => 'March 27th 2014',
|
28
|
+
:filters => ['Merge Leads']
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
32
|
+
get_multiple_from_january = {
|
33
|
+
:name => 'get_all_leads_january',
|
34
|
+
:type => 'leads',
|
35
|
+
:method => 'get_multiple',
|
36
|
+
:arguments => {
|
37
|
+
:ids => ['23849090','23849091'], # Notice the addition of the IDS box
|
38
|
+
:type => 'IDNUM'
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
@queue = [get_lead_changes_from_march, get_multiple_from_january]
|
43
|
+
|
44
|
+
###################################
|
45
|
+
# #
|
46
|
+
# DO NOT EDIT BELOW: LOAD MANAGER #
|
47
|
+
# #
|
48
|
+
###################################
|
49
|
+
|
50
|
+
|
51
|
+
def determine_loads_state
|
52
|
+
|
53
|
+
loads = @marketo.loads(:user => GOODDATA_USER,
|
54
|
+
:pass => GOODDATA_PASSWORD,
|
55
|
+
:project => GOODDATA_PROJECT,
|
56
|
+
:marketo_client => @marketo)
|
57
|
+
|
58
|
+
if loads.available?
|
59
|
+
|
60
|
+
file = loads.available.first
|
61
|
+
load = loads.create :name => file
|
62
|
+
|
63
|
+
load.execute
|
64
|
+
|
65
|
+
# Data from the job can now be accessed ARRAY load.storage
|
66
|
+
# load.storage
|
67
|
+
|
68
|
+
# Increment the load by one day if it is time related.
|
69
|
+
|
70
|
+
case load.json[:method]
|
71
|
+
|
72
|
+
when 'get_changes'
|
73
|
+
|
74
|
+
one_day = (24*60*60)
|
75
|
+
oca = load.arguments[:oldest_created_at]
|
76
|
+
lca = load.arguments[:latest_created_at]
|
77
|
+
|
78
|
+
load.arguments[:oldest_created_at] = (Time.parse(oca) + one_day).to_s
|
79
|
+
load.arguments[:latest_created_at] = (Time.parse(lca) + one_day).to_s
|
80
|
+
|
81
|
+
# If the latest time is later then today kill the load.
|
82
|
+
if Time.parse(lca) > Time.now
|
83
|
+
|
84
|
+
load.terminate
|
85
|
+
|
86
|
+
determine_loads_state
|
87
|
+
|
88
|
+
# Otherwise save the load and resume additional loads.
|
89
|
+
else
|
90
|
+
|
91
|
+
load.save
|
92
|
+
|
93
|
+
determine_loads_state
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
when 'get_multiple'
|
98
|
+
|
99
|
+
determine_loads_state
|
100
|
+
|
101
|
+
else
|
102
|
+
raise 'Unable to determine lead type ("get_multiple"/"get_changes")!'
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
else
|
107
|
+
|
108
|
+
load = @queue.pop
|
109
|
+
loads.create load
|
110
|
+
|
111
|
+
determine_loads_state
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
# Run once, recursive until no loads are available.
|
118
|
+
determine_loads_state
|
119
|
+
|