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.
- Original Link: https://go.telnyx.com/rs/telnyx/images/Content_eBook_YourGuidetoChoosingtheRightVoiceAPI.pdf
- Rebrandly Branded Shortened Link: https://tlyx.co/eb-voiceapi
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.
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!).
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
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
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