Marketo Design Studio Upload Via API

Your marketing team churning out content? Uploading this content to the Marketo Design Studio and setting up content performance tracking programs taking up a lot of your time? Take a look at how you can automate this process using the Marketo, Dropbox, Rebrandly, and Airtable APIs in Zapier.

Content Operations Introduction

As part of the marketing operations role, it is necessary to take content from the product marketing team and upload it to the Marketo Design Studio so that the content can be accessed when shared via blogs and social media posts. Since the Marketo content link is long and LinkedIn posts share the entire URL, ReBrandly can be used to get a custom branded and shortened link, which is more aesthetically pleasing e.g.

Additionally, Airtable can be used to store and categorize all the content links from your Marketo Design Studio for easy location by either the sales or marketing team. Last but not least, a Marketo program should be set up to track visits to the blog post containing the piece of content and email the content link when the download form is filled out.

Of course the process of 

  • Downloading the content (pdf, png, etc) from Dropbox
  • Uploading the content to the Marketo Design Studio
  • Getting a shortened version of the content link using ReBrandly
  • Uploading the Rebrandly link to Airtable
  • Creating the Marketo program to track content performance and to send content to customers

can be done manually, but if you have multiple pieces of content to upload on a weekly basis then it is worth streamlining the handoff from the content marketing team and then automating the 5 tasks above using the Dropbox, Marketo, ReBrandly, and Airtable APIs from within Zapier.

The Github repo containing all the code used within the Zapier actions described below can be found here.

N.B. If it is your first time using the Marketo REST API or you need a quick refresher then check out the Marketo API Quick-Start Guide to see how to make your first Marketo REST API requests in Postman before transitioning to making requests in code or in the Zapier automation tool.

Take a look at the video below to get a walk-through of how each step within Zapier is set up and get a look inside the Marketo content performance tracking program.

Marketo Design Studio Upload Walkthrough Video

Marketo Design Studio Upload Request Google Form

The first step in the process is to obtain the Content Type, Content Name, ReBrandly Slash Tag, Dropbox Asset Path, and hosting page URL from the content marketing team using a Google form.

Content Name

The file will be named as Asset_ContentType_ContentName in the Marketo Design Studio by the Python code in Zapier so when filling out the form the Content Type should not be included in the Content Name or else it will appear twice in the Marketo file name.

For example the “Apple” case study Content Name should just be “Apple” so that the name in the Marketo Design Studio will then be Asset_CaseStudy_Apple

Only use spaces as separators i.e. no underscores, colons etc should be used to separate words, and avoid long names since this name will be used in the Marketo file name e.g. “Your Guide to Better Leveraging Conversational AI” should be shortened to just “Conversational AI” so that the filename will be Asset_eBook_ConversationalAI.

Rebrandly Slash Tag

This is the part of the Rebrandly url that appears after the custom domain i.e. for an ebook the slash tag could be “eb-market2020” and the full Rebrandly link would be https://yourcompany.co/eb-market2020

As a suggestion, the slashtag can follow the following formats for each piece of content where name is an abbreviated version of the content’s title (so that the ReBrandly URL stays short and looks nice) without any separators between words and in lower case e.g. the abbreviated names for “Modernize Your Call Tracking Application For Today’s Marketing” and “The Better Twilio Alternative” can simply be “calltracking” and “twilioalt”.

  • Case Study: cs-name
  • eBooks: eb-name
  • Fact Sheets: fs-name
  • Infographics: in-name
  • Whitepaper: wp-name
  • Guide: gd:name

Dropbox Path for Content

The path should look similar to the example below and can be obtained by right-clicking on the desired asset from a list view and selecting “Copy Link Address” (see demo video). Note that when copied there may also be querystring parameters appended after the asset path such as in the example below, these can be left alone or removed if desired.

https://www.dropbox.com/preview/Telnyx/Departments/BizOps/Growth/Design/Messaging/Fax/Factsheets/Factsheet_Fax/Factsheet_Fax.pdf?role=work

Blog post link

This is the link to the web page that will host the content download form and the link is provided here so that visits to this webpage can be tracked in Marketo

Dropbox > Marketo Design Studio > Rebrandly > Airtable

Once the content information is obtained from a Google form the information then gets stored in a Google sheet row, which in turn triggers the “Get Submission from Google Form” action of the “Marketo Design Studio Upload” zap in Zapier.

N.B. Although there is a Python library for the Marketo REST API, which allows you to make requests in one line of code by passing parameters to functions of the library, the Python integration in Zapier does not have this library installed. This is why in each of the Marketo actions defined below, we have to make the HTTP requests to the Marketo REST API endpoints using the Python requests library as well as specifying all the ancillary information needed to make the request i.e. headers and payload.

So be wary when building Python scripts outside of Zapier. Always check in Zapier first that the libraries you want to use are installed (I will share an ordeal I had when finding a workaround for Beautiful Soup not being installed on Zapier’s version of Python in a future post…. spoiler alert: it was not fun!).

Screenshot of the Zapier actions used to upload a file from Dropbox to the Marketo Design Studio, get a Rebrandly shortened link for the Marketo file url, and upload the Rebrandly link to Airtable
Uploading a file from Dropbox to the Marketo Design Studio

The “Get Dropbox Temporary Link” action (get Python code for Zapier Step 2: Get Dropbox Temporary Link) makes a request to the get_temporary_link endpoint passing the path to the asset in Dropbox and then parses the response to obtain the link to download the asset using the Python regular expression below.

link = re.search('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', response.text).group(0)

It is important that this asset path from Dropbox is correct or else the request to the get_temporary_link endpoint via the Dropbox API will not work (see the “Dropbox Path for Content” section above).

Marketo Design Studio Upload Via REST API

After receiving the Marketo API access token (get Python code for Zapier Step 3: Get Marketo Access Token), the zap then proceeds to make a request to the files endpoint to upload the piece of content using the Dropbox temporary link (get Python code for “Zapier Step 4: Upload File to Marketo Design Studio”). The urlib.request.urlopen method is used to access the Dropbox file, from which the file extension and mime type can be extracted for later use in naming and then uploading the file.

f = urllib.request.urlopen(dropbox_temporary_link)
mime_type = f.info().get_content_type()
f_ext = f.info().get_content_type().split("/")[1]

The final preparation step before uploading the content is to use the content_type dictionary to identify the folder that the content should be uploaded to as well as to get part of the name for the file. This is done by passing the content type to the dictionary as a key and then accessing the first and second elements of the list returned to get the naming piece and the Marketo Design Studio folder ID respectively.

content_type = {"Case Study": ["CaseStudy", "169"] , "eBook":["eBook","1569"], "Fact Sheet":["FactSheet","2076"], "Infographic":["Infographic","2070"], "Guide":["Guide","2076"], "Whitepaper":["Whitepaper","2067"]}

After the upload request is made, the response is parsed to obtain the URL of the newly uploaded file in the Marketo Design Studio.

The first step of the “Get Rebrandly Link” action (get Python code for Zapier Step 5: Get Rebrandly Link) is to determine the destination URL of where the Rebrandly shortened link should point. In order to track visits to PDF content, Sanford Whiteman’s redirector page is the initial destination. Then using JavaScript code embedded on this page you will get redirected to the URL of the PDF asset (http://example.com/redirected.pdf) that is appended to the redirector landing page URL (http://pages.example.com/redirector).

http://pages.example.com/redirector#http://example.com/redirected.pdf

Note that this redirector does not work for images (png, jpg etc) and so if the asset is an image, conditional logic ensures that the redirector URL is not prepended to the asset link.

Once the destination URL has been obtained, it is passed along with the Rebrandly domain, and slashtag in a request to the https://api.rebrandly.com/v1/links endpoint (see Rebrandly docs here). 

The returned response is then parsed to obtain the Rebrandly shortened link, which will have the following format:

https://rebrandly_domain/slash_tag

where the slash tag is the string provided by the marketing team in the Google form fill (see “Rebrandly Slash Tag” section above).

Uploading to Airtable Via REST API

Screenshot of the marketing assets from the Marketo Design Studio stored in Airtable
Content from the Marketo Design Studio stored and categorized in Airtable

Airtable has a similar layout to Google sheets, where there will be a collection of assets e.g. “Marketing Assets”, which will have a table (similar to a tab in Google sheets) for each content type e.g. “eBooks”, “Fact Sheets”, “Guides” etc. Airtable has cool API docs specific to each collection of assets you have in Airtable. Once you arrive at the API landing page, you can then select the collection of assets you want to interact with and then you will be brought to a REST API docs page tailored to that collection of assets (get the Python code for Zapier Step 6: Upload Row to Airtable).

The content_type dictionary takes the c_type variable as a key and returns the list of values for that key, where the first index contains the content type id and the second index contains the URL encoded name of the table in Airtable. This URL encoded name is then appended to the base Airtable URL to get the full post_url that will be used as the post request destination:

post_url = "https://api.airtable.com/v0/apppRyxNabc5LTYeR/"+content_type[c_type][1]”

Next, the payload of the response is populated with the values for the “Content Name”, “URL”, “Content Type”, and “Last Updated” header values. The “Content Type” field is a dropdown menu and in order to select a dropdown value the id of the value needs to be known. These dropdown id values are then accessed through the first index of the list returned for a content key from the content_type dictionary (see paragraph above).

If you are wondering where to find the ids for a dropdown list in your table, comment below and I’ll help you find them 🙂

Once the payload has been populated it is then put in JSON format using the json.dumps() method and passed in the post request to the post_url. The response text is then returned at the end of the script so that it can be analyzed once the script has run to make sure that the new row was added successfully.

Creating Marketo Content Program

Screenshot of the Zapier actions to clone a program to track the performance of the asset uploaded to the Marketo Design Studio
Cloning a program to track performance of the content uploaded to the Marketo Design Studio

Get Folder ID

The first step of the “Get Marketo Folder ID” action is to make a request to the folder by name endpoint to check if the folder name “YYYY Folder_Name” exists for the content type (get the Python code for Zapier Step 7: Get Marketo Folder ID).

If the folder does not exist then the content_type dictionary is used to find the parent folder id for the content type and a request is then made to the folders endpoint to create the “YYYY Folder_Name” folder within this parent folder. The folder id is then stored as a string in the info variable i.e. info = "New:"+fid.

Else the program was found successfully and the folder id is stored as a string in the info variable info = "Existing:"+fid.

Get Latest Program ID

If “Existing” exists in the folder_info string then this means that there is at least one Marketo program in this folder from the previous time that this zap ran. Therefore, the id of the folder that needs to be searched can be parsed straight from the folder_info variable (get the Python code for Zapier Step 8: Get Latest Marketo Program ID).

Else “New” exists in the folder_info string meaning that the “YYYY Folder_Name” folder was newly created in the previous step and is empty of any Marketo programs. This means that the previous year’s folder id i.e. “YYYY-1 Folder_Name”, must be obtained, by making a request to the folder byName endpoint, in order to find the most recent Marketo program for this content type.

Once the correct folder id has been obtained, it is then passed as the root to the folders endpoint to return all programs within this folder. The findall regex function is then used to find all instances of the regular expression below from the response that is returned from the previous request.

"createdAt":"\d*-\d*-\w*:\d*:\w*\+\d*","updatedAt":"\d*-\d*-\w*:\d*:\w*\+\d*","url":"https://app-ab20.marketo.com/#PG\w+","folderId":{"id":\d*,"type":"Program"}

The list containing these instances i.e. dates, is then sorted in reverse order so that the instances with the most recent createdAt date will be at the top of the list. Once the correct order has been established the "folderId":{"id":(\d*),"type":"Program"} regular expression is used with the findall function to isolate all program ids in the same order and store them in the program_ids list. Therefore, the program id of the most recently created program will now be the first index of the program_ids list.

N.B. That there is a simpler way to obtain the latest program id by using the max method in Python as shown below. Each successive program in Marketo will have a program id number 1 digit higher i.e. program_id = n+1 than its predecessor program_id = n. Therefore, the most recent program in a list will have the highest program_id number and can thus, be extracted using the max() method.

raw=response.text
pattern = '"folderId":{"id":(\d*),"type":"Program"}'
program_ids = re.findall(pattern, raw)
latest_id= max(program_ids)

Clone Latest Program

The latest program id is then passed in a request to the program clone endpoint along with the parent folder id to create a new program for the piece of content just uploaded to the Marketo Design Studio (get the Python code for Zapier Step 9: Clone Latest Marketo Program).

Get UTM Parameters from Google Sheet

UTM parameters are appended to each link within the piece of content (if it is a PDF) so that any visits to our site from the PDF can be tracked by a smart campaign (see how page visits with UTM parameters can be tracked in the Marketo UTM Tracking & Automation post). This step searches from the bottom up of the UTM Builder Content sheet to find the latest row which will contain the querystring of UTM parameters that are appended to each link within the PDF.

Screenshot of the Zapier actions used to update the content performance tracking program and smart campaigns in Marketo
Updating the content performance tracking program and smart campaigns

Update Program Tokens

The token names to be updated are collected in a list called token_names and a corresponding list token_values contains all the values that the respective tokens need to be updated with (get code for Zapier Step 11: Update Marketo Program Tokens). Once all the token values have been populated within the token_values list, a for loop is then used to iterate through each token name, passing each name and the corresponding value to a request to the program tokens endpoint, thereby updating each token with the desired value.

Get & Rename Email

The Marketo content performance tracking program contains an email that is used to send the piece of content out to someone when they fill out the form to request the content. Provided that the piece of content is not a factsheet or infographic, which are not gated and do not get emailed out, then a request is made to the emails endpoint to get the email id from within the parent content program (get the code for Zapier Step 12: Get Marketo Email ID). Then in Step 13 this email id is appended to the email endpoint url so that the name of the email can be updated for the current content program (get the code for Zapier Step 13: Rename Marketo Email).

Get & Update Smart Campaigns

The Marketo content performance tracking program contains smart campaigns that are used to track when someone views/requests a piece of content, when they open a link within a piece of content leading to our website, and to track any conversions (contact sales or sign-up) that occur after they have interacted with the content (see how to track conversions after page visits with UTM parameters in the Marketo UTM Tracking & Automation post).

A request is made to the smart campaigns endpoint passing the content program id in order to get all the smart campaign ids within this program (get the code for Zapier Step 14: Get Marketo Smart Campaign IDs). In Step 15 these ids are parsed from the response and stored in a list (get the code for Zapier Step 15: Update Marketo Smart Campaign Descriptions).

A for loop is then used to iterate through the list of smart campaign ids and make a request to the id specific smart campaign endpoint i.e. /rest/asset/v1/smartCampaign/+sc_id+.json, to update the campaign description to contain the querystring that is appended to links within the content PDF.

These two steps are not strictly essential but since a lot of these smart campaigns require this content querystring in their smart list or flow it makes it easier to populate these smart campaigns by just copying the querystring from the description.

Unlock More With The Marketo API

Now that you have seen how the Marketo API can be used to automate repetitive workflows, take a look at the posts below to get more inspiration and ideas for processes that you can automate:

As always if you are enjoying this content and want to get an email when I launch a new post then hit that shiny, pink, subscribe button at the top of the page 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *