“Poison pills” for bad Smart Lists using Velocity

Custom flags like Is Embargoed and Is Customer add flexibility and a nice self-documenting quality to your database.

The problem is remembering to add these fields to Smart List filters. Even if all programs are supposed to be cloned, and premade SLs are waiting for use in Member of Smart List conditions, someone inevitably will mess up.

Plus, the SCs that are supposed to set those exclusion flags are always limited by what Marketo's string matching can and can't do.

I work with a client where, regardless of procedures and technical readiness, banned recipients occasionally get emails. (In financial services, sending to disallowed leads can carry legal consequences unrelated to spam, i.e. advertising to people who aren't licensed to buy or sell a product is a bad move, even if they're happy to get your messages.)

As a belt-and-suspenders approach, I implemented a Velocity-based layer to ensure that Smart Lists could not include bad leads. Using Velocity's Java methods gives you a lot more field-crunching and condition-combining power than the Smart List UI, needless to say. Of course, the token needs to be located where users are unable/unlikely to clip it out, so add it at the template level.

By the way, you are supposed to have your WTF? face on at this point… if you don't, start at the top of the post again!

You should be wondering how this could work, because Velocity scripts only execute when an email is being rendered, and that only happens after all included leads have been computed. While that's true, there's a little detail we can exploit.

The detail is that if a Velocity token throws an exception for a lead, that lead’s email never be put on the wire. Let me be clear: the lead’s Activity Log will still show a Sent Email line. But they will never show a Delivered Email line (this should tell you something about what Sent does and doesn't mean). And they’ll show an Email Bounced Soft with a Java error in the Details.

Interestingly, there is no formal way to throw an exception from Velocity. This is one of the ways in which, even as a language “powered by Java” VTL is its own beast.

In Java, exceptions and errors are all too easy to trigger. Velocity, on the other hand, swallows a lot of stuff (like chains of reference errors!) which no other language dares to do. But there are still ways to throw an error up into the Java VM, and when that happens, Marketo aborts the send process, again after making the Sent Email log entry but before actually doing anything SMTP-wise.

Here's an example of a “poison pill” token you might include in a template. Note the li'l subdomain matching macro to make sure that joe@baddomain.com and jill@mail.baddomain.com both release the poison.

## quick subdomain matcher
#macro( emailParentMatches $email $domains )
#set( $res = "false" )
#foreach( $domain in $domains )
  #if( $email.matches("(?i)(?:.*)@(?:\w+\.)*${domain}$") )
    #set( $res = "true" )
    #break
  #end
#end
${res}##
#end
## error thrower
#macro( throwError )
#set( $throwError = $lead.class.forName("") )
#end
## main stuff
#set( $badDomains = ["knownembargoed.com","otherembargoed.com"] )
#set( $isBadDomain = "#emailParentMatches( $lead.Email $badDomains )" )
#set( $isBadDomain = $isBadDomain.trim() )
#if( 
	$lead.isEmployee.equals("1") ||
	$lead.isEmbargoed.equals("1") || 
	$lead.isCompetitor.equals("1") || 
	$isBadDomain.equals("true")
)	
#throwError
#end

Instead of hardcoding the bad domains in the token you could check for membership in a segmentation:

#if( !$lead.Segmentation_NeverSend.equals("Default") )
... etc...

As for determining if an exception was thrown for the whole list, an Email Performance Report will show Delivered = 0, which certainly should set off alarms.

Overall, not the sweetest solution, but the only way I know of to hard-stop certain procedural problems.