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
@@ -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
+
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'gooddata_marketo'
4
+
5
+ MARKETO_USER = ""
6
+ MARKETO_KEY = ""
7
+ MARKETO_SUBDOMAIN = ''
8
+
9
+ MARKETO_AUTHORIZED_USER = ''
10
+ MARKETO_REST_SECRET = ''
11
+ MARKETO_REST_ID = ''
12
+
13
+ MARKETO_API_LIMIT = 10000 # Total number (SOAP+REST) of API calls to make in a given day.
14
+ LEAD_LIST_DUMP_CSV = 'marketo_leads_dump.csv' # Name of file to store all lead IDS.
15
+
16
+ GOODDATA_USER = 'YOU@gooddata.com'
17
+ GOODDATA_PASSWORD = ''
18
+ GOODDATA_PROJECT = ''
19
+ GOODDATA_ADS = ''
20
+
21
+ @webdav = WebDAV.new(:user => GOODDATA_USER,
22
+ :pass => GOODDATA_PASSWORD,
23
+ :project => GOODDATA_PROJECT)
24
+
25
+ @dwh = GoodData::Datawarehouse.new(GOODDATA_USER,
26
+ GOODDATA_PASSWORD,
27
+ GOODDATA_ADS)
28
+
29
+ @marketo = GoodDataMarketo.connect(:user_id => MARKETO_USER,
30
+ :encryption_key => MARKETO_KEY,
31
+ :api_subdomain => MARKETO_SUBDOMAIN,
32
+ :webdav => @webdav)
33
+
34
+ GoodDataMarketo.logging = true
35
+
36
+ ###############################
37
+ # #
38
+ # STAGE I: GET ALL LEAD IDS #
39
+ # #
40
+ ###############################
41
+ # REST API download of all available leads.
42
+
43
+ marketo.write_all_lead_ids_to_csv :file => LEAD_LIST_DUMP_CSV
44
+
45
+ ids = CSV.open(LEAD_LIST_DUMP_CSV).map { |m| m[0] }
46
+
47
+ puts "#{Time.now} => #{ids.length} imported from local CSV." if GoodDataMarketo.logging
48
+
49
+ def get_all_leads_batch batch, index
50
+
51
+
52
+ ###############################
53
+ # #
54
+ # STAGE II: CONFIGURE LOADS #
55
+ # #
56
+ ###############################
57
+ # SOAP API
58
+ # Configure additional loads as hashes, add them to @queue
59
+
60
+ get_all_leads = {
61
+ :name => "get_all_leads_chunk_#{index}",
62
+ :type => 'leads',
63
+ :method => 'get_multiple',
64
+ :arguments => {
65
+ :ids => batch, # Notice the addition of the IDS box
66
+ :type => 'IDNUM'
67
+ }
68
+ }
69
+
70
+ @lead_dump_file = get_all_leads[:name]
71
+
72
+ # If there are aditional loads, add to this array.
73
+ @queue = [get_all_leads]
74
+
75
+
76
+ ###############################
77
+ # #
78
+ # STAGE III: LOAD #
79
+ # #
80
+ ###############################
81
+ # SOAP API. No need to cofigure beyond this point.
82
+ # Loops function until no remaining jobs.
83
+
84
+ def determine_loads_state config = {}
85
+
86
+
87
+ loads = @marketo.loads(:user => GOODDATA_USER,
88
+ :pass => GOODDATA_PASSWORD,
89
+ :project => GOODDATA_PROJECT,
90
+ :marketo_client => @marketo)
91
+
92
+ if loads.available?
93
+
94
+ file = loads.available.first
95
+ load = loads.create :name => file
96
+
97
+ # Run the load from local or remote.
98
+ load.execute
99
+
100
+ # Data from the job can now be accessed ARRAY load.storage
101
+ # load.storage
102
+
103
+ # Join all of the columns from the sample to all other columns.
104
+ @columns_load_aggregate = ['sys_capture_date']
105
+ load.storage.each { |lead| @columns_load_aggregate = @columns_load_aggregate | lead.columns }
106
+ @columns_load_aggregate.map! { |column| column.downcase.gsub('-','_') }
107
+
108
+ # Set up a new Table/Automatically loads current table if exists.
109
+ table = Table.new :client => @dwh, :name => 'marketo_leads', :columns => ['id','email']
110
+
111
+ if @columns_load_aggregate.length > 0
112
+ table.merge_columns :merge_with => @columns_load_aggregate
113
+ @csv = CSV.open("#{@lead_dump_file}.csv", 'wb')
114
+ else
115
+ @csv = CSV.open("#{@lead_dump_file}.csv", 'wb')
116
+ end
117
+
118
+ updated_columns = table.columns
119
+
120
+ if @columns_load_aggregate.length > 0
121
+ @csv << updated_columns
122
+ end
123
+
124
+ count = 0
125
+ load.storage.each do |lead|
126
+
127
+ row_to_save_csv = []
128
+
129
+ row_with_columns = updated_columns.map { |column|
130
+ if lead.columns.include? column
131
+ { column => lead.values[column] }
132
+ elsif column == 'sys_capture_date'
133
+ { 'sys_capture_date' => Time.now.to_s }
134
+ else
135
+ { column => "NULL" }
136
+ end
137
+ }
138
+
139
+ row_with_columns.each { |item|
140
+ c = item.to_a.flatten
141
+ if c[1] == "NULL"
142
+ row_to_save_csv << "NULL"
143
+ else
144
+ row_to_save_csv << c[1]
145
+ end
146
+
147
+ }
148
+
149
+ count += 1
150
+ @csv << row_to_save_csv
151
+
152
+ end
153
+
154
+ # Prepare (flush) the CSV for upload.
155
+ @csv.flush
156
+
157
+ table.import_csv("#{@lead_dump_file}.csv")
158
+
159
+ puts "#{Time.now} => CSV:Rows:#{count}"
160
+ File.delete("#{@lead_dump_file}.json")
161
+ File.delete("#{@lead_dump_file}.csv")
162
+
163
+ puts "#{Time.now} => ADS:TableComplete:#{@lead_dump_file}" if GoodDataMarketo.logging
164
+
165
+ case load.json[:method]
166
+
167
+ when 'get_changes'
168
+
169
+ # Increment the load by one day if it is time related.
170
+ time_increment = (12*60*60)
171
+ oca = load.arguments[:oldest_created_at]
172
+ lca = load.arguments[:latest_created_at]
173
+
174
+ load.arguments[:oldest_created_at] = (Time.parse(oca) + time_increment).to_s
175
+ load.arguments[:latest_created_at] = (Time.parse(lca) + time_increment).to_s
176
+
177
+ # If the latest time is later then today kill the load.
178
+ if Time.parse(lca) > Time.now
179
+
180
+ load.terminate
181
+
182
+ determine_loads_state
183
+
184
+ # Otherwise save the load and resume additional loads.
185
+ else
186
+
187
+ load.save
188
+
189
+ determine_loads_state
190
+
191
+ end
192
+
193
+ when 'get_multiple'
194
+
195
+ determine_loads_state
196
+
197
+ else
198
+ raise 'Unable to determine lead type ("get_multiple"/"get_changes")!'
199
+
200
+ end
201
+
202
+ else
203
+
204
+ load = @queue.pop
205
+
206
+ if load
207
+ loads.create load
208
+ determine_loads_state
209
+ end
210
+
211
+ end
212
+
213
+ end
214
+
215
+ # Run once, recursive until no loads are available.
216
+ determine_loads_state
217
+
218
+ end
219
+
220
+ counter = 0
221
+
222
+ while ids.length > -1
223
+
224
+ counter += 1
225
+
226
+ batch = ids.slice!(1..1000)
227
+
228
+ if batch.length > 0
229
+ puts "#{Time.now} => Batch:Downloader:Length:#{batch.length} (Req:#{counter})" if GoodDataMarketo.logging
230
+ get_all_leads_batch batch, counter
231
+
232
+ CSV.open(LEAD_LIST_DUMP_CSV,'w') do |csv|
233
+ ids.each { |row| csv << [row] }
234
+ end
235
+
236
+ next
237
+
238
+ else
239
+
240
+ break
241
+
242
+ end
243
+
244
+ end
245
+
246
+ binding.pry
247
+ # table.select("SELECT * FROM #{table_name} ORDER BY id")
248
+ # SELECT * FROM marketo_leads ORDER BY id
249
+
@@ -0,0 +1,63 @@
1
+ # encoding: UTF-8
2
+ # !!! JRUBY 1.7 REQUIRED !!!
3
+
4
+ # MARKETO CONNECTOR EXAMPLE
5
+ # Gets changes for Merge Leads since March 26th 2014. Creates a table if there is not already called leads in ADS. BULK INSERTS changed leads into leads table on ADS.
6
+
7
+
8
+ require 'gooddata_marketo'
9
+
10
+ MARKETO_USER = ''
11
+ MARKETO_KEY = ''
12
+ MARKETO_SUBDOMAIN = ''
13
+
14
+ GOODDATA_USER = ''
15
+ GOODDATA_PASSWORD = ''
16
+ GOODDATA_PROJECT = ''
17
+ GOODDATA_ADS = ''
18
+
19
+ #############
20
+ # #
21
+ # MARKETO #
22
+ # #
23
+ #############
24
+
25
+ client = GoodDataMarketo.connect(:user_id => MARKETO_USER, :encryption_key => MARKETO_KEY, :api_subdomain => MARKETO_SUBDOMAIN)
26
+
27
+ changes = client.leads.get_changes(:oldest_created_at => 'March 26th 2014', :filters => ['Merge Leads'])
28
+
29
+ changed_ids = changes.map { |c| c.id }
30
+
31
+ leads = client.leads.get_multiple(:ids => changed_ids, :type => 'IDNUM')
32
+
33
+ CSV.open("tmp_leads_#{Process.pid}.csv", 'wb') do |csv|
34
+ csv << leads.first.headers
35
+ leads.each do |lead|
36
+ csv << lead.to_row
37
+ end
38
+ end
39
+
40
+ #############
41
+ # #
42
+ # ADS #
43
+ # #
44
+ #############
45
+
46
+ dwh = GoodData::Datawarehouse.new(GOODDATA_USER, GOODDATA_PASSWORD, GOODDATA_ADS)
47
+
48
+ # Set up a Table & Import BULK CSV
49
+ table = Table.new :client => dwh, :name => 'changes'
50
+ table.import_csv(file)
51
+
52
+ # File.delete(file) # Clean up
53
+
54
+ # For each change load into the leads table
55
+ count = 0
56
+
57
+ # Print the ads additions
58
+ puts 'Print tables?'
59
+ input = gets.chomp
60
+ if input == "y" || input == "yes" || input == ""
61
+ table.select("SELECT * FROM #{table_name} ORDER BY id")
62
+ end
63
+
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'gooddata_marketo'
3
+ s.version = '0.0.1'
4
+ s.date = '2015-01-01'
5
+ s.summary = "Marketo SOAP/REST wrapper to CSV/GoodData ADS"
6
+ s.description = "A gem."
7
+ s.authors = ["Patrick McConlogue"]
8
+ s.email = 'patrick.mcconlogue@gooddata.com'
9
+ s.files = `git ls-files`.split("\n")
10
+ s.homepage = 'https://github.com/thnkr/connectors/tree/master/marketo'
11
+
12
+ s.required_ruby_version = '>= 1.9.3'
13
+
14
+ s.add_development_dependency 'aws-sdk', '~> 1.61.0'
15
+ s.add_development_dependency 'rubyntlm', '~> 0.3.2'
16
+ s.add_development_dependency 'rest-client', '~> 1.7.2'
17
+ s.add_development_dependency 'pmap', '~> 1.0.2'
18
+
19
+ s.add_runtime_dependency 'savon', '= 2.8.0'
20
+ s.add_runtime_dependency 'gooddata', '= 0.6.11'
21
+ s.add_runtime_dependency 'gooddata_datawarehouse', '= 0.0.5'
22
+
23
+ s.license = 'MIT'
24
+ end