This is a post from Philippe Delle Case, Principal Solutions Consultant, Marketo.
Objectives
This article explains in detail how to integrate Marketo with potentially over 500 Cloud Apps, thanks to Zapier.
For that, we’re going to build from scratch a Zapier connector for Marketo and implement two practical integration use cases:
Use Case 1: Unidirectional Leads integration from FullContact Card Reader to Marketo
- Scan any contact’s business card with the FullContact mobile Card Reader app and get a lead automatically created in Marketo.
Use Case 2: Bidirectional Leads integration between Marketo and Google Sheets
- Add an existing lead to a static list in Marketo and find the lead automatically added to your Google Sheet.
- Modify any lead in your Google Sheet and find the change echoed back to Marketo.
Prerequisites
Sign-up for a free account with Zapier
Zapier is a web app Automation Service that lets you easily automate tasks between other online apps without the need for programmers or any IT resources. A brief introduction can be found here. Today Zapier supports more than 500 apps in many different domains such as Marketing, CRM, CMS, Customer Support, Electronic Signature, Forms, etc.
A single integration between one app and another is called a Zap. Check Zapier’s zapbook for an exhaustive list of supported web apps.
Sign up for a free account here. You’ll get access to up to 100 tasks/month, 5 zaps, and zaps running every 15 minutes. You can of course get much more by subscribing to Zapier’s paid plans (basic, business, business plus, etc.)
Access to a Marketo Instance as Administrator or with a provided API User account
Our Zapier connector will use the Marketo REST API to push Lead data to Marketo. In order to use this API, you’ll need an API User and a Custom Service that you can create yourself if you are administrator of your Marketo instance. If not, then an administrator will need to provide those to you. There is also a Webhook to create, only accessible to a Marketo Administrator.
A step by step explanation of how to create the Marketo API User and the Custom Service can be found here.
Once you’re done, you should have the following credentials in order to invoke the Marketo REST API: Client Id, Client Secret, Munchkin Account Id
- Munchkin Account Id
You can get the Munchkin Account Id from the Munchkin or the Web Services Admin screens. Its pattern looks like this: 000-XXX-000.
No need to get an access token as it would be only valid for a single hour. The Connector will generate tokens for you automatically.
Sign-up for a free account with Google
Google Docs, Sheets, and Slides are productivity apps that let you create different kinds of online documents, work on them in real time with other people, and store them in your Google Drive online. Our use case needs a Google Sheet.
Different features of Google Docs and creation of an account with Google can be found here.
Sign-up for a free account with FullContact
FullContact keeps you fully connected to the people who matter most by pulling in all your contacts and continuously syncing them with changes to social profiles, photos, email signatures, company information, and more. They offer a mobile business cards reader that can scan cards into 250+ Web Apps, including Zapier.
You can sign-up for a free account here. You may also subscribe to a premium paid account with more features and capacity.
The mobile app can be downloaded from the Apple AppStore, or from Google Play.
The FullContact Zaps are documented here.
Implementation of the Marketo Connector for Zapier
Create the Marketo App
From the Zapier web interface, go to the Developers Portal.
Click Add New App and fill out at minimum the Title (e.g. ‘Marketo’) and the Description. The logo is optional, but nice to have.
Authentication
In this section we declare the different fields used for the Marketo REST API authentication and the authentication settings.
Create first the following fields:
Label | Munchkin Account Id | Client Id | Client Secret |
Key | munchkin_account_id | client_id | client_secret |
Type | Unicode | Unicode | Unicode |
Required | Checked | Checked | Checked |
Edit the ‘Authentication Settings’ as in the following screen:
- Auth Type: Session Auth
- Auth Mapping:
{
“access_token”:”{{access_token}}”
}
- Access Token Placement: Token in Querystring
Once a Marketo custom service has been created, client id and client secret become available. We use the client id and client secret to generate an access token via the REST API Authentication endpoint. We can then use this access token to make subsequent requests to the REST API. The token expires after an hour and must be generated again to proceed calling the REST API.
We chose authentication Type = ‘Session Auth’ as it allows us to execute a custom authentication script every time our session token is expired. We’ll see in the section ‘Scripting API’ how to implement this mechanism that can only work with this type of authentication.
Triggers
Zapier Triggers are there to bring data into Zapier. We do not need one for our use cases as we will leverage a Marketo Webhook instead. However, we still need to write a dummy Trigger as a mandatory test for our Marketo connector.
We are going to create a Test Trigger calling the Marketo REST API Get Daily Usage endpoint.
Click Add New Trigger to start the wizard and fill-up the following fields (fields not mentioned can be left blank):
Name and Description
- Name: Test Trigger
- Key: test_trigger
- Description: The Test Trigger of the Marketo App
- Important? Not checked
- Hide? Checked
Trigger Fields
- None
Where Data Comes From
- Data Source: Polling
- Polling URL: https://{{munchkin_account_id}}.mktorest.com/rest/v1/stats/usage.json
Sample Result
- Leave blank
Click Manage Trigger Settings and set our Test Trigger to be the one we’ll use to verify a user’s credentials.
Actions
Zapier Actions are there to send data out from Zapier.
We are going to implement the Create_Update Lead Action calling the Marketo REST API Create/Update Leads endpoint. This Action will allow us to create a new lead within Marketo, or if the lead already exists, it will update it with the submitted values. We’ll use the field ‘email’ for de-duplication.
Click Add New Action to start the wizard and fill-up the following fields (fields not mentioned can be left blank):
Name and Description
- Name: Create_Update Lead
- Noun: Lead
- Key: create-update-lead
- Description: Create a new lead within Marketo, or if the lead already exists update it with the submitted values
- Important? Checked
- Hide? Not Checked
Action Fields
Action Fields are the fields users will map data into. Choose them carefully according to your own needs as they will represent all the data you will be able to update in Marketo. There is an option in Zapier to offer to the end user all fields available in Marketo, but that would induce more code and complexity, not required for a disposable connector.
As an example, we selected the following fields:
Label | Key | Type | Required? | Parent key | Send in POST by default? |
Email Address | Unicode | Checked | input | ||
Partition Name | partitionName | Unicode | Not Checked | Checked | |
First Name | firstName | Unicode | Not Checked | input | |
Last Name | lastName | Unicode | Not Checked | input | |
Phone Number | phone | Unicode | Not Checked | input | |
Notes | Lead_Notes__c | Textarea | Not Checked | input | |
Called | called | Unicode | Not Checked | input |
Partition Name is mandatory in our case since our Marketo instance has Lead Partitions in service. It could be omitted otherwise. We separated it from the ‘input’ group so the end-user understands this is not a field to synch.
The field ‘Notes’ comes from a synch between Marketo and Salesforce, do not use it if you don’t have it in your Marketo instance.
The field ‘Called’ has been created in our Marketo instance, do not use it if you don’t have it in your Marketo instance.
Of course, the goal is to let you pick the fields you need from Marketo. It is recommended to start small and add the extra fields later.
Where to Send Data
- Action Endpoint URL: https://{{munchkin_account_id}}.mktorest.com/rest/v1/leads.json
Sample Result
- Leave blank
Zapier Scripting API
Zapier’s scripting feature allows you to manipulate the requests and responses that are exchanged between your app’s API and Zapier. You can modify HTTP requests just before they are sent and can parse responses before Zapier does anything with them. We need it in order to complete our custom ‘Session Auth’ authentication so it works with Marketo. More information here.
Copy the following code and we’ll go through some explanations later on:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
var Zap = { get_session_info: function(bundle) { console.log('Entering get_session_info method ...'); var access_token, access_token_request_payload, access_token_response; // Assemble the meta data for our Access Token swap request console.log('building Request with client_id=' + bundle.auth_fields.client_id + ', and client_secret=' + bundle.auth_fields.client_secret); access_token_request_payload = { method: 'POST', url: 'https://' + bundle.auth_fields.munchkin_account_id + '.mktorest.com/identity/oauth/token', params: { 'grant_type' : 'client_credentials', 'client_id' : bundle.auth_fields.client_id, 'client_secret' : bundle.auth_fields.client_secret }, headers: { 'Content-Type': 'application/json', // Could be anything. Accept: 'application/json' } }; // Fire off the Access Token request. access_token_response = z.request(access_token_request_payload); // Extract the Access Token from returned JSON. access_token = JSON.parse(access_token_response.content).access_token; console.log('New Access_Token=' + access_token); // This will be mixed into bundle.auth_fields in future calls. //bundle.auth_fields.access_token=access_token; return {'access_token': access_token}; }, test_trigger_pre_poll: function(bundle) { console.log('Entering test_trigger_pre_poll method ...'); bundle.request.params = { 'access_token':bundle.auth_fields.access_token }; return bundle.request; }, test_trigger_post_poll: function(bundle) { console.log('Entering test_trigger_post_poll method ...'); var data = JSON.parse(bundle.response.content); if ((!data.success)&&((data.errors[0].code=="601")||(data.errors[0].code=="600"))){ console.log('Access Token expired or invalid, requesting new one - data.success=' + data.success + ', data.errors[0].code=' + data.errors[0].code); throw new InvalidSessionException(); // Calling get_session_info() to regenerate Access Token } return JSON.parse(bundle.response.content); }, create_update_lead_pre_write: function(bundle) { bundle.request.params = {'access_token':bundle.auth_fields.access_token}; return bundle.request; }, create_update_lead_post_write: function(bundle) { var data = JSON.parse(bundle.response.content); if ((!data.success)&&((data.errors[0].code=="601")||(data.errors[0].code=="600"))){ console.log('Access Token expired or invalid, requesting new one - data.success=' + data.success + ', data.errors[0].code=' + data.errors[0].code); throw new InvalidSessionException(); // Calling get_session_info() to regenerate Access Token } return JSON.parse(bundle.response.content); } }; |
Methods
get_session_info
- This method is responsible for generating or regenerating an access token calling the Marketo REST API Authentication endpoint.
- It is called every time any ‘post_poll’ method encounters an ‘Access Token Expired’ error. An access token is scheduled to expired every 1 hour so this is expected.
- Action Endpoint URL: https://{{munchkin_account_id}}.mktorest.com/identity/oauth/token
pre_poll, pre_write
- We must create a ‘pre-poll’ method on any Trigger we have created, in order to modify the HTTP request just before it is sent, so we can add the Marketo Access Token in its parameters.
- We must create a ‘pre-write’ method on any Action we have created, for the same reason.
post_poll, post_write
- We must create a ‘post-poll’ method on any Trigger we have created, in order to parse responses before Zapier does anything with them, and eventually intercept ‘Access Token Expired’ error.
- We must create a ‘post-write’ method on any Action we have created, for the same reason.
- If such an error has occurred, we throw an InvalidSessionException that will tell Zapier to replay the authentication and execute again the get_session_info method.
Note that you can access the Bundle logs from the Scripting API from the ‘Quick links’ menu on the top right corner of the screen. This is really useful to debug the scripts.
And now it’s time for the fun part…
Use Case 1: Integration of Marketo with FullContact Card Reader
For this integration we’ll create one single Zap from FullContact to Marketo. With this Zap, you’ll be able to scan business cards with the FullContact Mobile Card Reader and push the leads to Marketo.
From the Zapier Dashboard click the button ‘Make a new Zap’.
Trigger in Zapier
- Pick the App FullContact
- Choose FullContact Trigger ‘New Business Card’
- Connect to your FullContact account
- Test the FullContact App
Action in Zapier
- Pick the App Marketo we just created earlier, it should display in Beta
- Choose Marketo Action ‘Create_Update Lead’
- Connect to your Marketo account, filling up the authentication parameters (Munchkin Account Id, Client Id, Client Secret)
- Map the fields from FullContact to Marketo
- Fill-up eventually a Partition Name where your new leads should go (only if partitions exist in your Marketo Instance)
- Test the Marketo App
- Activate your Zap
Note: Make sure you download the business cards Reader from FullContact and activate the Zapier Integration right from your mobile device.
Use Case 2: Integration of Marketo with Google Sheets
For this integration we’ll create two Zaps. One from Marketo to Google Sheets and another one from Google Sheets to Marketo. With this Zap, you’ll be able to synch up some of your leads or contacts between Marketo and a Google Sheet.
Zap Marketo Webhook -> Google Sheets
For the first Zap, we don’t rely on a custom connector for Marketo, but we leverage Marketo’s Webhooks and the ‘Webhooks by Zapier’ Trigger.
From the Zapier Dashboard click the button ‘Make a new Zap’.
Trigger Part 1 in Zapier
- Pick the ‘Webhooks by Zapier’ Trigger App
- Check ‘Catch Hook’ that will allow to wait for a POST or GET to a Zapier URL
- No need to pick off a child key
- Zapier generated a custom webhook URL for you to send requests to, copy it in the clipboard
Webhook in Marketo (steps to be done by an Administrator)
- Go to Admin -> Webhooks
- Create a new Webhook called ‘Push Lead to Zapier’ and edit the Webhook form:
In the template’s field, declare all the Lead’s fields you would like to transfer to Zapier and leverage the Marketo’s tokens. For our Use Cases, we take the same fields we defined for the custom Zapier connector that push Leads to Marketo:
1 2 3 4 5 6 7 8 9 10 |
{ "firstName":"{{lead.First Name}}", "lastName":"{{lead.Last Name}}", "email":"{{lead.Email Address}}", "phone":"{{lead.Phone Number}}", "leadOwner":"{{lead.Lead Owner First Name}} {{lead.Lead Owner Last Name}}", "leadOwnerEmail":"{{lead.Lead Owner Email Address}}", "leadNotes":"{{lead.Lead Notes:default=edit me}}", "called":"{{lead.Called}}" } |
- Save the form
- No need for a Response Mapping, so you’re done with the Webhook
Test Campaign in Marketo (steps to be done by a Marketer or an Administrator)
- From the Marketing Activities, create a new Smart Campaign
For testing purpose we are going to create a campaign that triggers our Webhook each time a lead status changes to MQL. Of course you can use the Webhook for any other business purpose.
- Edit the Smart List
- Call the Webhook in the Flow
- Schedule the Campaign
- Make sure each lead can run through the flow every time
- Activate the Smart Campaign
Trigger Part 2 in Zapier
- In order to complete the ‘Webhooks by Zapier’ Trigger App, we need to fire the Marketo Smart Campaign once and catch the Webhook in Zapier
- In our test case, we just need to go to Marketo Lead Database, open a lead and change its status to ‘MQL’
Create the spreadsheet in Google Sheets
- Create a new spreadsheet
- Create a Worksheet or use the default one
- Add a column for each field you want to synch from Marketo (the ones declared in the Marketo webhook)
Action in Zapier
- Pick the App Google Sheets
- Check the option ‘Create Spreadsheet Row’
- Connect to your Google Sheets account
- Select your Google Sheets spreadsheet
- Select the Worksheet
- Map all the fields between the ‘Webhooks by Zapier’ Trigger App and Google Sheets:
- Test the Google Sheets App
- Activate your Zap
From the Zapier Dashboard click the button ‘Make a new Zap’.
Trigger in Zapier
- Pick the ‘Google Sheets’ Trigger App
- Tick the ‘Updated Spreadsheet Row’ that triggers when a new row is added or modified in a spreadsheet
- Connect to your Google account
- Select the Spreadsheet you want to trigger from (should be the same one used in the previous Zap) and the Worksheet
- Set Trigger Column to ‘any_column’
- Test the Google Sheets App
Action in Zapier
- Pick the App Marketo we just created earlier, it should display in Beta
- Choose Marketo Action ‘Create_Update Lead’
- Connect to your Marketo account, filling up the authentication parameters (Munchkin Account Id, Client Id, Client Secret)
- Map the fields from Google Sheets to Marketo
- Fill-up eventually a Partition Name where your new leads should go (only if partitions exists in your Marketo Instance)
- Test the Marketo App
- Activate your Zap
Conclusion
Here are some ideas for improvement for our Marketo connector for Zapier:
- Adding other Triggers and Actions related to diverse Marketo objects (Lists, Custom Objects, etc.)
- Instead of hard coding the fields from Marketo, it’s possible to dynamically pull the fields from Marketo, but that would require some technical translation work between Marketo and Zapier.
- Sharing the connector with development team and eventually make it generally available.
It is possible that Zapier will deploy a Premium Marketo adapter, which would make it much easier to implement our use cases. In any event, this article could always be leveraged to integrate Marketo with Zapier with a free Zapier plan, and also to build custom use cases that might not be supported by a premium adapter.
We hope you enjoyed this article and that it will help you to be even more successful with Marketo and Zapier. Thank You!