Uploading to the Design Studio via API

Tyron_Pretorius
Level 9 - Champion Level 9 - Champion
Level 9 - Champion

Your marketing team churning out content? Uploading this content to the Design Studio (DS) 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.

 

As part of the marketing operations role, it is necessary to take content from the product marketing team and upload it to the DS 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 DS for easy location by either the sales or marketing team. Last but not least, a 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 DS
  • Getting a shortened version of the content link using ReBrandly
  • Uploading the Rebrandly link to Airtable
  • Creating the 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 API or you need a quick refresher then check out the Quick-Start Guide to the API to see how to make your first requests in Postman before transitioning to making requests in code or in the Zapier automation tool.

 

Also if you are looking for a course for learning the Marketo API then DM me 🙂

 

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 content performance tracking program.

 

vid ins.PNG

 

 

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 DS 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 DS 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.

 

Dropbox > DS > 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 zap in Zapier.

 

N.B. Although there is a Python library for the 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 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!).

 

Uploading a file from Dropbox to the Design StudioUploading a file from Dropbox to the Design Studio

 

 

Get Dropbox Link

 

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).

 

Upload Via REST API

 

After receiving the 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 Step 4). 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 DS 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 DS.

 

Rebrandly Aesthetic Link Shortening

 

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 API

 

Content stored and categorized in AirtableContent 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 Content Program

 

Cloning a program to track performance of the contentCloning a program to track performance of the content

 

 

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 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 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 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 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 DS (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 theUTM 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.

 

Updating the content performance tracking program and smart campaignsUpdating 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 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 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 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 API

 

Now that you have seen how the 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:

 

 

The content in this blog has been reviewed by the Community Manager to ensure that it is following Marketing Nation Community guidelines. If you have concerns or questions, please reach out to @Jon_Chen or comment down below.

1681
0