Skip navigation
All Places > Products > Blog
1 2 3 Previous Next

Products

341 posts

The Marketo Master Class series is back with another deep dive into one of the many facets of Marketo: Lead Nurturing. This time around we were lucky enough to team up with Marketo Champion Alumni and Founder of Marketing Rockstar Guides Josh Hill on a special piece of content. Past master classes have drilled into a particular functionality and provided technical tips for navigating the Marketo platform. For this master class, rather than walk through how some of our successful customers leverage Marketo, we wanted to discuss the philosophy every marketer should consider before implementing any and every lead nurturing campaign.

 

1. How did you develop your nurture philosophy?


I developed the Journey Session Framework after working on various nurtures using smart campaigns as well as the Engagement Program. After a few tries, I realized that in order to make it work, there were the five questions to answer. If you cannot answer all of the questions, you won’t be able to launch the nurture properly. In many ways, this harkens back to the old Marketing or Campaign Brief, from a marketing automation point of view.
The Five questions are Who, What, When, Where, Why, and How. But that’s not how I ask them to get the answers we need for a nurture program.

  • Entry – Who
  • Exit – Bad – Why
  • Exit – Goal - Why
  • Cadence - When & How
  • Content – What


If you can concretely answer these questions, you can do amazing work in Marketo.
For example, you might end up with a Journey Doc like this:

  • Entry – Who – people who fill out the free trial form with XYZ fields.
  • Exit Bad – people who unsubscribe or cancel their trial.
  • Exit Goal – people who pay for the service.
  • Cadence: one email within 1 hour and then every 2 days at 2pm afterwards.
  • Content: onboarding emails – 3 to start, we may add 3 more.

 

2. What metrics are you looking at if you’re trying to improve a nurture? (open rates/click rates?)


I am not a big proponent of such metrics for a nurture. These days, clicks are about 80% fake – created by spam bot filters. A click can only tell us a little bit about that particular asset, not whether the journey itself is leading toward the desired lifecycle stage. If your nurture is designed to advance someone (a lead or Account) to MQL or SQL, that’s the only metric to consider.
Remember that your stages are (usually) based on a lead scoring methodology or your funnel methodology, so it is predeterminate to say that “We’re driving 20% more MQLs with this new nurture.” Is that because it takes 1 click to reach MQL? Is it three whitepaper downloads? Are your assets structured to hook into that scoring?
In some sense, you can treat a long term, carefully planned nurture, similar to the lead funnel. The ability to monitor the inflow and outflow of the nurture against the key stages is critical.

  • Entry – how many entered each day or month
  • Exit Bad – how many people fell out because of unsubscribes or excluded traits.
  • Exit Goal – how many people reached our goal – MQL or Upsell.

 

3. How do you make changes to an existing nurture/program without reinventing the wheel or breaking the system?


The best way is to add new content. However, I do encounter this issue frequently. Sometimes the marketer made a mistake, sometimes we add new nurtures and have to shift leads to a different nurture after the fact. Most of the time, at least with an Engagement, this is easy to do with smart lists and campaigns.
The challenge is when you have a Smart Campaign drip, or Irregular drip with wait steps running. If leads are in the flow, you may have to remove them and start again. You can also, if you are careful, adjust the flow steps, however, this is risky. Leads could pop out to the wrong step or you could create a bug in the smart campaign and cause it to fail.

4. How do I determine whether content should be in a separate stream or separate program entirely?


I use my Nurture Waterfall concept to decide things like this. Nurtures aren’t about a set of content, they are about the people. The Waterfall has several nurture programs, or streams, designed to take someone with a limited profile to entice them to offer us more information about themselves. Once they do, we move them to more specific nurtures targeting their Account-Solution-Persona.
Usually if the Lifecycle Stage is different or the Buyer Persona is, that’s a reason to have separate Nurture systems. Depending on how you structure the Streams, you can either do this by Persona-Stage or separate the Nurtures. There’s no perfect way to handle this.

 

5. What are the common pitfalls you see in nurture planning and execution?

 

Lack of planning.

Lack of content.
If you don’t understand the Journey Questions, you won’t be able to build the nurture in Marketo or any system.
It is critical to have a continuous stream of content to add to the Streams to extend the nurture as most B2B buyers will take months to years to be ready for your sales people.
The other pitfall is this strange assumption that every nurture begins with 4 emails. The assumption blocks a successful nurture because:

  1. Four emails are rarely enough. Most marketers can barely get 4 emails finalized on Day 1 and then they will rarely come back to add more than four. If you know it takes 60 days to reach SQL and 180 days to make a sale, why is your journey 4 emails?
  2. Only need one email on Day 1. Create a rolling schedule of new content. Your audience won’t notice if there’s a delay, but you definitely need to feed the machine or risk a dead list. Psychologically, creating one email at a time is less daunting than building a 49 week nurture.

 

6. In what situations would you want to leverage a nurture program over any other program?

 

This isn’t the right question. A nurture program is part of a continuous multi-channel effort. People should find content organically or through advertisements, then opt in to further communications. The nurturing program keeps your audience engaged while specific Events, Webinars, Videos, etc will spark their interest further. Of course, not everyone, but enough to keep business moving.

 

Each lead who opts in from offline events should enter a long term nurture. Leads who don’t advance in the funnel should move to an appropriate stream related to the reasons they did not work out this time.

 

We hope you learned some key takeaways to think about while planning your next nurture campaign. Do you have a nurture checklist of your own? We would love to hear about it in the comments!

***Posted on behalf of Rachel Noble, Manager of Client Services at Digital Pi***

 

Reporting on multi-touch attribution

If you have Revenue Explorer (aka Marketo Advanced Report Builder), you’ve seen (FT) and (MT) show up on a number of reports. Marketo gives a full breakdown of these two distinct types of attribution, but today we are going to focus on (MT): Multi-Touch.

 

Traditionally, multi-touch attribution provides demand-generation analysis.

 

Multi-Touch answers a complicated business question, "Which programs are most influential in moving people forward in the sales cycle over time?"

- Marketo

 

To get a basic understanding of how multi-touch attribution really works, let’s start by looking at the Opportunity Influence Analyzer in the Analytics section of Marketo.

Image_01_Elevate_DC.jpg

 

For any opportunity, Marketo will show the story of how that opportunity was influenced by marketing. The little red dots above are clickable, and are comprised of interesting moments and program successes.

Image_02_Elevate_DC.jpg

Understanding which marketing interactions influenced an opportunity will help you understand multi-touch attribution. (MT) is essentially the same story, but presented in a way that allows you to aggregate or slice-and-dice the data. In Revenue Explorer, (MT) is calculated by taking an opportunity and splitting credit evenly between each program success.

 

For example, let’s take Jane Doe. She attended a webinar, visited your booth at a tradeshow, and then downloaded an eBook from your website. Shortly after, an opportunity for $300,000 was opened and associated with her contact record. Now, we have $300k of pipeline that can be directly connected with the webinar, tradeshow, and eBook. A (MT) opportunity report will credit ⅓ of the opportunity to each of these, and a (MT) pipeline report will credit $100,000 each to the webinar, tradeshow, and eBook.

 

Let’s look at one more example: John Smith. He was acquired via a list purchase, engaged with a direct mail piece, and then visited your booth at the same tradeshow before an opportunity for $100,000 was opened and associated with John. Since the list purchase was not a program success, it will not receive credit when using (MT) attribution. But the direct mail and tradeshow engagements were successes, so each will receive ½ an opportunity, and $50,000 pipeline credit.

 

Now that we know how multi-touch is calculated, we can pull pipeline reports per program. Perhaps we want to know how much (MT) pipeline is associated with the tradeshow. In this case, Revenue Explorer will credit the $100,000 from Jane and the $50,000 from John for a total of $150k in pipeline from the show.

 

Image_03_Elevate_DC.jpg

 

Now, we can aggregate the data. What if we want to know the total pipeline associated with all of the tradeshows? A multi-touch pipeline report by channel will return the total sum of (MT) pipeline associated with each channel.

 

Image_04_Elevate_DC.jpg

 

How do you know when to use (MT) attribution?

(MT) focuses on program successes, which are direct representations of engagement. If your goal is to drive engagement (or MQLs, or pipeline, or demand generation, etc.), then you should use a multi-touch attribution report. If, however, your goal is new-name acquisition, stay away from these reports and focus on first-touch attribution instead.

 

Reporting when you use dynamic content

There are two places in Marketo where you can use Dynamic Content: on a landing page or in an email. Today, we’re going to focus on reporting when you use dynamic content in an email.

 

Dynamic content allows a marketer to deliver the same email to an audience with content variations based on segmentation. For example, if you have your database segmented by industry, you can send someone in the education industry Email A with an introduction specific to education, and a generic introduction to everyone else. It’s a powerful tool, but reporting on dynamic content can be complicated.

 

Of course, you can always create an Email Performance Report or an Email Link Performance Report to understand the performance of the overall email, but what if you want to understand how each dynamic variation performed? Here’s the easiest method. First, create an Email Performance Report. In the Smart List, add a filter referencing a specific segment:

Image_05_Elevate_DC.jpg

Cloning this report and updating the segment will give you a separate report for each version of the email that went out.

 

However, there’s a catch! It is possible for someone’s industry segment to change between the time they receive the email and the time you pull your report. So how do you know for sure which version someone received?

 

When building your program, first identify how many versions of the email you will have. Let’s say in this example, we have industry-specific dynamic content for:

  • Education
  • Manufacturing
  • Technology

As well as a generic email for everyone else.

 

When we send the email, we will also create a smart campaign to assign recipients to static lists depending on their segment.

If you've been around the block with Marketo Smart Lists, you know there's no Ends With operator, only Starts With and Contains.[1]

 

This puts a damper on a common need: accurately searching for an email domain (@gmail.com, @example.co.uk) or TLD (firmographic clues like .edu, geographic ccTLDs like .cn).[2]

 

Some have attempted extravagant combos of Contains and Not Contains, which require a whole lot of prep just to determine that... they don't work. (Read my comments on the linked post for some examples of how such approaches are broken.)

 

There's a much easier way: maintain a custom field, here called Matchable Email, that always holds the value of {{Lead.Email Address}} followed immediately by two quotation marks "":

 

ss

 

ss

 

Then, to do a domain search, search that Matchable Email field for Contains @example.com"", which is equivalent to searching the original Email Address for Ends With @example.com:

 

ss

 

Pretty easy, right?

 

Why two quotation marks (“”)?

The key is to add a sequence of characters to the end of the email address that can never occur in the middle of the email address, so Contains @{{domain}}{{characters}} is functionally equivalent to Ends With @{{domain}}.

 

Finding those appropriate {{characters}} is a lot harder than it sounds. For awhile I was lazily appending $ to the end, because I like the fact that the dollar sign represents end-of-line in regular expressions, so it was easy to remember. But the email address "$ke$ha@marketo.com$"@gmail.com — note the quotation marks around the mailbox part, it wouldn't be valid without those — is a Gmail account, but would match Contains @marketo.com$.

 

Yes, RFC 5321 is just that generous. There are so many crazy-but-valid email addresses, however inadvisable it would be to use them in the real world, that it's hard to find something that, without exception, can only occur outside of a valid address and so can be used as your anchor point.[3]

 

I think I've found that something, though. Two quotation marks in a row "" can occur inside an email address, but they can never be preceded by a character that is a valid part of a domain name.

 

Let me explain.

 

First of all, as you may already be confused by this part, it's possible to have a quoted mailbox name (called a quoted-string in the standard). That's how you can add spaces on the mailbox side of the @: "sandy spacebot"@teknkl.com is a valid SMTP address.

 

You can also put quotation marks inside an already quoted mailbox name, but if you do so, you have to escape them with a backslash.  Thus "Clarence "Frogman""@henry.com" is not a valid email address, but if you escape the quotes as "Clarence \"Frogman\""@henry.com it is valid. Even though this address has two quotes in a row "" (see the characters right before the @?) they are by necessity preceded by a \.  And the \ can never be at the end of a domain name. 

 

Therefore you can accurately search the Matchable Email field for a string that Contains @gmail.com"", knowing that that sequence of characters cannot be found at the start or middle of the value, only at the end.

 

Enjoy!

 

 


 

 

Notes

[1] As a sometime database architect, I've never understood the technical reasoning and figure it must be just legacy-code-nobody-wants-to-touch syndrome. When searching strings, Starts With is faster than Ends With unless specific indexing is used; yet Contains and Ends With have equivalent performance — often terrible performance, don't get me wrong, but roughly the same either way. Plus, it's way easier to add indexing to speed up Ends With than it is to optimize Contains (an index on the reversed value in the first case, n-grams in the second case, FWIW). But here we are.

 

[2] My colleague EU points out that Marketo attempts to optimize a search for a domain-like pattern, one that begins with the character @, and turn it into an SMTP domain search. The problem is that it still doesn't work: The valid address "me@gmail.com"@outlook.com will (as we would expect given the concept of contains) match both Contains @gmail.com and Contains @outlook.com so it doesn't successfully emulate Ends With. It will also false negative on Contains @outlook.co, which is just plain wrong.

 

[3] The way to do this in a technically complete manner is to add an ASCII control character (like ASCII 30 RECORD SEPARATOR, one of my faves) which is never allowed, not even in quotes. But while you can append such a character with a specially hacked Change Data Value, searching for those characters is, unless it's just a one-time thing, effectively impossible. So we'll have to make do with "".

Hadn't even heard of Appointlet until the other day, but when user SS mentioned he was trying to use the REST API to integrate an Appointlet widget with Marketo, I knew there had to be a better way. (There's almost always a more reliable + scalable alternative to server-to-server API calls for what should be browser-side integrations, Unbounce being another example.)

 

In line with services like ChiliPiper, TimeTrade, Calendly, et al. Appointlet is a service I wish I'd thought of because I'd be rich right now dedicated to scheduling. It interacts with a cloud calendar — O365 or Google calendar in this case — in real time to check availability, alerts reps of new bookings, and sends periodic reminders. (Again, no endorsement intended, just describing the published features... only spent 1/2 hr figuring out the API, so perhaps the platform might turn out to have humongous bugs, but it definitely looks useful enough so far!)

 

The Appointlet embed code gives you a button, which when clicked brings up the rep's availability:

 

 

And then a place for the lead to enter their personal info (more fields can be added but these are the defaults):

 

 

Naturally, when you're offering an Appointlet Book Now instead of a full Marketo form, the questions are:

 

  • How do you insert/merge the lead's info into Marketo?
  • How do you make sure past + future web activities are associated with the newly identified lead, i.e. how do you associate the Munchkin cookie with the lead, the way it works with a Marketo form?

 

The best answers are definitely not found in the Marketo REST API. Appointlet does offer outbound HTTP callbacks (accurately called webhooks, but they must not be in any way confused with Marketo's outbound 'hooks). So yes, you could set up your own gateway to receive said callbacks, and you could map them to the Marketo REST API endpoints (plural) that sort-of-maybe emulate a Marketo form post. But that means raw coding labor, new servers to maintain, and Denial of Service exposure. And no upside.

 

Instead the answer, as usual, is to simply post a Marketo form in the background, relaying the lead info from the Appointlet UI.

 

To do this reliably, Appointlet needs to have a client-side JS API. And indeed they do!

 

The Appointlet widget itself is rendered in an IFRAME, and like other sophisticated IFRAME-based embeds (the YouTube player, for example) the widget sends standard browser events to the parent document (that is, to the outer Landing Page) that include interesting info from the widget. We just have to listen for those events, add corresponding values to a Marketo form, and submit. Then we'll get a standard Filled Out Form activity in the Marketo Activity Log, which you can trigger and filter on like any other, and past + future Visited Web Page and Clicked Link on Web Page activities from that browser get merged in, too.

 

Step 1 of 3: Create a form

So first, set up a form that'll catch submissions from your Appointlet widget. (You can set up more than one form if you want to see cosmetically different Filled Out Form names for different pages, but it's not necessary and you don't want to create complexity.)

 

It doesn't need any fields at all, since we'll be populating the fields via API, but you can leave the default 3 fields in place. Just don't make any of them Required.

 

 

Step 2 of 3: Add the Marketo form to your page, with the <form> element not displayed

Inline style="display:none;" is easiest. With the embed code:

 

<form style="display:none;" id="mktoForm_787" class="mktoForm"></form>

 

With a Guided Marketo LP:

 

<div class="mktoForm" id="appointletForm" mktoName="Appointlet Hidden Form" style="display:none;"></div>

 

Or you can put it in a separate <style> which is more professional I suppose.

 

Step 3 of 3: Add the Forms 2.0 API custom JS

This is of course the meat of the solution.

 

MktoForms2.whenReady(function(mktoForm) {
var appointletUserConfig = {
allowedOrigins : ["https://teknkl.appointlet.com"],
formFields : [
{
appointletName : "first-name",
marketoName : "FirstName"
},
{
appointletName : "last-name",
marketoName : "LastName"
}
]
};

/* NO NEED TO TOUCH BELOW THIS LINE! */

window.addEventListener("message", function(message) {

var appointletGlobalConfig = {
messageType : {
TYPE_BOOKING_CREATED : "booking:created"
},
pattern : {
RE_AL_POSTMSG : /^appointlet:/
},
err : {
ERROR_NON_ORIGIN : "Message received from non-Appointlet origin",
ERROR_BAD_JSON : "Message received from Appointlet API but could not be parsed"
}
};

var appointletEvent,
isAlOrigin,
isAlBookingCreated,
mktoFieldsObj = {};

isAlOrigin = appointletUserConfig.allowedOrigins.some(function(origin){ return origin == message.origin; });
if (!isAlOrigin) {
return;
}

try {
appointletEvent = JSON.parse(message.data.replace(appointletGlobalConfig.pattern.RE_AL_POSTMSG, ""));
} catch (err) {
return console.log(appointletGlobalConfig.err.ERR_BAD_JSON);
}

if (appointletEvent.type == appointletGlobalConfig.messageType.TYPE_BOOKING_CREATED) {
mktoFieldsObj["Email"] = appointletEvent.data.email;
appointletUserConfig.formFields.forEach(function(fieldDesc){
mktoFieldsObj[fieldDesc.marketoName] = appointletEvent.data.fields.filter(function(alField){
return alField.field.slug == fieldDesc.appointletName;
})[0].value;
})
mktoForm.addHiddenFields(mktoFieldsObj);
mktoForm.submit();
}
});
});

 

Most of the code is no-touch, but there's a short config area at the top where you put your company-specific variables. From your Appointlet settings, get your Booking Page URL. That goes in the allowedOrigins config property:

 

 

Then the formFields property is an array that maps each Appointlet field name to its corresponding Marketo field name. (You didn't think it would be so easy that the separate products would miraculously use the same names, didja?) I filled in the First Name and Last Name mappings for you. Names of additional custom fields can be found via browser inspection, the Appointlet » Form Fields UI, and the SOAP API Name column of a Marketo UI » Field Management CSV export.

 

And that's it! Now, any confirmed Appointlet booking will post the form to Marketo.

 

What about the rest of the Appointlet setup?

That's on you. I found it very easy to set up an Appointlet account, link to a test Google Calendar, and grab the button code. But since I don't want to imply an outright endorsement, better to leave the rest of the product evaluation in your hands.

To switch up the Nancy Sinatra song, Booleans keep truthin’, when they ought to be falsin’.

 

As explored in earlier blog posts, when Marketo exposes Boolean fields in Velocity fields on the Lead/Person object, not on other objects they become Strings, not real Booleans.

 

And they're not even very Boolean-like Strings: they have values "1" and "" (the empty string) which in Velocity are both truthy values.[1]

 

As a result, you can't use a standard Boolean expression

 

#if( $isCustomer )
You're a customer.
#else
Wouldn't you like to be a customer?
#end

 

because everyone will match the first condition.

 

You have to be more exact, unfortunately making your code less self-documenting:

 

#if( $isCustomer == "1" )
You're a customer.
#else
Wouldn't you like to be a customer?
#end

 

Now, this more verbose version may not seem like a big deal, but I consider it to be poor programming practice because it relies on a “magic string”: a person reading your code has no way to know that "1" has some special significance and that the variable could not hold any other string value. That is, any Boolean-ish thing should be an enumeration only allowing 2 values (one representing true and one representing false, whatever those values might be) but since it's a freeform String it has no such restriction.

 

So here's something you can add to your global {{my.velocityIncludes}} token. (You do have such a token, don't you?  All the cool kids do.)

 

 

#set( $mktoBoolean = { "1" : true, "" : false } )

 

 

With that one-time include (put it in the <head> of your templates) now you can refer to those Boolean-ish fields like so:

 

#if( $mktoBoolean[$isCustomer] )
You're a customer.
#else
Wouldn't you like to be a customer?
#end

 

Now it's clear that you're using the variable as a Boolean.

 

I've recently decided this simple method is good enough. In the past I'd been  using a list (manually maintained in {{my.velocityIncludes}}) of known Boolean field names, then “massaging” those fields on the lead to turn them into real Booleans before using them. But that takes prep work and IM(new)O isn't worth it.

 

Code breakdown (if you need it)

The snippet above is just the kind of thing that can make new devs think VTL syntax works a certain way, and then try to adapt it to other scenarios only to find syntax errors.

 

So let me explain exactly what's happening, as short as it is.

 

First, let me add line breaks for readability:

 

#set( $mktoBoolean = { 
  "1" : true, 
  "" : false
} )

 

By using Velocity's map literal syntax we're creating a simple Map object with 2 keys.

 

(Informal/imprecise terms for such an object are Hash, HashTable or Dictionary, and the exact type is LinkedHashMap. Also feel like noting that even though Velocity's map literal syntax looks the same as JavaScript's object literal syntax, it creates an object that is different in one critical way, though that difference isn't relevant here.[2])

 

The keys in the Map can have any values, even including null, and can certainly include any kind of string, including an empty string. You access the keys in a Map using .get, bracketed-property syntax or, when it can be parsed unambiguously, dot-property syntax.

 

So for a more general example, if we defined this Map:

 

#set( $someOtherMap = {
  "FaveFruit" : "apple",
  "FaveVeg" : "broccoli"
} )

 

Then we can use one of 3 equivalent ways to access the person's favorite fruit:

 

$someOtherMap.get("FaveFruit")
$someOtherMap["FaveFruit"]
$someOtherMap.FaveFruit

 

Those all address the same key and will all show apple.

 

In the specific case of the $mktoBoolean Map, we can't use the 3rd option of dot-property syntax though, because $mktoBoolean.1 isn't a valid expression in Velocity Template Language since it starts with a number.  We're limited to

 

$mktoBoolean.get("1")
$mktoBoolean["1"]

 

This limitation isn't a big or surprising deal, by the way. Just one of a zillion cases where certain accessing syntax might be unusable, but that doesn't mean the initial definition of the variable was wrong. Sometimes you end up limiting the ways to refer to object keys — another common case is when a string key has a space in it ({ "My Other Car" : "Lambo" }), which also doesn't work with dot-syntax so you have to use $someOtherMap["My Other Car"] or $someOtherMap.get("My Other Car") — but you get other benefits in return.

 

Aaaaanyway, so we have a Map with 2 keys, both Strings. The value of each key is a real Boolean: I used the literal Boolean values true and false, not Strings.

 

That means we can use bracket-syntax to access the corresponding key in the Map, which will return a Boolean.  When I do

 

#if( $mktoBoolean[$isCustomer] )

 

I'm getting the value from the $mktoBoolean Map that matches the key $isCustomer. That is, within our reserved world of "1" and "", I'm always getting either $mktoBoolean["1"] or $mktoBoolean[""], and those values are both Booleans so the result can be used clearly and consistently.

 

Hope that all made sense!

 

 


 

 

Notes

[1] In Velocity's underlying Java environment, these would both be String instances and thus neither true nor false; they'd throw fatal errors if you tried to use them as Booleans. (Unlike other languages you might have used, in pure Java only an actual java.lang.Boolean can be used in a Boolean expression; there's no concept of truthy or falsy strings or numbers.)

 

But VTL is an often frustrating “friendlier” dialect on top of Java which minimizes visible errors. In VTL, #if ($someStringVariable) won't chuck an error message into your email; yet the logic it uses is basically “everything but exact Boolean false or null is true” which can be very misleading.

 

[2] That way being that the keys in a LinkedHashMap are ordered. Key order has no bearing on the way $mktoBoolean is used in this scenario, but it's a classic source of confusion in object-land. In JavaScript, object literal syntax creates a plain JS Object, which is unordered and is roughly like a simpler Java HashMap.

At Marketo, we understand that sharing knowledge with your peers is a great way to help accelerate learning. That’s why we partnered with our 2018 Marketo Champions to pull together a new ebook that dives into how you can use Marketo like some of our top performers. The new ebook, titled [Marketo Success] Guide, provides detailed insights on everything from setting up email templates to which reports you should be pulling to prove your impact on revenue. Check out an excerpt from the ebook below written by Chelsea Kiko, Marketing Automation Team Lead at Hileman Group to learn how she utilizes Marketo Segmentation.

 

What Is Segmentation?

Segmentation categorizes your audience into different subgroups based on a defined criterion that you establish in a Smart List. Once you create those subgroups, those are called segments. The best way to think about it is that a segmentation is a permanent smart list with the segments being the different targeted audience you define.

 

Why Use It?

Segmentations are important if you want to personalize your content to the specific audience you create. By creating and using dynamic content and snippets, you can personalize content based on who or where your end user is. For example, you can create an email to read a different call-to-action based on the segment in Texas. Dallas leads would see a different message than Austin leads because of the use of dynamic content tailored for each segment.

 

Dynamic Content—Once you've created different segments, you can add dynamic content blocks into your landing page or email. This tells Marketo that you want that piece of content to be different depending on which person views it.

 

Snippets—Create it once, and scale it. If you update the snippet, all the assets (landing pages or emails) using the snippet will be automatically updated.

 

How to Create a Segmentation

Below you’ll find a step-by-step guide to creating a segmentation in Marketo:

  • Navigate to lead database

Seg_Champion_EBook_Image01.jpg

 

  • Find the Segmentations Folder, right click and select new segmentation

Seg_Champion_EBook_Image02.jpg

 

  • Name your segmentation, select add segment to start creating the permanent smart list segments within that segmentation

Seg_Champion_EBook_Image03.jpg

 

  • Start adding segments and naming. Note: you will always have a default segment.
  • Next, this is just like creating a smart list. Pick the criteria and filters need to complete your segment
  • Put your segments in order. This is important because a lead will be located in the first segment of where they qualify

Seg_Champion_EBook_Image04.jpg

  • Click create
  • Take one last look at the number of people who qualify for each segment
  • Approve, it may take a while for the segmentation to be ready depending on the size of your database

 

Note: Once a segment is approved, you cannot edit. Rather, you must create a draft and then reapprove the segment/segmentation. Another folder will appear when you go to edit that is labeled ‘drafts’. You can only edit segments of the draft and not approved segmentation.

Seg_Champion_EBook_Image05.jpg

Remember, segmentations are mutually exclusive to workspaces. Each workspace can have its own set of segmentations.

 

Putting Segmentations to Use

Dynamic content is a strategic way to personalize content in Marketo assets. Personalization has been huge in marketing automation because it is going beyond traditional emails at the right time, to an even more memorable user experience.

 

Here are a few quick stats from to show how impactful personalized content can be:

  • 81% of consumers want brands to understand them better and know when and when not to approach them. – MarTech Today
  • 78% of consumers say personally relevant content increases their purchase intent. – Marketing Insider Group
  • 88% of U.S. marketers reported seeing measurable improvements due to personalization—with more than half reporting a lift greater than 10%. – Evergage

 

So, personalization works. Even as a consumer myself, I get all giddy when I see a personalized email or landing page. Dynamic content is a great start when working in Marketo, so let’s show you some examples.

 

Real-Life Marketo Example

At my last company, we were sticklers about deliverability rate. We were a big corporate company and our database wasn’t the healthiest until my team took over before my time. We consistently managed our data for bad data qualities (invalid emails, hard bounces, you know the deal)—but we also wanted to make sure our deliverability rate was top-notch because we suffered bad deliverability before my team joined.

 

From there, we created a marketable segmentation.

 

Our team was sick of cloning the perfect smart list and customizing, and then adding in all of the filters

 

We wanted to add to avoid sending any emails to bad data in the database so creating the segment was a great way to easily add in to make sure we only email the marketable segment.

 

The logic included filters like: blacklist =false; email invalid =false; email bounced=false; unsubscribed=false; marketing suspended= false; etc.

 

Even though it was a quick segmentation and was only used purely for sending emails (not dynamic content or reporting metrics)—our team saw a 9% increase in our deliverability rate simply by taking 15 minutes to create a segmentation to not even email those who are bad data.

 

******

 

We hope you enjoyed reading this excerpt from the upcoming [Marketo Success] Guide: Best Practices from Marketo Champions. Now it’s your turn, download the attached segmentation worksheet created by Marketo Champion, Brooke Bartos, Marketing Automation Manager at Walk Sands Communication, and start improving your segmentation today.

 

Keep an eye out for more tidbits from the new ebook that is launching in early 2019 (check out the excerpt on engagement program management here). Have questions about the content? Let us know in the comments!

**Posting on behalf of Chelsea Kiko Marketing Automation Team Lead at Hileman Group**

 

Reporting in Various Marketo Spaces

I have been building Marketo architecture and planning strategic marketing automation plans for about five years now and I still get the Marketo question about reporting. ‘Is that in Marketing Activities or Analytics section?’ – and there is a lot of confusion about which is better, which holds what type of reporting and what works best for subscriptions.

For me, it really comes down to the question ‘what are you trying to report?’ – if it is instance-wide and holistic reporting, I want to always say head to the analytics section to build those reports. However, there are reasons for usage of both and I will go through that in this blog post.

 

The biggest difference between program-level marketing activities reporting is the level of the reporting you want to accomplish. Analytics section is for that holistic reporting on a large group of assets/activities or even the whole instance. Also, if you want to see more details on ‘who’ not just the numbers, then program level reporting is your best bet as it can dive into the details a little more than analytics reporting can, and also, it makes more sense to build some reports next to the programs so that folder/reporting organization is intact.

 

I am going to talk about key factors and which reporting space would be a better for common situations.

 

Dashboard/Monthly Instance-Wide Reporting

I use analytics reporting for all my high-level reporting for my instance. For example, if I want to see how all my emails are doing YTD – I will use email insights and get that reporting. However, you can change your time period and pick and choose what emails you report on – but, this is a nice view for high level reporting or dashboards.

Image_01_Elevate_Analytics.jpg

 

Speaking of dashboards, depending on what type of tool you use, you may have to have data sources plug in to that external platform. Or, maybe you have a reporting dashboard where you still check out the instance and record it. Either way, it is great to organize reporting for dashboards in the analytics section. This makes it clean, easy to find and doesn’t get cluttered by marketing activities programs that are being deployed.

Image_02_Elevate_Analytics.jpg

 

**Expert Tip** [see below]– one nice feature of analytics reporting is you can actually layer on smart lists to your reporting to add additional detail for a holistic report. The below screenshot shows a lead lifecycle report with additional UTM smart lists so we can see exactly where each lead came from within the lead lifecycle. This is simply done by creating the smart lists and then adding them in within the setup tab of the report. You can also drill down on certain fields or attributes to see more information about the report. For example, say you want to add the custom columns of various UTMs and then drill down the reporting by company name – below is how you’d do that to achieve more data. This cannot be done to this extent in marketing activities.

Image_03_Elevate_Analytics.png

Image_04_Elevate_Analytics.jpg

Image_05_Elevate_Analytics.jpg

 

User & Roles

This is a popular reason to do reporting in analytics (or database) vs program level, marketing activities reporting. Many times, we want to make sure we have our users and roles to the point where it makes sense for the organization. If you tend to have a marketing person go rogue in Marketo when they want to see reporting but then manipulate or change marketing programs, you can lock them down to just see the analytics area of Marketo. Or, another reason for this would be for possibly a role where a team member’s role is to report how the marketing influenced campaigns are helping overall ROI. This way, you can give the user access to analytics, send them the Marketo link and they can export their own data. For example, Matty Marqeto is your analytics manager and he needs to see pre-built reports (or reports he builds on his own) in order to connect his dashboard and complete his role on the team. You can give him access to just the analytics section of Marketo so he can get in, pull the numbers he needs, and then go about his day. You can also do this in the database section of Marketo for smart lists. If you want to build out a smart list of data and don’t want to give the analytics manager or campaign reporter access to marketing activities – you can build the smart list in database and give the user access to database and analytics section only in Marketo. You can even choose if the user can export data or not – which is a nice feature.

Image_07_Elevate_Analytics.jpg

 

Specific Reporting by Campaign

It is best practice to build reports in advance within a program process template so when a new program is created or cloned, you have readily available common reporting within each program. This can help the campaign stakeholders know what reporting is available and be able to easily see the reporting in the program instead of searching in analytics.

Image_08_Elevate_Analytics.png

 

It is nice to have these reports ready because campaign specific reporting should be done at the program level versus in analytics so the organization is consistent and campaign stakeholders know where to find the reporting.

 

Subscriptions

Both the marketing activities reporting and analytics reporting can create subscriptions to be mailed to a user on a predetermined frequency. All you have to do is create the report how you want and then right click and create new subscription. The subscription will live where the report lives, so remember that if you want someone to have access to be able to modify the report. For example, Susan cannot edit her smart list report from her event in analytics section if the report lives in marketing activities.

 

Ad Hoc Reporting & Troubleshooting

Lastly, another common reason why users dive into the marketing activities program reporting versus analytics is for additional reporting and troubleshooting within campaigns. It makes sense to keep everything grouped together. When troubleshooting a potential area within a campaign, many times smart list reporting or even local asset reporting is used to see what an issue could be and how it can be resolved. Building these in the programs is best practice so all of the data is organized within the campaign and doesn’t get lost in another area of the platform like analytics.

 

The same goes for ad hoc reporting. For example, you have a unique campaign that needs some extra reporting for various campaign owners, so building it within the tree organization in the campaign makes sense to all parties. The reports can be easily found and reported on that campaign only.

 

Those are some common reasons to use one section of Marketo over the other and some extra details on why. Reporting with third parties can make these practices change as well as internal team organization.

Custom Forms 2.0 JavaScript behaviors are best managed via an external JS file and <script src="/yourfile.js"> tag in the LP. This allows your code to be updated without touching any other part of the page or form, sharing behaviors across forms & pages, and so on.

 

At tonight's NYC MUG meeting, my man Nick asked if you could put the custom behaviors JS into the form itself via Form Editor.

 

Indeed, if you want a quick-and-dirty JS enhancement, and you don't want to figure out where in the LP to put your <script> tag[1] or talk to your webmaster, yes, it's possible to use the Forms JS API from a Rich Text area. If you insist.

 

That should be good news! The only, let's say, more guarded news is that you have to do it right or can get craaaaazy results.

 

There's one major concern and one minor concern:

 

    (1) Major: You must ensure the code in your embedded <script> only runs once. Because of the curious way in which forms are rendered, this is a harder than you probably think.

    (2) Minor: You have to completely hide the Rich Text area so it doesn't show up in the layout, which means hiding its entire form row (margins, padding, et al.).

 

(2) is easy to accomplish with some CSS. So let's wait on that.

 

Run only once

Let's see what happens if we naïvely add a RT area containing a <script> with a simple whenReady listener function inside. Note I've put some text at the top of the RT so it looks in-use in Form Editor (“[Form Behaviors JS - Do Not Delete]”). Such text is optional but recommended; otherwise, the RT might be accidentally deleted as it looks empty until you double-click it.

 

ss

 

When you load a page with just that one Marketo form in it, you might see the following Console output:

 

ss

 

That's the same function run 4 different times even though we only have one Rich Text. Really bad if you're adding event listeners!

 

This happens because of the way the <form> DOM is built out. As the <script> is ejected and injected into the page repeatedly, it ends up executing its code repeatedly.

 

And that's not the same function running, technically speaking, but 4 functions that happen to have the same code running in a row. Because they're all separate from each other, they don't share a parent scope in which you could add behaviorsLoaded = true or something like that.

 

Instead, you can set an HTML data- attribute on the <form> element, since that will of course persist across executions. Each time the code runs, check for the attribute and return immediately if it's already true:

 

ss

 

In copy-and-pastable form:

 

[Form Behaviors JS - Do Not Delete!]
<script type="application/javascript">
MktoForms2.whenReady(function(form){
  var formEl = form.getFormElem()[0];

  if( formEl.getAttribute("data-inline-behaviors-loaded") == "true" ) {
    return;
  }

  formEl.setAttribute("data-inline-behaviors-loaded", "true");

  // now continue
  console.log("Doing something special");
});
</script>

 

Now you can see the meat of the code only runs once:

 

ss

 

Back to CSS

If you make the Rich Text area the first row in Form Editor, it's easy to select and hide:

 

ss

 

Copypasta:

 

.mktoFormRow:nth-of-type(1) {
    visibility: hidden;
    position : absolute;
}

 

I'd typically recommend a more resilient method of selecting the right row. But that would likely involve loading my FormsPlus::Tag Wrappers helper JS first… problematic if the whole idea is to consolidate the JS all within the form!

 

 


NOTES

[1] As a reminder, when not using the Rich Text method described here, put the behaviors <script> just inside the closing </body> tag on a Marketo LP, or anywhere after the form embed code on a non-Marketo LP.

Featured in the October edition of the Fearless Forum, Amber Hobson of Applied Systems is walking us through her journey of implementing Dynamic Content. In this master class, Amber goes into detail about her team's marketing strategy before rolling out Dynamic Content, lessons learned during implementation, and how it ultimately impacts marketing efficiency and reporting.

 

Q1: Can you describe how you leverage personalization at your organization?

Every single email is personalized to some extent. Our CMO is very much about the right content to the right person. We had implemented specific letterhead, envelopes, etc. throughout the organization to ensure that when you receive something from Applied, the address matches your country’s main location. He wanted us to do this for digital as well. We started with multiple emails for each region to get the right footer address, which later grew into the sophistication that we have today.

 

Q2: What are some specific benefits you’ve seen from implementing personalization?

It saved time for our Demand Gen team significantly! It’s much easier to change words or make minor edits within the Dynamic Content than it is to create multiple emails and set up our smart campaigns to send the right one based on country. Now, we can just build a single email and schedule it in a simple campaign.

 

It also had an unanticipated benefit where it can now flow into our reporting. We can actually do our reporting for email statistics based on the Dynamic Content segments as well. This is huge for our regional teams! It allows us to see how an email performs based on each group. For example, we’ve learned now that shorter emails are perform better North American while longer emails are better received in European.

 

Q3: Can you go into detail about efficiencies?

We work in 4 countries and technically 2 languages. In our industry, there are minor wording changes even between the US and Canada. This means that we were having to build separate emails for just a single word or a CTA link change. At this point building multiple emails for minor nuances was difficult to manage and we would have a single program with at least 5 emails to ensure we were getting the right content to the right person. By implementing Dynamic Content, we were able to scale down to a single email that we segment appropriately to make the necessary regional changes. We always start with the US (our largest market) and then we can quickly run a find/replace for some of the smaller copy changes.

 

Q4: How are you setting up your Dynamic Content campaigns within Marketo?

Our most used campaign is our Geographic segment. We set up a segment to catch country & language for everyone in our database. We’ve had to expand this segment over time as our company has grown by adding other markets. We also switched to using the State/Country picklist functionality in SFDC. One thing you have to remember is that when a change like that is made, you have to update all of your segments. Otherwise you end up with more people in the “Default” category than you want.

Picture1 (1).png

Then we created a Footer & Unsubscribe snippet for our emails as the most basic quick win. This allows us to have unique subscription centers and to include our local addresses in the footer of our emails.

Picture2 (1).png

Picture3 (1).png

Picture4 (1).png

Then for every email we do, we use that Snippet in our footer section.

Picture5 (1).png

 

Q5: What are some unique ways you’re leveraging Dynamic Content with Marketo?

We have two unique ways that we’re using Dynamic Content. One is geography. All emails automatically have a geographic segment added, even if it is just for the footer & unsubscribe content. The second method that we do is leverage Acuity to manage scripts. We use Acuity to provide each of our sales reps with their own calendar link. Then we create a segment based on SFDC account owner and simply change the URL based on the reps.

Picture6 (1).png

 

Q6: How are you layering features of Marketo to make Dynamic Content work for you by utilizing tokens/buttons?

This one took us a while to figure out! We had been using Dynamic Content for our copy for years before we realized that we could use it for our CTA links as well. We have added Dynamic Content to each of our five program tokens, which we use to populate our CTAs. We standardized our CTA to always include one of these tokens (with a few minor exceptions).

Picture7 (1).png

We also layered Marketo features into our modules when we are working in a newsletter. We have our client newsletter that goes out each month and each module corresponds loosely to a certain product. We segmented each module to have different content based on if you do or do not have that product. It gets crazy when working through QA, but we’ve identified key client accounts that will get specific content sections that we use as our QA people.

Picture8 (1).png

 

Q7: What was the trial and error process like leading up to the current Dynamic Content model you’re using?

It was more just us being paranoid about what we thought might happen versus what is actually likely to happen! We put our marketing team on every email that went out, but since we all have US information, the test results may not always be ideal. We got so many questions from the team asking if it should have said this or if it was correct for the market. I think we finally have them set up to understand it, but it made everyone so nervous!

 

Then, we had to train our communications team how to write the copy so that we were getting all regions at once so we could actually schedule them correctly. The other issue with the geographic segment was that we used to have our French copy translated for a later date, but now we’re providing the copy at the same time as the other regions. It creates a better experience for our client base (especially because a single account may have both French & English filters), but it took some training for our team.

 

Q8: What was the most challenging part of building out your Dynamic Content model?

It took a lot of research to decide how we wanted to start. We knew that building three (at the time) different emails every time that we sent something wasn’t working, but we weren’t sure how to fix it. After digging around on the Marketing Nation Community, talking to other users, and then going through trial/error, we decided that Dynamic Content was the way to go. Building out our segments was very challenging. We found originally that our data wasn’t as clean as sales thought it was, so we had to do a clean up campaign in SFDC and then we set up standardization for country & language across all areas of SFDC as well as within our Marketo forms. We still do periodic audits to ensure the data is correct and have had to expand our standardization to other systems that simply touch SFDC or Marketo (finance system, implementation system, etc.)

 

Q9: What advice would you give to Marketo users who are considering implementing Dynamic Content for localization purposes?

Think through your segments. You have to remember that no person can be a member of two segments so if there is any chance of overlap, you may need to diagram it out. And start small! Pick one type of item to do dynamically. For us, it was geography. As soon as you have that first one worked out, the ideas will just flow and you will find so many uses!

 

We hope you enjoyed reading about how Applied Systems is leveraging Dynamic Content to make the lives of their marketers easier.

In the feedback from our Marketo Fearless Forum: Edition 03 , we received a lot of comments asking for more information on the inaugural members of our Fearless 50. As a result, we have created a new series for our customer newsletter called How 2B Fearless.

 

In this first edition, we sat down with Brooke Bartos, who is not only a Fearless 50 member, but she is also a Marketo Champion and a Chicago MUG Leader. Brooke tells us about what being a fearless marketer means and what that has meant for her career.

 

What does fearless marketing mean to you?

Fearless marketing means knowing the risks and the rewards of trying something new and making an educated decision with full commitment.

Who is a fearless marketer you look up to and why?

When it comes to fearlessness, I have always admired Oprah Winfrey for the brand and the legacy she has created. When you learn about her background, her childhood, and her teenage years, this is someone who had every excuse not to succeed, and yet, she did in the most spectacular of ways. Oprah has become a globally recognized brand in media, literature, and consumer products. She chose to rise above the obstructions life placed in her path.

How did your career start out in marketing?

I went to school for psychology because I was intrigued by the puzzle of what motivates people. My first internship out of college was working in a market research department for a major automotive manufacturer, where I worked on the relaunch of their dealership incentive program. This relaunch was heavily based on feedback gained through interviews, surveys, and focus groups about what motivates them in the sales process. I learned that when it comes to business, there are subtle ways you can influence behavior through how you communicate— words, images, and styling that you use in marketing is all psychology at the core.

 

How did you get to the point you are at in your career today?

I learned a tremendous amount about how to communicate with people through my market research internship and time in field marketing. These experiences helped me learn what motivates people and how to talk to them.

When I went to work for a company where I had my hands in just about every element of our marketing, both  and offline, I was able to bring all that knowledge to helping transform the company from a traditional offline marketing company into one focused primarily on digital marketing. It was not an easy transformation! It took gaining buy-in from areas of the organization that were ingrained in the traditional marketing ideas of print and tradeshows and getting them to try new channels, upgrade strategies, and prove results.

 

That company was where my Marketo journey began. At first, I was a part-time user, “backup trigger” to our admin at the time. When she left, I asked to move into that role, but the response I got from HR was “no.” They wanted to bring in someone with more Marketo experience to manage and grow the instance. I started job hunting—this was something I was strongly interested in, and if that meant that I had to go out to go up, I would.

 

During the process, my boss found out I was interviewing. We were able to sit down and have a candid conversation about what I wanted and what I was looking for. She went to bat for me, and I moved into that admin role two weeks later! Within four months of that move, I became Marketo Certified for the first time. That only served to fuel the fire—I went on to get recertified and obtain all eight of the Specialization Certifications Marketo when they were released. I had something to prove to myself, and to my boss, for taking the chance on me. Early this year, I put myself out there and applied to the Marketo Champions program. In February, I was named to the 2018 Champions class.

 

I eventually ran out of room to grow at that company. From there, I moved to my current role with a full-service digital marketing agency. Every day I get to work with clients on a global enterprise scale to build out and optimize their Marketo instances in support of their overall demand gen and content marketing strategies. I am excited by new opportunities and resources afforded me as a part of an agency and I look at every challenge as a chance to grow.

I would not be where I am without an incredible support network of mentors, cheerleaders, and people who believe in me. I will be forever grateful to have them in my life and as a part of my journey.

What have you learned from other members of the Fearless 50?

This inaugural class of Fearless Marketers comes with such a diverse set of skills and from a broad set of backgrounds, industries, and roles. From them, I’ve learned that fearlessness comes in many forms, some personal and some professional. Commitment to success is at the core of every single one of their stories and is a principal I have really taken to heart.

What are three pieces of advice you would give to the next generation of fearless marketers?

#1. Take calculated risks! If you always play the safe game, you’ll never know what you could truly accomplish. When we try new things in marketing and in life, that hesitant moment of “can I do this?” that comes from self-doubt should not be a question, it should be a commitment. I CAN do this. Lean into that hesitation as a way to grow.

#2. Make smart decisions. When you are ready to commit to an idea, make sure you have gathered as much information as you can to make the most educated decision possible, and commit. Understand the pros and cons and make the best and smartest decision you can.

#3. Learn from failures. Do not berate yourself or others when something goes wrong. You cannot go back and change it. Take it as a lesson. Examine what went wrong and what you can learn from it to do things differently in the future.

 

 

Check out the rest of the content featured in Marketo Fearless Forum: Edition 04.

 

About Brooke Bartos

BrookeBartos-400x400.jpg

 

LinkedIn: https://www.linkedin.com/in/brookembartos/

Community Page: Brooke Bartos

 

Have any questions for Brooke about her fearless marketing career? We would love to hear them in the comments below.

At Marketo, we understand that sharing knowledge with your peers is a great way to help accelerate learning. That’s why we partnered with our 2018 Marketo Champions to pull together a new ebook that dives into how you can leverage Marketo like some of our top performers. The new ebook, titled the [Marketo Success] Guide, provides detailed insights on everything from setting up email templates to which reports you should be pulling to prove your impact on revenue. Check out an excerpt from the ebook below written by Erik Heldebro, Chief Marketing Officer at Bambuser and Rachel Noble, Manager Client Services at Digital Pi to learn how they manage engagement program memberships in Marketo.

 

Managing Engagement Programs

Nurture programs aren’t just hard to conceive. They can be hard to manage, too, especially if you don’t have a program set up for just that purpose. We call this a Nurture Traffic Controller, and here’s how to build one:

  1. Create a Default Operational Program named Nurture Traffic Controller.
  2. In the new program, create three folders: Smart Campaigns, Smart Lists, and Reports.
  3. In the Smart Lists folder, create a Smart List named “1. Nurture Target Audience.” The Smart List criteria should include anyone who would potentially qualify for any nurture program. We’ll specify which program later. Remember that Marketo filters out Unsubscribed, Marketing Suspended, and Blacklisted leads automatically.
  4. If you have one Engagement Program that everyone goes into, skip to step 5. Otherwise, you will need to create additional target audience Smart Lists to identify which Engagement Program qualified leads should go into. For example, if you have an Engagement Program specifically for VP’s, create a Smart List “2. VP Target Audience.”
  5. In the Smart Campaigns folder, create a new Smart Campaign named “1. Add Qualified Leads to Nurture.”
    1. Smart List:

         EP_Champion_EBook_Image01.png

    1. Flow:
      1. If you have a generic nurture program, your only Flow step should be: Add to Engagement Program -> Generic Engagement Program, Stream=Stream 1. Add choices to determine which stream if you have multiple streams.
      2. If you do not have a generic nurture program, you can use the Smart Lists you created in step 4 to identify which program they should go into
      3. Add to Engagement Program  If Member of Smart List A, Engagement Program A  Stream = Stream 1 and so on. Like in (i), you can also add choices to determine which stream if any of these programs have multiple streams.

                 EP_Champion_EBook_Image02.png

 

   6. Schedule this to run recurring just before the cast of the nurture program(s). If the casts are not consistent, consider scheduling this daily. Remember that the campaign is set so people can only run through once, so you don’t have to worry about this re-assigning everyone to new nurture programs each time it runs.

   7. If you don’t have any other nurture programs, you’re done! Otherwise, we need to set up transition rules to get people into the correct nurture program. For each additional nurture program, we need to create a new Smart Campaign to transition leads who qualify:

  EP_Champion_EBook_Image03.png

  EP_Champion_EBook_Image04.png

 

And that Smart List referenced in Flow step #1?

EP_Champion_EBook_Image05.png

 

Now your leads will be in the right Engagement Programs!

 

Engagement Program Checklist

When setting up your Engagement Programs, here’s a checklist you can use to make sure you have everything you need.

  • Engagement Program built
  • Content Streams created
  • Unsubscribed/Invalid Stream created
  • Transition Rules defined
  • Smart Campaign to track success at the Engagement Program level built and activated
  • Emails added to nested Default Programs within the Engagement Program
  • Smart Campaigns to track success at nested Default Program level built and activated
  • Excluded Smart Campaigns built-in nested Default Programs and activated
  • Default Programs/Email Assets added to streams
  • Default Programs/Email Assets activated in streams
  • Cadence/first Cast scheduled
  • Traffic Controller created/updated

 

We hope you enjoyed reading this excerpt from the upcoming [Marketo Success] Guide: Best Practices from Marketo Champions. Keep an eye out for more tidbits from the new ebook that is launching in late 2018. Have questions about the content? Let us know in the comments!

Hello Marketing Nation,

 

This week Marketo reopened the gates to the Marketo Champion Program and we wanted to extend the invitation to all of you in the Marketing Nation Community. Many of you have been impacted by a Marketo Champion in one way or another. Whether you've seen some of their content here on Community or you've attended a Champion-lead Marketo User Group, the Champions are deeply devoted to helping our customers win with Marketo. The application will be open until November 30th.

 

For more details around becoming a Marketo Champion, check out the Champion Info page listed here: Requirements & Benefits of the Champion Program

 

If you're ready to apply today, you can find the application here: https://engage.marketo.com/championapplication2019.html

 

If you have any further questions about the Champion Program’s Criteria & Requirements, please email customermarketing@marketo.com

 

Good luck to all the 2019 applicants!

As you dive into the world of webhooks for advanced database tasks, the number of webhook definitions in the Admin UI can get pretty crazy. I've seen instances with 100 different ’hooks!

 

Many webhooks do need to stand alone, but some come in pairs or groups. For example, an Add to Event Registration Counter webhook needs a companion Remove from Registration Counter. A Lookup in Suppression List webhook running against an external db likely means Add to Suppression List is also defined. And so on.

 

To consolidate webhooks and make the UI (and your code) more manageable, a cool trick is to send the {{Campaign.Name}} token along with the hook, so the remote service can decide which direction/action to take, and you only need to define one webhook to cover a group of related actions.

 

For example...

I have a webhook that maintains, in a Textarea custom field, all the Static Lists a lead is currently in. (This view is notoriously hard to get at, in both the UI and the API, unless you flatten it onto a field like this.) The field uses a semicolon-delimited format, as is typical for such things: Apples;Peaches;Pumpkin Pies.[1]

 

Naturally, the webhook is triggered on Added to List and on Removed from List. So I have those 2 campaigns set up with informative names:

 

ssss

ss

 

And the onRemove flow is exactly the same as the onAdd flow pictured above. They both call the same webhook, rather than there being 2 webhooks, one for each direction.

 

Then within the webhook itself, I can detect the direction because {{Campaign.Name}} is included in the payload (in addition to {{Trigger.Name}}, which is the List name):

 

ss

 

This I find infinitely more manageable than the alternative, since the onAdd and onRemove handlers sit right next to each other.

 

Obviously, the exact way your webhook service switches between different directions/modes depends on your architecture. Since this webhook uses JavaScript, there's a literal JS switch statement, while in other cases you might pass {{Campaign.Name}} in the URL path or query string (the dotted Program Name.Campaign Name could represent the dot-path to different Java class methods, that would be cool!).

 

 

Notes

[1] In this case, a single Static List can't have a semicolon within its name, for obvious reasons.  You can switch delimiters as necessary.

Isn't it annoying to add a Wait step before sending a registration confirmation, crossing your fingers that the provider has phoned home with the {{Member.Webinar URL}} token?

 

I've always hated this step. Not only because of the experience for the end user, who might think you've forgotten about them, but on a pure technical level. Techies hate timers that are “probably sufficient”: we want tools that are predictable, not best-case guesses with fatal downsides. Not only might a 15 minute Wait not be sufficient under load,  there's no Wait that will fix a major problem with the integration, so users will eventually get an email with a big blank in the middle anyway.

 

What if I told you you don't need to hold off on such emails at all?

 

Instead, set up an LP in the webinar program that redirects to the {{Member.Webinar URL}}. Send them a link to that LP with no delay. Unless it's very close to the webinar's start time, most people aren't going to click a Join Webinar link right away, so you've got lots of breathing room for the API to sync up the {{Member.}} token.

 

When they do click the email, you'll be ready for them and will immediately bounce them over to the webinar, hands-free.  If it does happen that the URL isn't yet ready when they click, well, you weren't going to get it to them any quicker with an arbitrary delay! You can give them a countdown timer and reload the page in 30 seconds, and you can send them a follow-up email since you know they're eager (that second email might as well have a Wait step).

 

Here's the briefest possible copypasta to add to that LP:

 

<style type="text/css">
.webinar-pending-note { 
  display: none; 
}
[data-url-ready-state="pending"] .webinar-pending-note { 
  display: block; 
}
</style>
<script>
var memberWebinarURL = "{{Member.Webinar URL}}";
if ( memberWebinarURL ) {
  document.location.href = memberWebinarURL;
  // just for completeness
  document.documentElement.setAttribute("data-url-ready-state","ready"); 
} else {
  document.documentElement.setAttribute("data-url-ready-state","pending");
}
</script>
<div class="webinar-pending-note">
Your customized webinar URL is still being assembled. 
Please refresh this page or re-click the email link in a few minutes!
</div>

 

More ideas

Once the LP is in place, you can extend the user experience in several ways:

 

1. As noted above, you can add a periodic document.location.reload(true) in case they did hit the page before the API phoned home.

2. You can adapt some of my Redirector Page JS to add a progress indicator before reloading. Note sending leads to the Webinar Redirector LP also enables Munchkin tracking, which is a benefit in its own right.

3. You can add Agical Add to Calendar links to the page, referencing the {{Member.Webinar URL}} using the alternate separator syntax originally designed for this very case.

4. If you want to send the lead an Add to Calendar link that works from the start, then reference the Redirector LP's URL in your .ICS file or Agical link, not the {{Member.Webinar URL}}.

5. You can retarget the lead with rich contextual content if they land on the page after the webinar is over (check another {{my.}} token that stores the event date) or well before it begins, instead of taking them to this beautiful page:

ss

For any Velocity project, I've taken to offering clients a separate config token, call it {{my.ThisIsWhereYouChangeStuff}}, where they can manage some output settings without having to email me all the time.

 

Then there are one or more {{my.PleaseDontChangeAnythingInHereItsFragile}} tokens with the meat of the code.

 

Velocity #define directives are really handy for the config token. They're a bit more fault-tolerant than #set statements, where the non-technical person has to remember to escape quotes, close parentheses and such.

 

That is, instead of:

 

#set( $baseURL = "https://www.example.com/preferencecenter" )
#set( $linkText = "Say \u0022Hello\u0022 to our new preference center." )

 

I give them a token like so:

 

#define( $baseURL )
https://www.example.com/preferencecenter
#end
#define( $linkText )
Say "Hello" to our new preference center.
#end

 

As long as they leave the #define/#end lines alone they can change anything in-between (especially good for multiline text, as you might imagine).

 

There's a little trick to using #define, though, and that is like everything in Velocity, it preserves whitespace.  What whitespace, you may ask? Well, look at the end of this line:

 

https://www.example.com/preferencecenter

 

That has a carriage return + line feed (or just LF, depending on the OS) at the end.

 

So if I output a link like so:

 

<a href="${baseURL}">${linkText}</a>

 

The email will contain:

 

<a href="https://www.example.com/preferencecenter
">Say "Hello" to our new preference center.
</a>

 

Instead of what you intended:

 

<a href="https://www.example.com/preferencecenter">Say "Hello" to our new preference center.</a>

 

Which is bad because it will wreck your links even though you may not even see the wreckage in Preview because of the way HTML itself swallows line breaks.

 

Now, you can suppress the trailing whitespace by adding a comment ## at the end of the line

 

https://www.example.com/preferencecenter##

 

but I daresay that's not an improvement, since the idea is to offer this token as a not-too-fragile place for a non-technical person to make adjustments, and adding ## is something they're bound to forget or mess up.

 

So what you want to do is let them enter text in as close to free-form fashion as possible. Then in your code, strip out extraneous whitespace at the beginning or end to be tolerant of minor messups.

 

How trim() works

The documentation of the trim() method in Java, which exists on any Java String and therefore on any Velocity String is almost lovable in its complexity.

 

trim() does exactly what we want, but you have to understand the ASCII table to know that! Not that a programmer shouldn't understand ASCII, but it's a particularly circuitous explanation IMO:

 

[L]et k be the index of the first character in the string whose code is greater than '\u0020' (the space character), and let m be the index of the last character in the string whose code is greater than '\u0020'. A new String object is created, representing the substring of this string that begins with the character at index k and ends with the character at index m-that is, the result of this.substring(k, m+1).

 

Let me put that in clearer terms:

 

If a contiguous block of characters between ASCII 0 and ASCII 32 is found at at the beginning and/or end of the string, the whole block is removed.

 

ASCII 0 through ASCII 32 means the nul (0) through space (32) characters, inclusive. In that range are the quite common carriage return (13), line break (10), and tab (9) characters, and some more obscure ones like vertical tab (11).[1]

 

So though it only explicitly mentions the space character \u0020 (hex 20 is decimal 32), which you're probably familiar with as %20 in URLs, in fact it covers line breaks as well. If there's a long intro or outro of spaces, line breaks, and tabs, trim() will clean 'em all out.

 

trim()-ing what's inside a #define

So trim() is perfect, but you can't simply do this:

 

<a href="${baseURL.trim()}">${linkText.trim()}</a>

 

That'll throw an error. The reason is that any #define, when you address it directly, is a Velocity-specific Block$Reference, not a generic java.lang.String.

 

A Block Reference doesn't itself have a trim() method. But it does have a toString() method. (In fact, toString() is called under the hood when you output a plain ${reference} in Velocity, otherwise you couldn't output it at all.)

 

So I know this was long-winded but hopefully you learned something you need:

 

<a href="${baseURL.toString().trim()}">${linkText.toString().trim()}</a>

 

And you're done!

 

 


 

Notes

[1] But not all whitespace characters, since some as common as non-breaking space (the famous &nbsp; in HTML) are above ASCII 32. And over in JavaScript, the almost-identically-purposed trim() does strip non-breaking space. Is there nothing in programming that's not complicated when you care to learn the details? ☺

Filter Blog

By date: By tag: