Category: Marketo

  • Is your marketing pipeline data leak-proof?

    Is your marketing pipeline data leak-proof?

    Most companies rely on out-of-the-box reports from Salesforce to understand how their marketing efforts are translating to pipeline and revenue. The assumption is this data is accurate, yet there are flaws in how Salesforce tracks marketing impact. In fact, these flaws are big enough to cause as much as 50% of data about marketing sourced/influenced pipeline to be totally inaccurate in reports.

    It starts with how marketing impact is tracked on individuals — leads and contacts. If you’re like most, you’re writing to fields like Lead Source to track the first (or last) touch, and using campaigns to track the different programs that a given lead/contact has interacted with. These two data points — lead-level fields and campaign membership — are the basis for nearly all Salesforce marketing reports, and the reason why you can make statements like “we generated 200 leads from search engine marketing last month” or “50 people registered for the webinar”.

    It’s reasonable to assume that these same insights should translate well to tracking pipeline impact too, right? The answer, it turns out, depends on how the opportunity was created.

    Opportunities created through lead conversion

    If a lead flows through your funnel in a perfectly orderly way, the lead gets converted to an account, and an opportunity is generated. This is how Salesforce lead conversion is designed to work. When this happens, the new opportunity will automatically have the lead (now a contact) associated to it. The opportunity will also inherit key lead details, namely lead status, and any campaign history that the lead was a part of prior to being converted.

    With all this information attached to the opportunity, you can accurately say where the opportunity was sourced from, and even what influenced it. Since all this association of data happens automatically, you can safely rely on it for reporting purposes. Meanwhile…

    Opportunities created manually

    We all like to think our sales processes fit into a nice and tidy flowchart, yet the reality in most organizations is that opportunities get created through other ways than just lead conversion. For example, suppose an existing customer expresses interest in a new product. Since that customer wouldn’t be a lead in the system anymore, the sales rep will most likely create an opportunity directly from their existing account.

    The problem, though, is that a manually created opportunity won’t have a contact associated with it by default. This also means that marketing data like lead source or campaign history are often blank. It’s why your campaign pipeline reports never seem to add up properly with the total pipeline reports — if no one is added to the opportunity, no campaigns will be added either.

    Bottom line, manually-created opportunities, left to their own devices, make measurement of marketing impact completely unreliable. And this isn’t just an edge case. In nearly every Salesforce org I’ve seen, manually-created opportunities — those created outside of the typical lead conversion process — account for 50% or more of the total opportunities in the system. This means that 50% of your marketing pipeline data is just not accurate.

    You can quickly confirm how big of an issue this is in your organization by running a simple opportunity report, and checking how many lack a primary contact.

    The solution

    Never fear, this can be fixed, and without buying any specialized software. Work with your Salesforce admin to modify the default way opportunities can be created, and ask them to remove the ability for opportunities to be created anywhere besides a lead conversion, or directly from a contact. This requires a bit of customization to accomplish, but should be a relatively straightforward change for your admin. Just make sure you train your sales team on the new process, as you’ll want to ensure they still know how to create opportunities.

    You can also use 3rd party tools to address this issue, though they’ll come in handy later, when you’re trying to get more than just one contact on each opportunity. Just the step above will make a big difference to fill in gaps in your data.

  • Fallback Alerts: How to build a broken link warning system in Marketo

    Fallback Alerts: How to build a broken link warning system in Marketo

    You don’t want to provide a poor user experience or waste ad spend on broken links. Marketo has a default fallback page you can set to help prevent a totally stuck user, but this doesn’t help you fix broken links that you don’t know about. Wouldn’t it be great if you could be alerted whenever that page was visited, find out what page drove them to the 404, and fix the broken link right away?

    It’s actually pretty easy to do, and you can build this warning system it in about ten minutes.

    First you need to visit Admin > Landing Pages, and make sure you have some sort of uniqueness built in to your Marketo fallback URL. A lot of people use their main website 404 page, and others create a dedicated 404 for Marketo. Others just redirect to their homepage. You’re fine in any case (so long as whatever page you’re pointing to has munchkin on it) but you’ll want to edit the URL in the admin settings to include a custom querystring so you can properly identify traffic to that page from Marketo links versus other website traffic.Marketo Fallback Alerts

    Now build a simple email alert that you’ll use to send every time the fallback page is hit. The two key pieces to include here are the tokens:

    • {{trigger.referrer}} – this will pull in the referring URL that triggered the fallback page. This won’t tell you specifically the broken link, but it will tell you what page the broken link exists on, which is often* enough to identify the issue.
    • {{SP_Send_Alert_Info}} – the awesome system token Marketo provides to insert links to the corresponding record in Marketo or Salesforce. This is great in case {{trigger.referrer}} doesn’t provide anything useful – you can always drill into the activity log of the lead tosuss out why they hit the fallback page.

     

    marketo-fallback-email-alert

    Next, build a smart campaign in your operational program or whatever area you keep miscellaneous data management stuff, and have it trigger every time your fallback page is visited, with a modifier included to catch the querystring. You’ll also want to include some sort of filter that ensure the triggering lead is known to the database, such as “email address is not empty” (you used to be able to use “is anonymous = false, but thats no longer available). You need this because I’ve noticed anonymous leads still tend to trigger a smart campaign like this, which will result in a bunch of alerts with no information in them. Not super helpful.

     

    marketo-fallback-alert-trigger

    For the flowstep, send the alert to you or whoever needs to know to fix it. I like to include everyone who can modify affected domains – so a Marketo admin and a website manager are good places to start.

    marketo-fallback-alert-flowstep

     

    As a rule, I don’t like getting email alerts for much, but a broken link is high priority issue, and an easy one to fix at that, so an email alert feels appropriate here. That said, if you prefer, you could also log an interesting moment using the same {{trigger.referrer}} token, or assign a task too. It’s up to you.

    Once you get the alert, sometimes the referrer URL will be enough to allow you to hunt down the offending link, but even if it is not, you can always dig into the activity log of the lead who triggered it, and look at the web pages they’ve recently visited.

    *Note – This doesn’t always work when the referrer is a search engine or a direct visit, because in the former you can’t necessarily see the search query that drove them, and the latter has no referrer to track. Though in my experience, the most common offenders of broken links are on thank you pages, or the thank you page itself being set incorrectly on a form’s settings. In either of those cases, a lead would generally be known to Marketo, so your alert would properly notify you.

     

    All the credit for this idea goes to Adam New-Waterson, you can hear more about this topic from our presentation at Marketo Summit 2016.

     

  • New Lead Processing Queues

    New Lead Processing Queues

    Remember “PEMDAS” in school? That little trick to figuring out the right order of operations for solving algebra equations?

    So if you had to solve an equation like 4 x (3 + 4), PEMDAS would tell you to solve the stuff in the parentheses first before multiplying so that you’d get the correct answer.

    I find myself confronted with the same sort of “order of operations” conundrums in Marketo all the time. When a new lead is created, there are actions, like data value changes and program associations, that I want to ensure occur ahead of something else, such as a Salesforce sync. But these actions often exist in disparate areas, and there isn’t an obvious, direct way to control what happens first.

    Or is there?

    The Campaign is Requested/Request Campaign trigger & flowstep combination is a powerful way to allow control over the order of disparate triggers.

    Campaign is Requested

    Request Campaign

    Take a new lead creation action, as an example. For us, there are several data steps we want to occur before anything gets synced to Salesforce. For instance, we want to ensure the new lead isn’t missing any key values, like lead source, status, etc. We also want to ensure their country name/state name match an approved list of values (aka we want “United States”, not “USA” or “‘Merica”).

    Geographic Field Cleanup

    The essence of this is a chain of triggered smart campaigns that all use the “Campaign is Requested” trigger, and their flowstep ends with a “request campaign” flowstep, requesting the next campaign in the series.
    NewLeadQueue

    Here’s an example of how these chain together:

    1. Step 1: Lead Created (this one just watches for new leads created in the system, and kicks of the chain of actions)
      1. Trigger: Lead Is Created
      2. Flowstep: Request Campaign: Step 2
    2. Step 2: Clean up Lead Source & Type
      1. Trigger: Campaign is Requested
      2. Flowstep 1: If lead source is empty, populate with a default value
      3. Flowstep 2: if lead source is irregular, normalize it
      4. Flowstep 3: Request Campaign: Step 3
    3. Step 3: Fix Geographic fields
      1. Trigger: Campaign is Requested
      2. Flowstep 1:
        1. Choice 1: if Country is US, USA, United States of America, America etc, change value to “United States”
        2. Choice 2: if Country is “England, Scotland, etc” change value to “United Kingdom”
      3. Flowstep 2: Request Campaign: Step 4
    4. Step 4: Assign to a Nurture Program
      1. Trigger: Campaign is Requested
      2. Flowstep 1:
        1. Choice 1 If lead meets whatever criteria you use to assign to a nurture stream, add to engagement program
      3. Flowstep 2: Request Campaign – Continue until you reach the end of the chain

    The examples I’ve described above are primarily data management & manipulation, but a new lead processing queue can also be handy for engagement program assignment, or calling external services and webhooks. For example, suppose you use a lead enrichment tool that works via a webhook. Include that step as part of your new lead processing queue, and you can ensure all new leads get enriched as they enter the database.

    Completing the queue before a CRM sync

    While the processing queue can be extremely handy on its own, some special considerations come into play if you’re trying to ensure the queue occurs before a sync to your CRM.  . First consider all the activities that could sync a lead to Salesforce. This includes any existing smart campaigns that use the “Sync to Salesforce” or any other Salesforce related flowstep, along with any programs that are tied to a Salesforce campaign (This last one is the one most people forget).

    We’re heavy users of the program to campaign sync, so minding when the sync occurs relative to our processing queue is really important. We don’t want leads accidentally ending up in Salesforce before we get a chance to clean their data up. The way to prevent this is build in a wait step in front of any program status change steps. So if you have an event program with a smart campaign that updates a lead’s status to “Registered”, you need a wait step of a couple of minutes in front of the status change flowstep.

    Queue Diagram

    Unless you have a really long queue of complex actions, usually 2-3 minute wait steps is plenty. But if you really want to hone in on how long your queue takes to process, you can create timestamp fields for start and end times, and have the first campaign in your queue stamp leads on entry, and the final campaign stamp on completion. Then after you have a few weeks of data, export all the leads that ran through the system, and calculate the average time between start and end.

    A few caveats

    • I like to avoid excess use of trigger campaigns in Marketo where possible, as at scale, they can significantly degrade performance of the tool. In a way, this processing queue is beneficial in this regard, because you’re effectively consolidating many of your disparate trigger campaigns into a single, orderly list. However if you are a user with a database of significant size, you’ll want to thoroughly test out a processing queue such as the one above to confirm performance isn’t negatively impacted.
    • A longer processing queue can get a bit bogged down with big list imports or other batch creation of leads. So don’t rely on it here, as these may cause a spike in processing time, and may cause a sync to occur before the queue gets done processing.
    • Programs with a landing page and form in them will automatically assign a program status when a form is completed. It’s something Marketo does that you cannot disable, presumably as a safeguard if you were to build a program and forget to active your smart campaigns. This is super annoying. A way to get around this is by storing your landing pages in programs that are not tied to a Salesforce campaign, or by using the Add to Salesforce campaign actions instead of the program-campaign sync feature.

    Once you get a basic processing queue up and running, it’s super easy to expand and modify it. It also makes hunting down critical lead creation activities a breeze, since they’re all chained together in a nice, ordered list.

  • Program templates: Best-of-class in a bottle

    Program templates: Best-of-class in a bottle

    I’ve worked with companies using Marketo across large teams and small teams. Each has their own set of challenges, but one they share is the need for consistency and simplicity in their marketing programs.

    All too often, you’ll see organizations with programs that just don’t feel consistent, because they all have a different look and feel. And if the front-end looks disjointed, then all the behind-the-scenes structure, tracking, and reporting is at least as messy.

    It’s easy enough to spin up a new program in Marketo, or clone a prior program and adapt it, but real productivity comes with the use of templates for your programs. Meticulously created and maintained, these are your absolute best campaigns, and are your ticket to more predictable marketing efforts. With program templates, big teams benefit from better alignment and turnaround time. Yet even a one-person Marketo master can benefit from standardizing their processes in templates.

    Where do templates make sense?

    Your first step is identifying where templates actually make sense. Build a list of your most common use cases in Marketo. Do you run a lot of events in the field? Webinars? Downloadable content? Here’s my rule – anything I’m doing more than a few times a quarter is a prime candidate for a program template.

    Next, identify all the assets you might need in your program. For an event program, that may include invites, reminders and follow up emails, Registration and thank you landing pages. Plus all the smart campaigns for sending emails and tracking registrations.

    You want your templates to contain every possible asset you might need for most circumstances. There will still be occasions where you need to build something more custom, but these should become the exception to the rule once your templates are in place.

    Marketo Program Templates

    You should also use this opportunity to review your program channel tags. I prefer to maintain a small list of channel types in Marketo, as it helps keep your list of templates small too. For example, Marketo out of the box contains tags for tradeshows and roadshows. Yet these are built quite the same in Marketo. Unless you have major reporting needs that require this differentiation, I recommend collapsing these sub-types into broader categories, like “Event”, “Webinar”, “Content”, etc. Stay away from overly specific channel names, because it’s a pain to change the tags once the template has been created, and you ideally want to avoid maintaining a big list of templates.

    Once you’ve identified your key use-case programs, and all the assets they need, build out everything in a shell template program, but leave the content of everything empty for now, because you’ll be setting tokens for most of it.

    Token Time

    Next you’ll want to tackle the setup of your program tokens. While you can follow any naming convention you like, it’s important to remain consistent, and record these token names in a document somewhere. I like to use a spreadsheet to log every token name, its type, and its intended use case.

    To help keep your list of tokens tight, think of how a particular token can be used globally, across several different templates. In other words, avoid tokens like {{my.Webinar Invite Email Subject Line}}, and instead pick a more generic name like {{my.Email – Invite – Subject Line}}, that can be used across different templates. Remember, in most cases this won’t just be you working with these templates, so sticking to a standard system will keep tokens easier to remember, and more versatile if you need to adapt them to new templates later.

    Tokens work great for front end content on your assets, and can be used anywhere in your emails and landing pages. So for an invite email, you may set a token for the sender email, the subject line, the banner image URL, the headline, and even the body text. For a landing page, you may set tokens for your headline, the body content of the page, the header on the form, and even for hidden values on the form itself. For smart campaigns, tokens are helpful for change data value actions and interesting moments. A great use case is logging an interesting moment after a lead registers for a webinar, and populating the name of the initiative in an interesting moment.

    Marketo Program Token Setup

    When setting your tokens in the program settings, I’ve found it helpful to specify an obvious default value such as “EDIT ME”. This will make it easier to visually see which tokens have been set, and which still need to be edited.

    Once all your tokens are built, reference each of these tokens in your assets, and confirm in preview mode that you didn’t misspell or miss any tokens. There are some pitfalls to tokens though. This is far from an exhaustive list, but a few to watch out for:

    • If you set a token for the body text of your email, you may decide to use a rich text token for this. This is fine, but remember that the plain text version of the email will render that same token content explicitly, code included. So you may need to create plain text tokens for these sections.
    • Be careful with setting tokens for links in emails. Anytime a link exists that you want to track clicks, be sure that link is in a rich text token, not a plain text token.
    • Be wary of referencing tokens in your programs that you will only use some of the time. Marketo used to be make it easier to delete tokens in the program settings menu, but it tends to produce errors when you do this now, especially for approved email and landing page assets.

    If you want to align to a solid naming convention for your tokens and general great info on the power of tokens, check out Edward Unthank’s presentation from Summit 2015 on the subject.

    Tying all the loose ends

    Once all your assets are loaded in the program, approve all the assets, and reference them within each of the smart campaigns (but don’t switch on any smart campaigns). This will ensure that when you clone your template, all the asset references are maintained when the program is cloned, and minimizes extra edit work.

    Now give the template a test by cloning, and editing each token, checking to ensure everything is populated. This takes time to do, but it is critical that your templates are flawless before you start asking your teams to work in them.

    As you begin using the templates, you’ll likely receive feedback over time for improvements. you may also want to update the design of your assets over time. Before making and edits to the template itself, first clone the current version of the template into a new version that is clearly named. Keep the old versions in an archive folder. This will ensure that if you break anything, you can always revert back to the old version.

    And that’s it! I’ve opted not to get into my specific program structure, as everyone will have different use cases, and the assets that make sense for my purposes may not always work for you. Though if you do ever want to talk structure specifics, feel free to reach out, I’m happy to talk 1:1.

  • A Marketo field for every occasion

    A Marketo field for every occasion

    Chicken or fish?

    It’s as if every program or event has some random, custom field requirement. Dietary restrictions at an event, questions for a webinar, or a time slot for an in-person consultation. Fields aren’t exactly hard to create in Marketo, but they live on forever once they’re created, and can lead to a ton of confusion later. Avoid the temptation to add new fields in every scenario. There’s a much better way to deal with this, and I’ll show you how.

    Instead of creating a new field for every random request, create a small handful of temporary “burner fields” that you can use over and over again. Just remember these aren’t to be used for data you want to hold on to. Nothing critical like contact info, lead profile info, etc. Just single or temporary-use data.

    In fact, for truly temporary data, it’s a bad idea to keep this sort of data around permanently – if you ever run a similar program again in the future, you run the risk of referencing old data in the new program. Not to mention it creates a complete mess when trying to find the proper fields to use.

    To start, you’ll want to create at least one string field, but you may want a few of these. Give it distinct names like Temporary Text Field 1, Temporary Text Field 2, etc.

    Burner fields on a Marketo form
    Add your temporary field to a form – here’s an example of a multi-location event registration form.

    Once you add one of these fields to a form, you’ll need a way to record the temporary value, and then clear the field so it can be used again later.

    Set up a smart campaign that triggers when your form is submitted (this may already exist for something like an event registration action), with specific actions for dealing with the value just stored in your burner field. And your method here may vary a bit depending on the data you’re capturing.

    For example, if you’re running a multi-location roadshow, and you want to use one registration form for the entire series, you might want to use your temporary field to display a selection of all the events in the series.

    In the smart campaign that triggers on the form submission, use the value in that field to add the lead to the appropriate sub-program, or static list.

    Then, follow up with a data value change of the temporary field, and set a new value of “NULL”. This will clear the field of it’s value for that particular lead.

    Temporary fields in a Marketo smart campaign
    Here’s the same roadshow example on the smart campaign. Marketo sorts through the temporary field values, assigns to the proper program, and then clears the value out.

    Alternatively, if the data is something more open-ended like dietary restrictions or webinar questions, consider setting up an email alert that fires when the form is submitted, which will essentially stamp that value in an email for future reference, even if it no longer exists on the lead. If email alerts won’t work, you could also opt to add all the leads to a static list, and subscribe to it. Then set a timed smart campaign to clear out the field of any values after your event or whenever the data will be used.

    Now you have a field for every occasion, and you’ll probably discover new use cases for them all the time. If you ever have concerns about the use of a field overlapping across programs, you just add another temporary field, or better yet, assign your burner fields by use case or region to avoid any accidental crossover.

  • Bombproof your list imports with proxy fields

    Bombproof your list imports with proxy fields

    photo-1436902773985-52c1040b6100

    List imports are scary stuff.

    There are a lot of things that can go wrong with pushing a file of leads into your database. Duplicates. Overwritten values. Bad data. List imports open you up to a lot of risk to your Marketo database all at once.

    But you can set up a line of defense for your more sensitive fields using what I call “proxy fields”, which help you intelligently manage how data is overwritten.

    List imports are a daily task for us, and so we’ve gotten pretty strict on the data requirements for new leads, particularly with the lead status field. When we upload, we need to be able to distinguish between suspects/inquiries and truly qualified leads.

    We block field updates for the lead status field, meaning it only accepts the first value from a list import, and won’t be changed by future imports. This helps us ensure a lead that’s already an MQL cannot move backwards and become a suspect from a later list import.

    List imports with field blocking
    Here’s my crappy drawing of how field update blocking works. New leads get a status, existing leads (who already have a status) are unchanged.

    This is handy, but field blocking is a double edged sword. Suppose a lead was originally imported as a suspect, but is now on an import list where we’ve marked them as an MQL. In that case, we actually want them to become an MQL, but since that field blocking is in place, that lead’s status won’t be changed, and we’d be forced to fix it manually.

    To work around this, we created a proxy field, called “Import Lead Status.” It replaces the standard lead status field on our import lists, and more intelligently manages the data, making sure leads can move forward in status, but not backwards.

    Marketo List imports with proxy fields
    Here’s what imports look like with a proxy field. We’re now conditionally assigning lead status from list imports, so existing leads can be updated when it makes sense. Sweet!

    Here’s how to set it up in about 10 minutes:

    • Create a new text field with a name distinct from the original field (this should be a marketo-only field), such as “Import Lead Status.” Ensure no field updates are blocked. You may also want to set a few list import aliases for this field, as this is the field you’ll want all your list imports to map to in the future.
    • Create a smart campaign set to run every time a lead qualifies, with two triggers: one for anytime your new field’s value changes, and another for when the lead is created (since data value change triggers won’t fire for new leads). You’ll also want to include two filters:
      • A filter to exclude any lead statuses you do not want to change. You need to include this so your import lead status doesn’t move any leads backwards inadvertently. I decided that anything Marketing Qualified or beyond (SAL, SQL, etc) shouldn’t be changed.
      • A filter the specifies that the import lead status field isn’t empty (for the aforementioned “lead is created” trigger)
    • For your new Smart Campaign’s flow, you just need one step, “Change Data Value” that sets the lead status by grabbing the value from the proxy field, using a field token.

    How to set up proxy fields in MarketoHow to set up proxy fields in Marketo

     

    The nice thing about this process is it’s invisible to your other Marketousers. We have a standard import template that we require for any list uploads, and I have “lead status” and variations of it mapped to this proxy field as a safeguard, so to anyone importing lists, this is no different to how they managed the process before. Since implementing this process, it’s had a big impact on efficiency and accuracy for us.

    Obviously this is just one example of a proxy field – you could do something similar for geographic fields, company names, phone numbers, and much more. If you’re doing something similar, I’d love to hear about it!

  • One Landing Page Template to Rule Them All

    One Landing Page Template to Rule Them All

    This post originally appeared on the Champion Blog of the Marketo Community on August 10, 2015

    ringI hate repeating work in Marketo. Yet landing page templates seem to be an area that requires a lot of repeat work. It seems natural to just build a new template when you have some new use case, channel, or brand to contend with. But the problem with this approach shows up later, when changes are needed at a global level. Suddenly you’re stuck with all sorts of versions to update. The end result is a bunch of legacy templates with outdated code, and maybe one or two templates that actually remain current.

    So instead of building new templates each time some minor new change is needed, I try to think about the process backwards-identify the elements I might need to customize on my landing pages, and then build a flexible template that will let me control those changes in the future.

    This approach is made more viable with the new guided landing page templates, which add an awesome new functionality called Variables. These, plus some creative applications of program/folder {{my.Tokens}}, allow you to build a template that works for nearly any situation. Here are a few ideas to try:

    Branding: logo swaps, color palate changes, fonts, etc

    Logo and style changes are some of the more common edits you might be making to a template. You may need different looks for an SEM page vs an event registration page, or for a parent and sub brand. At a minimum, you should wrap key brand elements like a logo within a “mktEditable” div. The magic of this class allows the content within it to be directly editable within the landing page editor.

    You can get even more control with variables, for scenarios like:

    • Toggling between two main logos (boolean variable)
    • Changing the accent color used on your pages (color variable)
    • Setting the URL of an element like a banner image (string variable)

    CSS TokensAnd when you need finer tuned control and the ability to overhaul CSS on the fly, program {{my.Tokens}} are what you’ll want to use. Consider putting a few placeholder tokens in <style> </style> tags in your header for any program or folder-specific CSS editing you might want to do.

    Tokens are great in that you can choose whether or not you want to assign them a value, so it’s always worth adding a few to your templates should you need them later. They’re especially handy when you’re testing a new form design, or need to make broader layout changes. It’s as simple as pasting the new CSS snippet into a token, and the pages within that folder or program will instantly reflect the new code–no draft approval required.

    Placement and visibility of elements

    Landing Page VariablesIf you check out the documentation on variables, you’ll see a few mentions of manipulating the visibility of elements in your page, such as making your footer shown or hidden. But you can take this idea a lot further, and build variables that allow you to display a form or secondary call to action with the flip of a switch. You can use this sort of idea in tandem with other variables that control the width of different elements (especially when using a responsive, grid-based framework like Bootstrap). This allows you to use the same template for both your landing pages with forms and form-free confirmation pages.

    Scripts and tags

    It’s common to see separate landing page templates when specific tracking scripts are needed, such as a confirmation page to track goal conversions in Google Analytics, or on a specific landing page used to fire a remarketing script. This can get clunky to manage across multiple templates, and a few tokens will serve you well here.

    Just as with CSS tokens, you can set a few dedicated javascript tokens in your template which can be referenced as needed. Then, if you have a specific program or set of programs that you need to call a script for, just put in a value for one of your script tokens, and you’ll be set. Note: if you’re really clever, you’ll put programs that use common scripts in the same folder, such as those used for Search Engine Marketing. Then you can just set the token in one place–at the folder level, and all the programs within it will automatically inherit that value.

    Better yet,  you can solve a lot of this with Google Tag Manager. It’s a wonderful tool that allows you to fire different scripts based on different scenarios: a specific page view, a click, or another event you configure there. This will probably keep your PPC manager or agency happy, because they don’t have to fuss with different landing pages to get the configuration needed.

    Localization and miscellaneous meta info

    For global brands with page localization needs, there are meta properties such as HTML language type and CSS text direction (for languages like Hebrew that read right to left). You can set these sorts of items as variables in your template too, allowing you to quickly swap between localization preferences.

    There’s a few other miscellaneous use cases too:

    • Copyright year – this changes every year, so think about setting a token for it in your footer if you display one. This will save you hours of work fixing landing pages on January 1st.
    • Footer links – For social icons, privacy and T&C links, make that area a token that you can change globally. This stuff does sometimes change, and with a token it takes just seconds to update.
    • Open Graph tags – Do you ever wonder how people get their posts to display well on social networks with full sized images? Chances are they’re using open graph tags to specify post meta content. So you can place this data in your templates and set via tokens for quick updates.

    clapIf you were to implement every one of these ideas, you’d have a lot of tokens and variables to contend with. So the key word here is moderation–just because you can make everything a token or a variable doesn’t always mean you should. This is doubly important for variables, which require hard coding into the templates, so tweaking these all the time isn’t really ideal.

    These ideas just scratch the surface of what some of you have already come up with–so please share any clever template ideas you’re using in the comments!

  • Building a Scalable Alert System in Marketo

    Building a Scalable Alert System in Marketo

    “What have you done for me today?”
    It’s the unspoken question asked every day by sales teams. Alignment between sales and marketing teams has a lot to do with communication and visibility. If sales doesn’t see the value of marketing at a daily, tactical level, trust erodes fast.

    There’s entire books sales and marketing alignment. I’m not here to write one of those. Instead, I’ll show how redesigning a simple but critical process, your lead alerts, can up your perceived value to your sales team.

    When I first started using Marketo, my sales team was in a constant state of flux. There were new and departing faces, and management would completely redefine territories at the first sign of a stalled pipeline. As the designated Marketo jockey, it was up to me to ensure the right reps saw the right notifications. But keeping this up to date in Marketo was both time consuming and tricky to keep accurate everywhere.

    Sound familiar?

    If you’ve just adopted marketing automation, you’ll have handful of situations where you’d want to send an alert, such as the contact-us form on the website. This is easy to do—just create a smart campaign that triggers off a specific form fill, and runs a flow step of send alert to lead owner.

    Simple Alerts
    An example of the simplest of lead alerts. They’re easy to build, but you’ll outgrow them quickly.

    But as you grow, you’ll add more forms and different alerts for different offers. You’ll also need to keep pace with a growing and evolving sales organization. Soon your simple alert processes will get unwieldy (and unreliable).

    If you’re at this point, the first step you should take is in adopting some global assets, particularly with your forms (See #4 in this post for more on that topic).

    Think about the forms you can use within multiple programs. For example, a “download a whitepaper” form could be the same form re-used for different whitepapers. If you can’t do that, at least create a common naming convention e.g. “Form – Contact Us”, “Form – Contact Us v2” etc. This is handy because your alerts can start to live in one place, and you can trigger off of all-inclusive logic like “form name contains “Contact Us”.

    Form name contains example
    Name your forms consistently, and you can rely on much more open filter logic

    You’ll find this will close some of the gaps in your alerts, and will help wrangle the odd campaign sending out alerts when it shouldn’t be.  This is an elegant solution, as long as you keep your naming conventions tight.

    But then comes the process of determining who should get which alerts. If you’re like me, your sales team is carved up by geographic region. If you’re syncing your leads to salesforce, and they’re then getting assigned to the reps, you can just use the lead owner info to determine who should get which alert. But what if the audience you want to alert doesn’t own records in SFDC? This often happens with account management teams, SDR teams, or organizations using lead queues (If you haven’t discovered it yet, lead queues make the {{lead.lead owner}} tokens unusable). For situations where you can’t lean on CRM data, you need to adapt Marketo to handle this.

    When you’re at scale with a complex territory assignment rules that change often, and more than a handful alerts to manage, you can build your alerts based on Segmentations and Program Tokens ({{my.Tokens}}). These will let you update territories and recipients in one place, with changes immediately affecting all your alerts.

    Using a Segmentation to define sales territories

    Marketo Segmentation for Geography
    Now you’ve got a reliable way to identify which territory a given lead belongs to.

    First create a new Segmentation, and define your segments based on your sales team’s territory assignments. In the filters of each segment, you’d use country or whatever field that defines geography to specify that segment. Once approved, Marketo will slice up your data and dump leads into the appropriate buckets.

    If you haven’t already, it’s time to create a central program for all your alerts. Build out your first smart campaign with the appropriate trigger, eg: Form name starts with “Contact Us”. For the flow step, you’ll send an alert with a conditional statement for each of the segments you defined earlier.

    This tells Marketo to send a particular alert to a particular person based on which segment the lead (which triggered the alert campaign) is a member of.

    Using a marketo segmentation as conditional logic
    You can use the segmentation you just created as filter criteria, or, in this case, conditional logic for your alerts.

    Note: While we’re using this segmentation for a somewhat unusual purpose, it’s also great for dynamic content (for which it was originally designed for). Most people under use Segmentations, but it’s a great feature with some pretty cool use cases far beyond this example.

    Using tokens to define alert recipients

    Now we’ve got our logic in place, but what we’re most concerned about is who the alert is going to. You could plug in a list of email addresses under the “to other recipients” section. But remember that anytime your assignments change or you hire a new rep, you’ve got to change that in every alert campaign. It’ll seem easy now, but it’ll be a pain later. Trust me.

    So instead, go into the My tokens area of your program, and create text tokens with consistent names like {{my.NW-Sales-Rep}}. Do this for for each of your territories and reps, and set the token values to their email addresses.

    Setting Marketo tokens for alerts
    Create tokens for each of your regions. Note: It’s possible to put several emails in a single token value. Just separate them with a comma.

    Once your tokens are all set, plug them into the flow step choices under “other recipients”. Marketo will send to the token values whenever the alert fires.

    Setting tokens in Marketo flowsteps
    Your alert flowstep will now be a long set of choice steps, each with a different segment and corresponding token.

    Note: You can only use tokens in a smart campaign like this when it’s based on at trigger. You cannot use {{my.Tokens}} in batch smart campaigns.

    Bringing it all together

    Once you’ve built out the rest of your alerts and set all your tokens, you’ll feel like you did a lot of work for no clear reason.

    But you’ll see this pay off when your territories and sales teams start to change. You’ll find that you can skip edits to individual alerts, and instead update either tokens or Segmentations, depending on what’s changing.

    You’ll save time, but most importantly, you’ll ensure consistency and reliability for the alerts to your sales teams.

  • Updated: Tracking Embedded YouTube and Wistia Videos in Marketo

    Updated: Tracking Embedded YouTube and Wistia Videos in Marketo

    Update 5/26 – I’ve fixed a player dimensions issue with the Wistia embed script, and added the ability to track both video starts and video completions. I’ve also updated the token naming conventions with a clearer, more consistent naming convention. Finally I removed the munchkin script call at the top of each embed code (though enabling Munchkin API is still necessary). It’s not necessary if you already have munchkin installed on your pages. Let me know if these changes are helpful!

    A common need among Marketo users lies in the ability to track embedded video engagement with their prospects and customers. Marketo will natively track form submissions and web page activity, but it does not have great built-in video tracking functionality.

    Since it’s important for marketers to understand when their target audiences actually view or interact in a certain way with a video, and not just that they visited a web page that happened to have a video on it, a more robust solution is needed. There are vendors who specialize in tracking video behavior in your marketing automation, but for basic tracking, you can do it yourself, and I’ll show you how.

    By leveraging Marketo’s munchkin API in conjunction with an API-enabled video hosting service like YouTube or Wistia, it’s easy to build this integration yourself. Before we get any further: don’t get scared off by terms like “API”–this particular piece of functionality is actually pretty simple to implement with a basic understanding of HTML and Marketo, and I’ve hopefully done most of the heavy lifting for you. Plus, it’s a great practical demonstration of the extensibility of the Marketo platform.

    This implementation works by using the video player to tell Marketo when it’s state changes from not playing to playing (in other words, when the lead clicks the play button on an embedded video). Then Marketo logs a web page visit event in the lead’s activity log, which can be used to trigger other actions off of Marketo, such as an interesting moment or program status change.

    First Things First: Enable Munchkin API

    Before we get into the specifics of how this works, you’ll first need to set up your Marketo instance to use the Munchkin API. Marketo Admins should first navigate to their admin section > Integration > Munchkin > Edit API Configuration. You’ll want to check the box labeled “Enable Munchkin API”

    Enable Munchkin APIWhile you’re on your Munchkin Settings, also make note of your nine-digit Munchkin ID (formatted as XXX-XXX-XXX). You’ll need this later.

    Now that you have this squared away, you’re set to start setting up your customized embed code. I’ve set up codes for both YouTube and Wistia. While YouTube is certainly a more widely used platform, I’ve started using Wistia more recently because of the issues with corporate IT filters blocking YouTube videos for B2B users. While this isn’t always an issue for embedded videos, I ended up preferring the the customization and business focus of Wistia. It’s a matter of personal preference I’ll leave up to you. For each guide, I’ve included standard embed codes, and tokenized codes (if you’re using your Marketo Programs).

    Option 1: Embedding with My.Tokens

    I mentioned that there are two versions of these embed codes – a standard and a token enabled script. If possible, you really should use the token-enabled script. You’ll find it’s far easier to work with, so long as the page you want to embed your video on is contained within a Marketo Program.

    First are the modified versions of the embed codes for Wistia and YouTube that are set to accept Marketo’s My Tokens, which work within Programs. Also make special note the highlighted section for Munchkin ID. You will want to set this manually, since it’s the same value for your entire Marketo instance. Your tracking will not work without setting this up.

    To set up video play tracking for a Wistia or YouTube video, you’ll need a few things:

    1. Your video ID (10 digit code that you can find in the embed code on Wistia, or on the video URL – The same is true for YouTube, but the code is 9 digits)
    2. Video height and width dimensions (eg 550×309)
    3. A “play” URL that you want Marketo to log anytime the video is played
    4. Your 9-digit Munchkin ID

    Next, you’ll need a landing page to embed your video to. Generally it’s advisable to do this within a program so that you can make use of the token-enabled script, however if you’re comfortable editing the script yourself and cannot make use of program tokens, you can install the videos on really any landing page using the standard scripts at the end of this post.

    If you plan to use the token-enabled script, here are the tokens you’ll need to create (all should be plain text tokens):

    • My.Video – ID: the 10 digit video ID from wistia  (9 digit for YouTube)
    • My.Video – Width: The pixel width of the video (note: this should be input as a numerical value only, eg: “550”, and not “550px”.)
    • My.Video – Height: the pixel height of the video (same instructions as my.videowidth)
    • My.Video – Name No Spaces: this is the fictitious URL you define that will display in the Marketo activity log. You can set anything you want here, but I generally like to follow a similar naming convention to the page that the video is embedded on. I’ll clarify with an example: if your video is embedded on info.yourdomain.com/myvideo.html,  you might want the log to display info.yourdomain.com/myvideo/play when the video is played. In that case, you’ll want to set this token value as “myvideo”. Do not include any other part of the URL – Marketo will do that automatically. Note that this script logs a video start and a video complete event. You can opt to use one or the other, or both at the same time.
    • My.Video – Player Color: This one is optional, and only for Wistia, but it controls the color of the video player. You don’t need to set a value here, but if you want to customize it to your own video branding, feel free to use your own hexadecimal color code. (eg 6688AAD – no # needed)

    Below are the scripts you’ll want to place within an HTML object on a Marketo landing page. Note: The codes below will replace any embed code you would ordinarily retrieve from Wistia or YouTube directly. These will handle both the embed of the video and the tracking and integration within Marketo.

    Remember – you must update the highlighted sections with your specific Marketo 9-digit Marketo ID (including hyphens).

    You can also download all the scripts via my GitHub repository of this project.

     Wistia (With Tokens)

    <!--Video embed (this is what embeds the Wistia player)-->
    <div id="wistia_{{my.Video - ID:default=c6xf9ao18h}}" class="wistia_embed" style="width:{{my.Video - Width:default=550}}px;height:{{my.Video - Height:default=309}}px;" data-video-width="{{my.Video - Width:default=550}}" data-video-height="{{my.Video - Height:default=309}}"></div>
    <script charset="ISO-8859-1" src="//fast.wistia.com/assets/external/E-v1.js"></script>
    <script>
     wistiaEmbed = Wistia.embed("{{my.Video - ID:default=c6xf9ao18h}}", {
     videoWidth: {{my.Video - Width:default=550}},
     videoHeight: {{my.Video - Height:default=309}},
     playerColor: "{{my.Video - Player Color:default=688AAD}}"
     });
     // the functions below will watch for the video to be started or ended (tracked via state changes), and translating that to page visits in Marketo. 
     wistiaEmbed.bind('play', function() {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/{{my.Video - Name No Spaces}}/played', params: 'x=y&2=3'
     });
     });
     wistiaEmbed.bind('end', function() {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/{{my.Video - Name No Spaces}}/completed', params: 'x=y&2=3'
     });
     });
    </script>

    YouTube (With Tokens)

    <!--Youtube iframe embed script with Munchkin integration-->
    <div id="player"></div>
     <script>
     // 2. This code loads the IFrame Player API code asynchronously.
     var tag = document.createElement('script');
     tag.src = "https://www.youtube.com/iframe_api";
     var firstScriptTag = document.getElementsByTagName('script')[0];
     firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
     // 3. This function creates an <iframe> (and YouTube player)
     // after the API code downloads.
     var player;
     function onYouTubeIframeAPIReady() {
     player = new YT.Player('player', {
     height: '{{my.Video - Height:default=309}}',
     width: '{{my.Video - Width:default=550}}',
     videoId: '{{my.Video - ID:default=c6xf9ao18h}}',
     playerVars: { 'showinfo': 0, 'controls': 2, 'rel': 0 },
     events: {
     'onReady': onPlayerReady,
     'onStateChange': onPlayerStateChange
     }
     });}
     // 4. The API will call this function when the video player is ready.
     function onPlayerReady(event) {
     }
     // 5. The API calls this function when the player's state changes, and sends a visit web page action to Marketo via the Munchkin API
     var done = false;
     function onPlayerStateChange(event) {
     if (event.data == YT.PlayerState.PLAYING && !done) {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/{{my.Video - Name No Spaces}}/started', params: 'x=y&2=3'
     });
     }
     else if (event.data == YT.PlayerState.ENDED && !done) {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/{{my.Video - Name No Spaces}}/completed', params: 'x=y&2=3'
     });
     }
     }
     </script>
    
    

    Standard Embed Codes

    If for some reason you can't use your video within a Marketo program and use the tokenized codes above, the standard codes below will also work, just know that you must edit the highlighted portions with your video and Marketo info. Take extra care with the Wistia embed code, as variables like video player dimensions and ID must be edited in several places. Again, use the tokenized version above if you can! Finally, note the highlighted portion for “url”. Remember, this is the name of the URL you wish to have logged in a lead’s Marketo activity log when the video is played. This can be set to anything, and doesn't need to be an actual working URL. In the example of a webinar, your URL could be “myQ2Webinar/play”. Note to only include the page name and then something afterwards to distinguish the actual page from the play action, such as  "/play". Do not include any prefixes or domains (http, www, domainname.com, etc).

    Wistia (Standard Script, no Tokens)

    <!--Video embed (this is what embeds the Wistia player)-->
    <div id="wistia_29b0fbf547" class="wistia_embed" style="width:550px;height:309px;" data-video-width="550" data-video-height="309"></div>
    <script charset="ISO-8859-1" src="//fast.wistia.com/assets/external/E-v1.js"></script>
    <script>
    wistiaEmbed = Wistia.embed("29b0fbf547", {
     videoWidth: 550,
     videoHeight: 309,
     playerColor: "688AAD"
    });
     // the functions below will watch for the video to be started or ended (tracked via state changes), and translating that to page visits in Marketo.
    wistiaEmbed.bind('play', function() {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/YourVideoName/started', params: 'x=y&2=3'
    });
    });
     wistiaEmbed.bind('end', function() {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/YourVideoName/completed', params: 'x=y&2=3'
     });
     });
    </script>

    YouTube (Without Tokens)

    <!--Youtube iframe embed script with Munchkin integration-->
    <div id="player"></div>
     <script>
     // 2. This code loads the IFrame Player API code asynchronously.
     var tag = document.createElement('script');
     tag.src = "https://www.youtube.com/iframe_api";
     var firstScriptTag = document.getElementsByTagName('script')[0];
     firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
     // 3. This function creates an <iframe> (and YouTube player)
     // after the API code downloads.
     var player;
     function onYouTubeIframeAPIReady() {
     player = new YT.Player('player', {
     height: '390',
     width: '640',
     videoId: 'kTcRRaXV-fg',
     layerVars: { 'showinfo': 0, 'controls': 2, 'rel': 0 },
     events: {
     'onReady': onPlayerReady,
     'onStateChange': onPlayerStateChange
     }
     });}
     // 4. The API will call this function when the video player is ready.
     function onPlayerReady(event) {
     }
     // 5. The API calls this function when the player's state changes, and sends a visit web page action to Marketo via the Munchkin API. Make sure to update the mktoMunchkin value to match your specific account ID (Admin > Integration > Munchkin)
     var done = false;
     function onPlayerStateChange(event) {
     if (event.data == YT.PlayerState.PLAYING && !done) {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/YourVideoName/started', params: 'x=y&2=3'
     });
     }
     else if (event.data == YT.PlayerState.ENDED && !done) {
     mktoMunchkin("XXX-XXX-XXX");
     mktoMunchkinFunction('visitWebPage', {
     url: '/YourVideoName/completed', params: 'x=y&2=3'
     });
     }
     }
     </script>
    
    Once you've successfully embedded your codes, It's time to test out your page. Visit the Marketo landing page you've just created, and click the play button on your video. Make sure to be using a browser that has already been cookied by Marketo (An easy way to confirm this is to visit a Marketo page with a form on it - if the form is pre-filled with your information, you're cookied). Then, search for your lead record in the Marketo lead database, and click over to the activity log. You should see something like this: activity log This web page will now appear anytime the video you've set up is played. Cool, huh?

    Triggering flowsteps off video play behavior

    So what do you do now? Now that you've got your videos tracked in Marketo, it's time to have Marketo do something interesting with that information. Since you've logged a web page visit, you can now use the "visited web page" trigger or corresponding filter in a Marketo Smart Campaign to trigger activities off of video plays. web page trigger   For example, you could log an interesting moment anytime your video is played. Your sales team will thank you for this, as you can log something very explanatory, like "Viewed Video: Q2 Product Demo" instead of "visited web page my-landing-page-Q2_Demo-V8.html/play." In the past I've discussed how to centralize your content tracking through Marketo programs. You can do the same with videos too, and log a program success when a lead plays one of your videos. This is especially helpful if you want to view all the leads who've watched your video, or to calculate return on the investment of a video's production. Flowstep   Keep in mind that these examples work best when the lead is already known in your database. So in the case of a recorded webinar, where you've probably got a form sitting in front of that video, it's safe to assume that you'll probably have known visitors being tagged with video views. But if the video is a general marketing video that may be sitting on its own, you will likely have anonymous as well as known visitors. Marketo will still track both, but logging a program status change or interesting moment is really only of value to known leads. So you may consider dropping in a filter to your smart campaigns to exclude anonymous leads, or just be willing to accept some anonymos leads in your program reports.

    Moving beyond the basics

    I built this integration because it solved a very specific problem for me, yet there are pretty limitless possibilities with expanding on this. With a bit of work, it's likely possible to track more nuanced behavior, such as viewing a video for a specified period of time, or observing the degree to which the video is started and stopped. I constructed this integration using the following resources. Feel free to use these in your own efforts! Marketo Munchkin API Documentation Wistia Player API Documentation Youtube JS Player API Reference As I mentioned earlier, I've started with Wistia and YouTube, but there are probably plenty of other video players you could build similar integrations with, such as Vimeo. Most of their APIs are fairly similar to work with, so it's probably just a matter of adapting the existing scripts to other players' specific operations. If you're interested in other applications of this, let me know in the comments!