Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,25 @@ lead = client.sync_lead(
)
```

## Sync Multiple Leads

This fucntion updates multiple lead records from Marketo. If a lead without a matching email isn't found in the database, a new one is created. The request returns a list of results detailing creation/update/failure for each lead.

```python
result = client.sync_multiple_leads(leads = (
('[email protected]', (
('City', 'string', 'Toronto'),
('Country', 'string', 'Canada'),
('Title', 'string', 'Web Developer'),
)
),
('[email protected]', (
('Phone', 'string', '5551234567'),
)
)
))
```

## Request Campaign

This function triggers a Marketo campaign request (typically used to activate a campaign after a user has filled out a form). This requires the numeric ID of both a campaign and the lead that is to be associated with the campaign. Returns True on success.
Expand Down Expand Up @@ -111,4 +130,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 changes: 15 additions & 1 deletion marketo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import requests
import auth

from marketo.wrapper import get_lead, get_lead_activity, request_campaign, sync_lead
from marketo.wrapper import get_lead, get_lead_activity, request_campaign, sync_lead, sync_multiple_leads


class Client:
Expand Down Expand Up @@ -108,3 +108,17 @@ def sync_lead(self, email=None, attributes=None):
return sync_lead.unwrap(response)
else:
raise Exception(response.text)

def sync_multiple_leads(self, leads=None, create_duplicates=False):

if not leads or not isinstance(leads, tuple):
raise ValueError('Must supply leads as a non-empty tuple.')

body = sync_multiple_leads.wrap(leads, create_duplicates)

response = self.request(body)

if response.status_code == 200:
return sync_multiple_leads.unwrap(response)
else:
raise Exception(response.text)
20 changes: 20 additions & 0 deletions marketo/wrapper/result_record.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

class ResultRecord:
def __init__(self):
self.leadId = ''
self.status = ''
self.error = ''

def __str__(self):
return "Lead %s - Result: %s (error: %s)" % (self.leadId, self.status, self.error)

def __repr__(self):
return self.__str__()

def unwrap(xml):
result = ResultRecord()
result.leadId = xml.find('leadId').text
result.status = xml.find('status').text
result.error = xml.find('error').text

return result
33 changes: 33 additions & 0 deletions marketo/wrapper/sync_multiple_leads.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import xml.etree.ElementTree as ET
import lead_record, sync_lead, result_record

def wrap(leads=None, create_duplicates=False):

ret = (
'<mkt:paramsSyncMultipleLeads>' +
'<leadRecordList>'
)

for lead in leads:
wrapped_lead = sync_lead.wrap(email=lead[0], attributes=lead[1])
ret += wrapped_lead[wrapped_lead.index('<leadRecord>'):wrapped_lead.index('</leadRecord')+13]


ret += (
'</leadRecordList>' +
'<dedupEnabled>' + ('false' if create_duplicates else 'true') + '</dedupEnabled>' +
'</mkt:paramsSyncMultipleLeads>'
)

return ret

def unwrap(response):
root = ET.fromstring(response.text)
resultList = root.find('.//result')

unwrappedList = []

for result in resultList.findall('.//syncStatus'):
unwrappedList.append(result_record.unwrap(result))

return unwrappedList